diff --git a/plugin/src/main/java/com/denizenscript/denizen/events/player/BiomeEnterExitScriptEvent.java b/plugin/src/main/java/com/denizenscript/denizen/events/player/BiomeEnterExitScriptEvent.java index 9bf2dac4d1..78b0e99b1e 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/events/player/BiomeEnterExitScriptEvent.java +++ b/plugin/src/main/java/com/denizenscript/denizen/events/player/BiomeEnterExitScriptEvent.java @@ -1,5 +1,6 @@ package com.denizenscript.denizen.events.player; +import com.denizenscript.denizen.nms.NMSHandler; import com.denizenscript.denizen.objects.BiomeTag; import com.denizenscript.denizen.objects.EntityTag; import com.denizenscript.denizen.utilities.Utilities; @@ -123,8 +124,8 @@ public void onPlayerEntersExitsBiome(PlayerMoveEvent event) { } from = new LocationTag(event.getFrom()); to = new LocationTag(event.getTo()); - old_biome = new BiomeTag(from.getBlock().getBiome()); - new_biome = new BiomeTag(to.getBlock().getBiome()); + old_biome = new BiomeTag(NMSHandler.getInstance().getBiomeAt(from.getBlock())); + new_biome = new BiomeTag(NMSHandler.getInstance().getBiomeAt(to.getBlock())); if (old_biome.identify().equals(new_biome.identify())) { return; } diff --git a/plugin/src/main/java/com/denizenscript/denizen/nms/NMSHandler.java b/plugin/src/main/java/com/denizenscript/denizen/nms/NMSHandler.java index 75d89ab293..df2777322b 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/nms/NMSHandler.java +++ b/plugin/src/main/java/com/denizenscript/denizen/nms/NMSHandler.java @@ -14,7 +14,9 @@ import net.md_5.bungee.api.chat.HoverEvent; import org.bukkit.Location; import org.bukkit.NamespacedKey; +import org.bukkit.World; import org.bukkit.block.Biome; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.persistence.PersistentDataContainer; @@ -163,7 +165,11 @@ public boolean isCorrectMappingsCode() { public abstract ProfileEditor getProfileEditor(); - public abstract BiomeNMS getBiomeNMS(Biome biome); + public abstract BiomeNMS getBiomeNMS(World world, String name); + + public BiomeNMS getBiomeAt(Block block) { + return NMSHandler.getInstance().getBiomeNMS(block.getWorld(), block.getBiome().name()); + } public abstract double[] getRecentTps(); diff --git a/plugin/src/main/java/com/denizenscript/denizen/nms/abstracts/BiomeNMS.java b/plugin/src/main/java/com/denizenscript/denizen/nms/abstracts/BiomeNMS.java index c67cc8e2c1..b191ecc872 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/nms/abstracts/BiomeNMS.java +++ b/plugin/src/main/java/com/denizenscript/denizen/nms/abstracts/BiomeNMS.java @@ -1,6 +1,8 @@ package com.denizenscript.denizen.nms.abstracts; -import org.bukkit.block.Biome; +import com.denizenscript.denizencore.utilities.CoreUtilities; +import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.entity.EntityType; import java.util.ArrayList; @@ -8,10 +10,13 @@ public abstract class BiomeNMS { - private final String name; + public String name; - public BiomeNMS(Biome biome) { - this.name = biome.name(); + public World world; + + public BiomeNMS(World world, String name) { + this.world = world; + this.name = CoreUtilities.toLowerCase(name); } public DownfallType getDownfallType() { @@ -62,4 +67,6 @@ public enum DownfallType { protected abstract boolean getDoesRain(); protected abstract boolean getDoesSnow(); + + public abstract void setTo(Block block); } diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/BiomeTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/BiomeTag.java index 928bf8dcf7..ed76aa9ce1 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/BiomeTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/BiomeTag.java @@ -1,5 +1,6 @@ package com.denizenscript.denizen.objects; +import com.denizenscript.denizen.nms.NMSVersion; import com.denizenscript.denizen.utilities.debugging.Debug; import com.denizenscript.denizencore.DenizenCore; import com.denizenscript.denizencore.flags.AbstractFlagTracker; @@ -16,6 +17,8 @@ import com.denizenscript.denizencore.tags.TagRunnable; import com.denizenscript.denizencore.utilities.CoreUtilities; import com.denizenscript.denizencore.utilities.Deprecations; +import org.bukkit.Bukkit; +import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.entity.EntityType; @@ -29,13 +32,14 @@ public class BiomeTag implements ObjectTag, Adjustable, FlaggableObject { // @base ElementTag // @implements FlaggableObject // @format - // The identity format for biomes is simply the biome name, as registered in Bukkit, for example: 'desert'. + // The identity format for biomes is a world name, then a comma, then the biome key. For example: 'hub,desert', or 'space,minecraft:desert'. // // @description - // A BiomeTag represents a world biome type. + // A BiomeTag represents a world biome type. Vanilla biomes are globally available, however some biomes are world-specific when added by datapacks. // - // A list of all valid Bukkit biomes can found be at - // <@link url https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/Biome.html> + // A list of all vanilla biomes can be found at <@link url https://minecraft.fandom.com/wiki/Biome#Biome_IDs>. + // + // BiomeTags without a specific world will work as though they are in the server's default world. // // This object type is flaggable. // Flags on this object type will be stored in the server saves file, under special sub-key "__biomes" @@ -51,46 +55,38 @@ public static BiomeTag valueOf(String string) { return valueOf(string, null); } - /** - * Gets a Biome Object from a string form. - * - * @param string the string - */ @Fetchable("b") public static BiomeTag valueOf(String string, TagContext context) { - if (string.startsWith("b@")) { string = string.substring(2); } - - for (Biome biome : Biome.values()) { - if (biome.name().equalsIgnoreCase(string)) { - return new BiomeTag(biome); + string = CoreUtilities.toLowerCase(string); + int comma = string.indexOf(','); + String worldName = null, biomeName = string; + if (comma != -1) { + worldName = string.substring(0, comma); + biomeName = string.substring(comma + 1); + } + World world = Bukkit.getWorlds().get(0); + if (worldName != null) { + WorldTag worldTag = WorldTag.valueOf(worldName, context); + if (worldTag == null || worldTag.getWorld() == null) { + return null; } + world = worldTag.getWorld(); } - - return null; + BiomeNMS biome = NMSHandler.getInstance().getBiomeNMS(world, biomeName); + if (biome == null) { + return null; + } + return new BiomeTag(biome); } - /** - * Determines whether a string is a valid biome. - * - * @param arg the string - * @return true if matched, otherwise false - */ public static boolean matches(String arg) { - if (arg.startsWith("b@")) { - arg = arg.substring(2); - } - - for (Biome b : Biome.values()) { - if (b.name().equalsIgnoreCase(arg)) { - return true; - } + return true; } - - return false; + return valueOf(arg, CoreUtilities.noDebugContext) != null; } /////////////// @@ -98,8 +94,20 @@ public static boolean matches(String arg) { ///////////// public BiomeTag(Biome biome) { - this.bukkitBiome = biome; - this.biome = NMSHandler.getInstance().getBiomeNMS(biome); + String key = biome.name(); + if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_17)) { + if (biome.getKey().getNamespace().equals("minecraft")) { + key = biome.getKey().getKey(); + } + else { + key = biome.getKey().toString(); + } + } + this.biome = NMSHandler.getInstance().getBiomeNMS(Bukkit.getWorlds().get(0), key); + } + + public BiomeTag(BiomeNMS biome) { + this.biome = biome; } ///////////////////// @@ -108,8 +116,6 @@ public BiomeTag(Biome biome) { private BiomeNMS biome; - public Biome bukkitBiome; - public BiomeNMS getBiome() { return biome; } @@ -133,7 +139,7 @@ public String getObjectType() { @Override public String identify() { - return "b@" + CoreUtilities.toLowerCase(biome.getName()); + return "b@" + biome.world.getName() + "," + biome.getName(); } @Override diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java index 500dc5c865..8e44d64db9 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java @@ -1,6 +1,7 @@ package com.denizenscript.denizen.objects; import com.denizenscript.denizen.events.BukkitScriptEvent; +import com.denizenscript.denizen.nms.abstracts.BiomeNMS; import com.denizenscript.denizen.objects.notable.NotableManager; import com.denizenscript.denizen.objects.properties.material.MaterialDirectional; import com.denizenscript.denizen.objects.properties.material.MaterialHalf; @@ -452,7 +453,7 @@ public static BlockState getBlockStateSafe(Block block) { } } - public Biome getBiomeForTag(Attribute attribute) { + public BiomeNMS getBiomeForTag(Attribute attribute) { NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); try { if (getWorld() == null) { @@ -467,7 +468,7 @@ public Biome getBiomeForTag(Attribute attribute) { } return null; } - return super.getBlock().getBiome(); + return NMSHandler.getInstance().getBiomeAt(super.getBlock()); } finally { NMSHandler.getChunkHelper().restoreServerThread(getWorld()); @@ -3088,7 +3089,7 @@ else if (PolygonTag.matches(attribute.getContext(1))) { if (attribute.startsWith("formatted", 2)) { Deprecations.locationBiomeFormattedTag.warn(attribute.context); attribute.fulfill(1); - return new ElementTag(CoreUtilities.toLowerCase(object.getBiomeForTag(attribute).name()).replace('_', ' ')); + return new ElementTag(CoreUtilities.toLowerCase(object.getBiomeForTag(attribute).getName()).replace('_', ' ')); } return new BiomeTag(object.getBiomeForTag(attribute)); }); @@ -3656,7 +3657,7 @@ public void adjust(Mechanism mechanism) { // // --> if (mechanism.matches("biome") && mechanism.requireObject(BiomeTag.class)) { - getBlock().setBiome(mechanism.valueAsType(BiomeTag.class).bukkitBiome); + mechanism.valueAsType(BiomeTag.class).getBiome().setTo(getBlock()); } // <--[mechanism] diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/material/MaterialMode.java b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/material/MaterialMode.java index 2d6e2fdd27..0014aec5db 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/material/MaterialMode.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/material/MaterialMode.java @@ -122,7 +122,7 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("mode") && mechanism.requireEnum(false, Comparator.Mode.values())) { + if (mechanism.matches("mode")) { if (isComparator() && mechanism.requireEnum(false, Comparator.Mode.values())) { getComparator().setMode(Comparator.Mode.valueOf(mechanism.getValue().asString().toUpperCase())); } diff --git a/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/Handler.java b/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/Handler.java index 4b8443522e..0842d48ca6 100644 --- a/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/Handler.java +++ b/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/Handler.java @@ -24,6 +24,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.NamespacedKey; +import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.craftbukkit.v1_14_R1.CraftServer; import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; @@ -210,8 +211,13 @@ public ProfileEditor getProfileEditor() { } @Override - public BiomeNMS getBiomeNMS(Biome biome) { - return new BiomeNMSImpl(biome); + public BiomeNMS getBiomeNMS(World world, String name) { + for (Biome biome : Biome.values()) { + if (biome.name().equalsIgnoreCase(name)) { + return new BiomeNMSImpl(world, biome); + } + } + return null; } @Override diff --git a/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/impl/BiomeNMSImpl.java b/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/impl/BiomeNMSImpl.java index 1b5b4df838..b1c508e8f3 100644 --- a/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/impl/BiomeNMSImpl.java +++ b/v1_14/src/main/java/com/denizenscript/denizen/nms/v1_14/impl/BiomeNMSImpl.java @@ -3,7 +3,9 @@ import com.denizenscript.denizen.nms.abstracts.BiomeNMS; import com.denizenscript.denizencore.utilities.ReflectionHelper; import net.minecraft.server.v1_14_R1.*; +import org.bukkit.World; import org.bukkit.block.Biome; +import org.bukkit.block.Block; import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock; import org.bukkit.entity.EntityType; @@ -15,8 +17,11 @@ public class BiomeNMSImpl extends BiomeNMS { private final BiomeBase biomeBase; - public BiomeNMSImpl(Biome biome) { - super(biome); + public Biome bukkitBiome; + + public BiomeNMSImpl(World world, Biome biome) { + super(world, biome.name()); + bukkitBiome = biome; this.biomeBase = CraftBlock.biomeToBiomeBase(biome); } @@ -88,4 +93,9 @@ private List getSpawnableEntities(EnumCreatureType creatureType) { } return entityTypes; } + + @Override + public void setTo(Block block) { + block.setBiome(bukkitBiome); + } } diff --git a/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/Handler.java b/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/Handler.java index 57f8a3f5f9..edd95de9ab 100644 --- a/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/Handler.java +++ b/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/Handler.java @@ -24,6 +24,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.NamespacedKey; +import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.craftbukkit.v1_15_R1.CraftServer; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; @@ -210,8 +211,13 @@ public ProfileEditor getProfileEditor() { } @Override - public BiomeNMS getBiomeNMS(Biome biome) { - return new BiomeNMSImpl(biome); + public BiomeNMS getBiomeNMS(World world, String name) { + for (Biome biome : Biome.values()) { + if (biome.name().equalsIgnoreCase(name)) { + return new BiomeNMSImpl(world, biome); + } + } + return null; } @Override diff --git a/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/impl/BiomeNMSImpl.java b/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/impl/BiomeNMSImpl.java index 27989f85e1..7bd1d34f54 100644 --- a/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/impl/BiomeNMSImpl.java +++ b/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/impl/BiomeNMSImpl.java @@ -3,7 +3,9 @@ import com.denizenscript.denizen.nms.abstracts.BiomeNMS; import com.denizenscript.denizencore.utilities.ReflectionHelper; import net.minecraft.server.v1_15_R1.*; +import org.bukkit.World; import org.bukkit.block.Biome; +import org.bukkit.block.Block; import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock; import org.bukkit.entity.EntityType; @@ -15,8 +17,11 @@ public class BiomeNMSImpl extends BiomeNMS { public BiomeBase biomeBase; - public BiomeNMSImpl(Biome biome) { - super(biome); + public Biome bukkitBiome; + + public BiomeNMSImpl(World world, Biome biome) { + super(world, biome.name()); + bukkitBiome = biome; this.biomeBase = CraftBlock.biomeToBiomeBase(biome); } @@ -88,4 +93,9 @@ private List getSpawnableEntities(EnumCreatureType creatureType) { } return entityTypes; } + + @Override + public void setTo(Block block) { + block.setBiome(bukkitBiome); + } } diff --git a/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/Handler.java b/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/Handler.java index 29c4e1969a..af95f429bf 100644 --- a/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/Handler.java +++ b/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/Handler.java @@ -9,6 +9,7 @@ import com.denizenscript.denizen.nms.v1_16.impl.blocks.BlockLightImpl; import com.denizenscript.denizen.nms.v1_16.impl.jnbt.CompoundTagImpl; import com.denizenscript.denizen.nms.util.jnbt.Tag; +import com.denizenscript.denizen.objects.BiomeTag; import com.denizenscript.denizen.objects.ItemTag; import com.denizenscript.denizen.utilities.FormattedTextHelper; import com.google.common.collect.Iterables; @@ -30,6 +31,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.NamespacedKey; +import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.craftbukkit.v1_16_R3.CraftServer; import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; @@ -217,8 +219,13 @@ public ProfileEditor getProfileEditor() { } @Override - public BiomeNMS getBiomeNMS(Biome biome) { - return new BiomeNMSImpl(biome); + public BiomeNMS getBiomeNMS(World world, String name) { + for (Biome biome : Biome.values()) { + if (biome.name().equalsIgnoreCase(name)) { + return new BiomeNMSImpl(world, biome); + } + } + return null; } @Override diff --git a/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/impl/BiomeNMSImpl.java b/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/impl/BiomeNMSImpl.java index ac8e7ec473..7ad578e710 100644 --- a/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/impl/BiomeNMSImpl.java +++ b/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/impl/BiomeNMSImpl.java @@ -3,9 +3,9 @@ import com.denizenscript.denizen.nms.abstracts.BiomeNMS; import com.denizenscript.denizencore.utilities.ReflectionHelper; import net.minecraft.server.v1_16_R3.*; -import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.block.Biome; +import org.bukkit.block.Block; import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock; import org.bukkit.entity.EntityType; @@ -18,9 +18,11 @@ public class BiomeNMSImpl extends BiomeNMS { public BiomeBase biomeBase; - public BiomeNMSImpl(Biome biome) { - super(biome); - World world = Bukkit.getWorlds().get(0); // TODO: Biomes can now be world-unique as of 1.16.2 + public Biome bukkitBiome; + + public BiomeNMSImpl(World world, Biome biome) { + super(world, biome.name()); + bukkitBiome = biome; this.biomeBase = CraftBlock.biomeToBiomeBase(((CraftWorld) world).getHandle().r().b(IRegistry.ay), biome); } @@ -97,4 +99,9 @@ private List getSpawnableEntities(EnumCreatureType creatureType) { } return entityTypes; } + + @Override + public void setTo(Block block) { + block.setBiome(bukkitBiome); + } } diff --git a/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/Handler.java b/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/Handler.java index ab45661b70..0bcaac822f 100644 --- a/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/Handler.java +++ b/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/Handler.java @@ -26,21 +26,27 @@ import net.md_5.bungee.api.chat.hover.content.Item; import net.md_5.bungee.api.chat.hover.content.Text; import net.md_5.bungee.chat.ComponentSerializer; +import net.minecraft.core.Registry; import net.minecraft.nbt.ByteArrayTag; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.TagParser; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.Container; import net.minecraft.world.Nameable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.biome.Biome; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.NamespacedKey; -import org.bukkit.block.Biome; +import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.craftbukkit.v1_17_R1.CraftServer; +import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventory; import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryCustom; @@ -226,8 +232,22 @@ public ProfileEditor getProfileEditor() { } @Override - public BiomeNMS getBiomeNMS(Biome biome) { - return new BiomeNMSImpl(biome); + public BiomeNMS getBiomeNMS(World world, String name) { + BiomeNMSImpl impl = new BiomeNMSImpl(((CraftWorld) world).getHandle(), name); + if (impl.biomeBase == null) { + return null; + } + return impl; + } + + @Override + public BiomeNMS getBiomeAt(Block block) { + // Based on CraftWorld source + ServerLevel level = ((CraftWorld) block.getWorld()).getHandle(); + Biome biome = level.getNoiseBiome(block.getX() >> 2, block.getY() >> 2, block.getZ() >> 2); + ResourceLocation key = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getKey(biome); + String keyText = key.getNamespace().equals("minecraft") ? key.getPath() : key.toString(); + return new BiomeNMSImpl(level, keyText); } @Override diff --git a/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/impl/BiomeNMSImpl.java b/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/impl/BiomeNMSImpl.java index 18eb858360..27637d857c 100644 --- a/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/impl/BiomeNMSImpl.java +++ b/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/impl/BiomeNMSImpl.java @@ -1,17 +1,19 @@ package com.denizenscript.denizen.nms.v1_17.impl; +import com.denizenscript.denizen.nms.NMSHandler; import com.denizenscript.denizen.nms.abstracts.BiomeNMS; import com.denizenscript.denizen.nms.v1_17.ReflectionMappingsInfo; import com.denizenscript.denizencore.utilities.ReflectionHelper; +import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.util.random.WeightedRandomList; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.level.biome.MobSpawnSettings; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.block.Biome; +import net.minecraft.world.level.chunk.LevelChunk; +import org.bukkit.block.Block; import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock; import org.bukkit.entity.EntityType; import java.util.ArrayList; @@ -22,10 +24,12 @@ public class BiomeNMSImpl extends BiomeNMS { public net.minecraft.world.level.biome.Biome biomeBase; - public BiomeNMSImpl(Biome biome) { - super(biome); - World world = Bukkit.getWorlds().get(0); // TODO: Biomes can now be world-unique as of 1.16.2 - this.biomeBase = CraftBlock.biomeToBiomeBase(((CraftWorld) world).getHandle().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), biome); + public ServerLevel world; + + public BiomeNMSImpl(ServerLevel world, String name) { + super(world.getWorld(), name); + this.world = world; + biomeBase = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).get(new ResourceLocation(name)); } @Override @@ -102,4 +106,21 @@ private List getSpawnableEntities(MobCategory creatureType) { } return entityTypes; } + + @Override + public void setTo(Block block) { + if (((CraftWorld) block.getWorld()).getHandle() != this.world) { + NMSHandler.getInstance().getBiomeNMS(block.getWorld(), getName()).setTo(block); + return; + } + // Based on CraftWorld source + BlockPos pos = new BlockPos(block.getX(), 0, block.getZ()); + if (world.hasChunkAt(pos)) { + LevelChunk chunk = world.getChunkAt(pos); + if (chunk != null) { + chunk.getBiomes().setBiome(block.getX() >> 2, block.getY() >> 2, block.getZ() >> 2, biomeBase); + chunk.markUnsaved(); + } + } + } }