mirror of https://github.com/Minestom/Minestom.git
Optionally load vanilla biomes (#1988)
* Add biomes from vanilla * cleanup * rework biomes * nullability * getByName string * expose vanilla biomes * not null * before rename * rename * nbt cache * fix * fix * fix * final on vanilla biome
This commit is contained in:
parent
1b9e186c3a
commit
7320437640
|
@ -27,6 +27,7 @@ public class Generators {
|
||||||
generator.generate(resource("blocks.json"), "net.minestom.server.instance.block", "Block", "BlockImpl", "Blocks");
|
generator.generate(resource("blocks.json"), "net.minestom.server.instance.block", "Block", "BlockImpl", "Blocks");
|
||||||
generator.generate(resource("items.json"), "net.minestom.server.item", "Material", "MaterialImpl", "Materials");
|
generator.generate(resource("items.json"), "net.minestom.server.item", "Material", "MaterialImpl", "Materials");
|
||||||
generator.generate(resource("entities.json"), "net.minestom.server.entity", "EntityType", "EntityTypeImpl", "EntityTypes");
|
generator.generate(resource("entities.json"), "net.minestom.server.entity", "EntityType", "EntityTypeImpl", "EntityTypes");
|
||||||
|
generator.generate(resource("biomes.json"), "net.minestom.server.world.biomes", "Biome", "BiomeImpl", "Biomes");
|
||||||
generator.generate(resource("enchantments.json"), "net.minestom.server.item", "Enchantment", "EnchantmentImpl", "Enchantments");
|
generator.generate(resource("enchantments.json"), "net.minestom.server.item", "Enchantment", "EnchantmentImpl", "Enchantments");
|
||||||
generator.generate(resource("potion_effects.json"), "net.minestom.server.potion", "PotionEffect", "PotionEffectImpl", "PotionEffects");
|
generator.generate(resource("potion_effects.json"), "net.minestom.server.potion", "PotionEffect", "PotionEffectImpl", "PotionEffects");
|
||||||
generator.generate(resource("potions.json"), "net.minestom.server.potion", "PotionType", "PotionTypeImpl", "PotionTypes");
|
generator.generate(resource("potions.json"), "net.minestom.server.potion", "PotionType", "PotionTypeImpl", "PotionTypes");
|
||||||
|
|
|
@ -36,6 +36,7 @@ public class Main {
|
||||||
MinecraftServer.setCompressionThreshold(0);
|
MinecraftServer.setCompressionThreshold(0);
|
||||||
|
|
||||||
MinecraftServer minecraftServer = MinecraftServer.init();
|
MinecraftServer minecraftServer = MinecraftServer.init();
|
||||||
|
MinecraftServer.getBiomeManager().loadVanillaBiomes();
|
||||||
|
|
||||||
BlockManager blockManager = MinecraftServer.getBlockManager();
|
BlockManager blockManager = MinecraftServer.getBlockManager();
|
||||||
blockManager.registerBlockPlacementRule(new DripstonePlacementRule());
|
blockManager.registerBlockPlacementRule(new DripstonePlacementRule());
|
||||||
|
|
|
@ -3,7 +3,7 @@ metadata.format.version = "1.1"
|
||||||
[versions]
|
[versions]
|
||||||
|
|
||||||
# Important dependencies
|
# Important dependencies
|
||||||
data = "1.20.4-rv2"
|
data = "1.20.4-rv3"
|
||||||
adventure = "4.15.0"
|
adventure = "4.15.0"
|
||||||
kotlin = "1.7.22"
|
kotlin = "1.7.22"
|
||||||
dependencyGetter = "v1.0.1"
|
dependencyGetter = "v1.0.1"
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
package net.minestom.server.world.biomes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code autogenerated, do not edit!
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
interface Biomes {
|
||||||
|
Biome SNOWY_SLOPES = BiomeImpl.get("minecraft:snowy_slopes");
|
||||||
|
|
||||||
|
Biome OLD_GROWTH_PINE_TAIGA = BiomeImpl.get("minecraft:old_growth_pine_taiga");
|
||||||
|
|
||||||
|
Biome MUSHROOM_FIELDS = BiomeImpl.get("minecraft:mushroom_fields");
|
||||||
|
|
||||||
|
Biome TAIGA = BiomeImpl.get("minecraft:taiga");
|
||||||
|
|
||||||
|
Biome DEEP_OCEAN = BiomeImpl.get("minecraft:deep_ocean");
|
||||||
|
|
||||||
|
Biome ERODED_BADLANDS = BiomeImpl.get("minecraft:eroded_badlands");
|
||||||
|
|
||||||
|
Biome FROZEN_RIVER = BiomeImpl.get("minecraft:frozen_river");
|
||||||
|
|
||||||
|
Biome END_HIGHLANDS = BiomeImpl.get("minecraft:end_highlands");
|
||||||
|
|
||||||
|
Biome CHERRY_GROVE = BiomeImpl.get("minecraft:cherry_grove");
|
||||||
|
|
||||||
|
Biome SUNFLOWER_PLAINS = BiomeImpl.get("minecraft:sunflower_plains");
|
||||||
|
|
||||||
|
Biome BIRCH_FOREST = BiomeImpl.get("minecraft:birch_forest");
|
||||||
|
|
||||||
|
Biome WINDSWEPT_HILLS = BiomeImpl.get("minecraft:windswept_hills");
|
||||||
|
|
||||||
|
Biome BAMBOO_JUNGLE = BiomeImpl.get("minecraft:bamboo_jungle");
|
||||||
|
|
||||||
|
Biome WOODED_BADLANDS = BiomeImpl.get("minecraft:wooded_badlands");
|
||||||
|
|
||||||
|
Biome BADLANDS = BiomeImpl.get("minecraft:badlands");
|
||||||
|
|
||||||
|
Biome SAVANNA_PLATEAU = BiomeImpl.get("minecraft:savanna_plateau");
|
||||||
|
|
||||||
|
Biome BEACH = BiomeImpl.get("minecraft:beach");
|
||||||
|
|
||||||
|
Biome DARK_FOREST = BiomeImpl.get("minecraft:dark_forest");
|
||||||
|
|
||||||
|
Biome STONY_PEAKS = BiomeImpl.get("minecraft:stony_peaks");
|
||||||
|
|
||||||
|
Biome MANGROVE_SWAMP = BiomeImpl.get("minecraft:mangrove_swamp");
|
||||||
|
|
||||||
|
Biome SPARSE_JUNGLE = BiomeImpl.get("minecraft:sparse_jungle");
|
||||||
|
|
||||||
|
Biome LUKEWARM_OCEAN = BiomeImpl.get("minecraft:lukewarm_ocean");
|
||||||
|
|
||||||
|
Biome RIVER = BiomeImpl.get("minecraft:river");
|
||||||
|
|
||||||
|
Biome STONY_SHORE = BiomeImpl.get("minecraft:stony_shore");
|
||||||
|
|
||||||
|
Biome WARPED_FOREST = BiomeImpl.get("minecraft:warped_forest");
|
||||||
|
|
||||||
|
Biome SNOWY_PLAINS = BiomeImpl.get("minecraft:snowy_plains");
|
||||||
|
|
||||||
|
Biome DRIPSTONE_CAVES = BiomeImpl.get("minecraft:dripstone_caves");
|
||||||
|
|
||||||
|
Biome SNOWY_TAIGA = BiomeImpl.get("minecraft:snowy_taiga");
|
||||||
|
|
||||||
|
Biome GROVE = BiomeImpl.get("minecraft:grove");
|
||||||
|
|
||||||
|
Biome SWAMP = BiomeImpl.get("minecraft:swamp");
|
||||||
|
|
||||||
|
Biome JAGGED_PEAKS = BiomeImpl.get("minecraft:jagged_peaks");
|
||||||
|
|
||||||
|
Biome COLD_OCEAN = BiomeImpl.get("minecraft:cold_ocean");
|
||||||
|
|
||||||
|
Biome FOREST = BiomeImpl.get("minecraft:forest");
|
||||||
|
|
||||||
|
Biome LUSH_CAVES = BiomeImpl.get("minecraft:lush_caves");
|
||||||
|
|
||||||
|
Biome BASALT_DELTAS = BiomeImpl.get("minecraft:basalt_deltas");
|
||||||
|
|
||||||
|
Biome DEEP_COLD_OCEAN = BiomeImpl.get("minecraft:deep_cold_ocean");
|
||||||
|
|
||||||
|
Biome ICE_SPIKES = BiomeImpl.get("minecraft:ice_spikes");
|
||||||
|
|
||||||
|
Biome END_MIDLANDS = BiomeImpl.get("minecraft:end_midlands");
|
||||||
|
|
||||||
|
Biome FROZEN_OCEAN = BiomeImpl.get("minecraft:frozen_ocean");
|
||||||
|
|
||||||
|
Biome DESERT = BiomeImpl.get("minecraft:desert");
|
||||||
|
|
||||||
|
Biome DEEP_FROZEN_OCEAN = BiomeImpl.get("minecraft:deep_frozen_ocean");
|
||||||
|
|
||||||
|
Biome WINDSWEPT_FOREST = BiomeImpl.get("minecraft:windswept_forest");
|
||||||
|
|
||||||
|
Biome JUNGLE = BiomeImpl.get("minecraft:jungle");
|
||||||
|
|
||||||
|
Biome OCEAN = BiomeImpl.get("minecraft:ocean");
|
||||||
|
|
||||||
|
Biome OLD_GROWTH_SPRUCE_TAIGA = BiomeImpl.get("minecraft:old_growth_spruce_taiga");
|
||||||
|
|
||||||
|
Biome SNOWY_BEACH = BiomeImpl.get("minecraft:snowy_beach");
|
||||||
|
|
||||||
|
Biome WINDSWEPT_SAVANNA = BiomeImpl.get("minecraft:windswept_savanna");
|
||||||
|
|
||||||
|
Biome END_BARRENS = BiomeImpl.get("minecraft:end_barrens");
|
||||||
|
|
||||||
|
Biome WARM_OCEAN = BiomeImpl.get("minecraft:warm_ocean");
|
||||||
|
|
||||||
|
Biome DEEP_LUKEWARM_OCEAN = BiomeImpl.get("minecraft:deep_lukewarm_ocean");
|
||||||
|
|
||||||
|
Biome FLOWER_FOREST = BiomeImpl.get("minecraft:flower_forest");
|
||||||
|
|
||||||
|
Biome SOUL_SAND_VALLEY = BiomeImpl.get("minecraft:soul_sand_valley");
|
||||||
|
|
||||||
|
Biome NETHER_WASTES = BiomeImpl.get("minecraft:nether_wastes");
|
||||||
|
|
||||||
|
Biome FROZEN_PEAKS = BiomeImpl.get("minecraft:frozen_peaks");
|
||||||
|
|
||||||
|
Biome THE_END = BiomeImpl.get("minecraft:the_end");
|
||||||
|
|
||||||
|
Biome SMALL_END_ISLANDS = BiomeImpl.get("minecraft:small_end_islands");
|
||||||
|
|
||||||
|
Biome OLD_GROWTH_BIRCH_FOREST = BiomeImpl.get("minecraft:old_growth_birch_forest");
|
||||||
|
|
||||||
|
Biome CRIMSON_FOREST = BiomeImpl.get("minecraft:crimson_forest");
|
||||||
|
|
||||||
|
Biome THE_VOID = BiomeImpl.get("minecraft:the_void");
|
||||||
|
|
||||||
|
Biome DEEP_DARK = BiomeImpl.get("minecraft:deep_dark");
|
||||||
|
|
||||||
|
Biome MEADOW = BiomeImpl.get("minecraft:meadow");
|
||||||
|
|
||||||
|
Biome WINDSWEPT_GRAVELLY_HILLS = BiomeImpl.get("minecraft:windswept_gravelly_hills");
|
||||||
|
|
||||||
|
Biome SAVANNA = BiomeImpl.get("minecraft:savanna");
|
||||||
|
|
||||||
|
Biome PLAINS = BiomeImpl.get("minecraft:plains");
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import net.minestom.server.command.builder.CommandExecutor;
|
||||||
import net.minestom.server.command.builder.arguments.minecraft.SuggestionType;
|
import net.minestom.server.command.builder.arguments.minecraft.SuggestionType;
|
||||||
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
|
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
|
||||||
import net.minestom.server.command.builder.suggestion.SuggestionCallback;
|
import net.minestom.server.command.builder.suggestion.SuggestionCallback;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
@ -30,10 +30,10 @@ import java.util.function.Supplier;
|
||||||
*/
|
*/
|
||||||
public abstract class Argument<T> {
|
public abstract class Argument<T> {
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public static final Registry.Container<ArgumentImpl> CONTAINER = Registry.createContainer(Registry.Resource.COMMAND_ARGUMENTS,
|
public static final Registry.Container<ArgumentImpl> CONTAINER = Registry.createStaticContainer(Registry.Resource.COMMAND_ARGUMENTS,
|
||||||
(namespace, properties) -> new ArgumentImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
(namespace, properties) -> new ArgumentImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
||||||
|
|
||||||
record ArgumentImpl(NamespaceID namespace, int id) implements ProtocolObject {
|
record ArgumentImpl(NamespaceID namespace, int id) implements StaticProtocolObject {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name();
|
return name();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package net.minestom.server.entity;
|
package net.minestom.server.entity;
|
||||||
|
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface EntityType extends ProtocolObject, EntityTypes permits EntityTypeImpl {
|
public sealed interface EntityType extends StaticProtocolObject, EntityTypes permits EntityTypeImpl {
|
||||||
/**
|
/**
|
||||||
* Returns the entity registry.
|
* Returns the entity registry.
|
||||||
*
|
*
|
||||||
|
|
|
@ -42,7 +42,7 @@ import java.util.function.BiFunction;
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
|
|
||||||
record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType {
|
record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType {
|
||||||
private static final Registry.Container<EntityType> CONTAINER = Registry.createContainer(Registry.Resource.ENTITIES,
|
private static final Registry.Container<EntityType> CONTAINER = Registry.createStaticContainer(Registry.Resource.ENTITIES,
|
||||||
(namespace, properties) -> new EntityTypeImpl(Registry.entity(namespace, properties)));
|
(namespace, properties) -> new EntityTypeImpl(Registry.entity(namespace, properties)));
|
||||||
static final Map<String, BiFunction<Entity, Metadata, EntityMeta>> ENTITY_META_SUPPLIER = createMetaMap();
|
static final Map<String, BiFunction<Entity, Metadata, EntityMeta>> ENTITY_META_SUPPLIER = createMetaMap();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package net.minestom.server.entity.damage;
|
package net.minestom.server.entity.damage;
|
||||||
|
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
@ -10,7 +10,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface DamageType extends ProtocolObject, DamageTypes permits DamageTypeImpl {
|
public sealed interface DamageType extends StaticProtocolObject, DamageTypes permits DamageTypeImpl {
|
||||||
/**
|
/**
|
||||||
* Returns the damage type registry.
|
* Returns the damage type registry.
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,7 +16,7 @@ record DamageTypeImpl(Registry.DamageTypeEntry registry, int id) implements Dama
|
||||||
|
|
||||||
static {
|
static {
|
||||||
AtomicInteger i = new AtomicInteger();
|
AtomicInteger i = new AtomicInteger();
|
||||||
CONTAINER = Registry.createContainer(Registry.Resource.DAMAGE_TYPES,
|
CONTAINER = Registry.createStaticContainer(Registry.Resource.DAMAGE_TYPES,
|
||||||
(namespace, properties) -> new DamageTypeImpl(Registry.damageType(namespace, properties), i.getAndIncrement()));
|
(namespace, properties) -> new DamageTypeImpl(Registry.damageType(namespace, properties), i.getAndIncrement()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class AnvilLoader implements IChunkLoader {
|
public class AnvilLoader implements IChunkLoader {
|
||||||
private final static Logger LOGGER = LoggerFactory.getLogger(AnvilLoader.class);
|
private final static Logger LOGGER = LoggerFactory.getLogger(AnvilLoader.class);
|
||||||
private static final Biome BIOME = Biome.PLAINS;
|
private final static Biome PLAINS = MinecraftServer.getBiomeManager().getByName(NamespaceID.from("minecraft:plains"));
|
||||||
|
|
||||||
private final Map<String, RegionFile> alreadyLoaded = new ConcurrentHashMap<>();
|
private final Map<String, RegionFile> alreadyLoaded = new ConcurrentHashMap<>();
|
||||||
private final Path path;
|
private final Path path;
|
||||||
|
@ -189,7 +189,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||||
int finalY = sectionY * Chunk.CHUNK_SECTION_SIZE + y;
|
int finalY = sectionY * Chunk.CHUNK_SECTION_SIZE + y;
|
||||||
String biomeName = sectionBiomeInformation.getBaseBiome();
|
String biomeName = sectionBiomeInformation.getBaseBiome();
|
||||||
Biome biome = biomeCache.computeIfAbsent(biomeName, n ->
|
Biome biome = biomeCache.computeIfAbsent(biomeName, n ->
|
||||||
Objects.requireNonNullElse(MinecraftServer.getBiomeManager().getByName(NamespaceID.from(n)), BIOME));
|
Objects.requireNonNullElse(MinecraftServer.getBiomeManager().getByName(NamespaceID.from(n)), PLAINS));
|
||||||
chunk.setBiome(finalX, finalY, finalZ, biome);
|
chunk.setBiome(finalX, finalY, finalZ, biome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||||
int index = x / 4 + (z / 4) * 4 + (y / 4) * 16;
|
int index = x / 4 + (z / 4) * 4 + (y / 4) * 16;
|
||||||
String biomeName = sectionBiomeInformation.getBiomes()[index];
|
String biomeName = sectionBiomeInformation.getBiomes()[index];
|
||||||
Biome biome = biomeCache.computeIfAbsent(biomeName, n ->
|
Biome biome = biomeCache.computeIfAbsent(biomeName, n ->
|
||||||
Objects.requireNonNullElse(MinecraftServer.getBiomeManager().getByName(NamespaceID.from(n)), BIOME));
|
Objects.requireNonNullElse(MinecraftServer.getBiomeManager().getByName(NamespaceID.from(n)), PLAINS));
|
||||||
chunk.setBiome(finalX, finalY, finalZ, biome);
|
chunk.setBiome(finalX, finalY, finalZ, biome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,7 +400,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||||
if (x % 4 == 0 && sectionLocalY % 4 == 0 && z % 4 == 0) {
|
if (x % 4 == 0 && sectionLocalY % 4 == 0 && z % 4 == 0) {
|
||||||
int biomeIndex = (x / 4) + (sectionLocalY / 4) * 4 * 4 + (z / 4) * 4;
|
int biomeIndex = (x / 4) + (sectionLocalY / 4) * 4 * 4 + (z / 4) * 4;
|
||||||
final Biome biome = chunk.getBiome(x, y, z);
|
final Biome biome = chunk.getBiome(x, y, z);
|
||||||
final String biomeName = biome.name().asString();
|
final String biomeName = biome.name();
|
||||||
|
|
||||||
biomePalette.increaseReference(biomeName);
|
biomePalette.increaseReference(biomeName);
|
||||||
palettedBiomes[biomeIndex] = biomePalette.getPaletteIndex(biomeName);
|
palettedBiomes[biomeIndex] = biomePalette.getPaletteIndex(biomeName);
|
||||||
|
|
|
@ -24,6 +24,7 @@ import net.minestom.server.utils.MathUtils;
|
||||||
import net.minestom.server.utils.ObjectPool;
|
import net.minestom.server.utils.ObjectPool;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
import net.minestom.server.world.biomes.Biome;
|
import net.minestom.server.world.biomes.Biome;
|
||||||
|
import net.minestom.server.world.biomes.BiomeManager;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||||
|
@ -51,6 +52,7 @@ public class DynamicChunk extends Chunk {
|
||||||
|
|
||||||
private long lastChange;
|
private long lastChange;
|
||||||
final CachedPacket chunkCache = new CachedPacket(this::createChunkPacket);
|
final CachedPacket chunkCache = new CachedPacket(this::createChunkPacket);
|
||||||
|
private static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager();
|
||||||
|
|
||||||
public DynamicChunk(@NotNull Instance instance, int chunkX, int chunkZ) {
|
public DynamicChunk(@NotNull Instance instance, int chunkX, int chunkZ) {
|
||||||
super(instance, chunkX, chunkZ, true);
|
super(instance, chunkX, chunkZ, true);
|
||||||
|
@ -124,10 +126,14 @@ public class DynamicChunk extends Chunk {
|
||||||
assertLock();
|
assertLock();
|
||||||
this.chunkCache.invalidate();
|
this.chunkCache.invalidate();
|
||||||
Section section = getSectionAt(y);
|
Section section = getSectionAt(y);
|
||||||
|
|
||||||
|
var id = BIOME_MANAGER.getId(biome);
|
||||||
|
if (id == -1) throw new IllegalStateException("Biome has not been registered: " + biome.namespace());
|
||||||
|
|
||||||
section.biomePalette().set(
|
section.biomePalette().set(
|
||||||
toSectionRelativeCoordinate(x) / 4,
|
toSectionRelativeCoordinate(x) / 4,
|
||||||
toSectionRelativeCoordinate(y) / 4,
|
toSectionRelativeCoordinate(y) / 4,
|
||||||
toSectionRelativeCoordinate(z) / 4, biome.id());
|
toSectionRelativeCoordinate(z) / 4, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -180,7 +186,13 @@ public class DynamicChunk extends Chunk {
|
||||||
final Section section = getSectionAt(y);
|
final Section section = getSectionAt(y);
|
||||||
final int id = section.biomePalette()
|
final int id = section.biomePalette()
|
||||||
.get(toSectionRelativeCoordinate(x) / 4, toSectionRelativeCoordinate(y) / 4, toSectionRelativeCoordinate(z) / 4);
|
.get(toSectionRelativeCoordinate(x) / 4, toSectionRelativeCoordinate(y) / 4, toSectionRelativeCoordinate(z) / 4);
|
||||||
return MinecraftServer.getBiomeManager().getById(id);
|
|
||||||
|
Biome biome = BIOME_MANAGER.getById(id);
|
||||||
|
if (biome == null) {
|
||||||
|
throw new IllegalStateException("Biome with id " + id + " is not registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
return biome;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,6 +2,7 @@ package net.minestom.server.instance;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
|
@ -9,6 +10,7 @@ import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
import net.minestom.server.instance.generator.UnitModifier;
|
import net.minestom.server.instance.generator.UnitModifier;
|
||||||
import net.minestom.server.instance.palette.Palette;
|
import net.minestom.server.instance.palette.Palette;
|
||||||
import net.minestom.server.world.biomes.Biome;
|
import net.minestom.server.world.biomes.Biome;
|
||||||
|
import net.minestom.server.world.biomes.BiomeManager;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -21,6 +23,7 @@ import static net.minestom.server.utils.chunk.ChunkUtils.*;
|
||||||
|
|
||||||
final class GeneratorImpl {
|
final class GeneratorImpl {
|
||||||
private static final Vec SECTION_SIZE = new Vec(16);
|
private static final Vec SECTION_SIZE = new Vec(16);
|
||||||
|
private static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager();
|
||||||
|
|
||||||
static GenerationUnit section(Section section, int sectionX, int sectionY, int sectionZ,
|
static GenerationUnit section(Section section, int sectionX, int sectionY, int sectionZ,
|
||||||
boolean fork) {
|
boolean fork) {
|
||||||
|
@ -217,10 +220,13 @@ final class GeneratorImpl {
|
||||||
@Override
|
@Override
|
||||||
public void setBiome(int x, int y, int z, @NotNull Biome biome) {
|
public void setBiome(int x, int y, int z, @NotNull Biome biome) {
|
||||||
if (fork) throw new IllegalStateException("Cannot modify biomes of a fork");
|
if (fork) throw new IllegalStateException("Cannot modify biomes of a fork");
|
||||||
|
var id = BIOME_MANAGER.getId(biome);
|
||||||
|
if (id == -1) throw new IllegalStateException("Biome has not been registered: " + biome.namespace());
|
||||||
|
|
||||||
this.biomePalette.set(
|
this.biomePalette.set(
|
||||||
toSectionRelativeCoordinate(x) / 4,
|
toSectionRelativeCoordinate(x) / 4,
|
||||||
toSectionRelativeCoordinate(y) / 4,
|
toSectionRelativeCoordinate(y) / 4,
|
||||||
toSectionRelativeCoordinate(z) / 4, biome.id());
|
toSectionRelativeCoordinate(z) / 4, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -264,7 +270,9 @@ final class GeneratorImpl {
|
||||||
@Override
|
@Override
|
||||||
public void fillBiome(@NotNull Biome biome) {
|
public void fillBiome(@NotNull Biome biome) {
|
||||||
if (fork) throw new IllegalStateException("Cannot modify biomes of a fork");
|
if (fork) throw new IllegalStateException("Cannot modify biomes of a fork");
|
||||||
this.biomePalette.fill(biome.id());
|
var id = MinecraftServer.getBiomeManager().getId(biome);
|
||||||
|
if (id == -1) throw new IllegalStateException("Biome has not been registered: " + biome.namespace());
|
||||||
|
this.biomePalette.fill(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int retrieveBlockId(Block block) {
|
private int retrieveBlockId(Block block) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package net.minestom.server.instance.block;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
import net.minestom.server.instance.batch.Batch;
|
import net.minestom.server.instance.batch.Batch;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.tag.Tag;
|
import net.minestom.server.tag.Tag;
|
||||||
import net.minestom.server.tag.TagReadable;
|
import net.minestom.server.tag.TagReadable;
|
||||||
|
@ -23,7 +23,7 @@ import java.util.function.BiPredicate;
|
||||||
* <p>
|
* <p>
|
||||||
* Implementations are expected to be immutable.
|
* Implementations are expected to be immutable.
|
||||||
*/
|
*/
|
||||||
public sealed interface Block extends ProtocolObject, TagReadable, Blocks permits BlockImpl {
|
public sealed interface Block extends StaticProtocolObject, TagReadable, Blocks permits BlockImpl {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new block with the the property {@code property} sets to {@code value}.
|
* Creates a new block with the the property {@code property} sets to {@code value}.
|
||||||
|
|
|
@ -31,7 +31,7 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
|
||||||
private static final ObjectArray<PropertyType[]> PROPERTIES_TYPE = ObjectArray.singleThread();
|
private static final ObjectArray<PropertyType[]> PROPERTIES_TYPE = ObjectArray.singleThread();
|
||||||
// Block id -> Map<PropertiesValues, Block>
|
// Block id -> Map<PropertiesValues, Block>
|
||||||
private static final ObjectArray<Map<PropertiesHolder, BlockImpl>> POSSIBLE_STATES = ObjectArray.singleThread();
|
private static final ObjectArray<Map<PropertiesHolder, BlockImpl>> POSSIBLE_STATES = ObjectArray.singleThread();
|
||||||
private static final Registry.Container<Block> CONTAINER = Registry.createContainer(Registry.Resource.BLOCKS,
|
private static final Registry.Container<Block> CONTAINER = Registry.createStaticContainer(Registry.Resource.BLOCKS,
|
||||||
(namespace, properties) -> {
|
(namespace, properties) -> {
|
||||||
final int blockId = properties.getInt("id");
|
final int blockId = properties.getInt("id");
|
||||||
final Registry.Properties stateObject = properties.section("states");
|
final Registry.Properties stateObject = properties.section("states");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package net.minestom.server.item;
|
package net.minestom.server.item;
|
||||||
|
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface Enchantment extends ProtocolObject, Enchantments permits EnchantmentImpl {
|
public sealed interface Enchantment extends StaticProtocolObject, Enchantments permits EnchantmentImpl {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the enchantment registry.
|
* Returns the enchantment registry.
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
record EnchantmentImpl(Registry.EnchantmentEntry registry) implements Enchantment {
|
record EnchantmentImpl(Registry.EnchantmentEntry registry) implements Enchantment {
|
||||||
private static final Registry.Container<Enchantment> CONTAINER = Registry.createContainer(Registry.Resource.ENCHANTMENTS,
|
private static final Registry.Container<Enchantment> CONTAINER = Registry.createStaticContainer(Registry.Resource.ENCHANTMENTS,
|
||||||
(namespace, properties) -> new EnchantmentImpl(Registry.enchantment(namespace, properties)));
|
(namespace, properties) -> new EnchantmentImpl(Registry.enchantment(namespace, properties)));
|
||||||
|
|
||||||
static Enchantment get(@NotNull String namespace) {
|
static Enchantment get(@NotNull String namespace) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.item.attribute.ItemAttribute;
|
import net.minestom.server.item.attribute.ItemAttribute;
|
||||||
import net.minestom.server.network.NetworkBuffer;
|
import net.minestom.server.network.NetworkBuffer;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.tag.Tag;
|
import net.minestom.server.tag.Tag;
|
||||||
import net.minestom.server.tag.TagReadable;
|
import net.minestom.server.tag.TagReadable;
|
||||||
import net.minestom.server.tag.Taggable;
|
import net.minestom.server.tag.Taggable;
|
||||||
|
@ -165,7 +165,7 @@ public sealed interface ItemMeta extends TagReadable, NetworkBuffer.Writer
|
||||||
|
|
||||||
@Contract("_ -> this")
|
@Contract("_ -> this")
|
||||||
default @NotNull Builder canPlaceOn(@NotNull Set<@NotNull Block> blocks) {
|
default @NotNull Builder canPlaceOn(@NotNull Set<@NotNull Block> blocks) {
|
||||||
return set(ItemTags.CAN_PLACE_ON, blocks.stream().map(ProtocolObject::name).toList());
|
return set(ItemTags.CAN_PLACE_ON, blocks.stream().map(StaticProtocolObject::name).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Contract("_ -> this")
|
@Contract("_ -> this")
|
||||||
|
@ -175,7 +175,7 @@ public sealed interface ItemMeta extends TagReadable, NetworkBuffer.Writer
|
||||||
|
|
||||||
@Contract("_ -> this")
|
@Contract("_ -> this")
|
||||||
default @NotNull Builder canDestroy(@NotNull Set<@NotNull Block> blocks) {
|
default @NotNull Builder canDestroy(@NotNull Set<@NotNull Block> blocks) {
|
||||||
return set(ItemTags.CAN_DESTROY, blocks.stream().map(ProtocolObject::name).toList());
|
return set(ItemTags.CAN_DESTROY, blocks.stream().map(StaticProtocolObject::name).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Contract("_ -> this")
|
@Contract("_ -> this")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package net.minestom.server.item;
|
package net.minestom.server.item;
|
||||||
|
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface Material extends ProtocolObject, Materials permits MaterialImpl {
|
public sealed interface Material extends StaticProtocolObject, Materials permits MaterialImpl {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the material registry.
|
* Returns the material registry.
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
record MaterialImpl(Registry.MaterialEntry registry) implements Material {
|
record MaterialImpl(Registry.MaterialEntry registry) implements Material {
|
||||||
private static final Registry.Container<Material> CONTAINER = Registry.createContainer(Registry.Resource.ITEMS,
|
private static final Registry.Container<Material> CONTAINER = Registry.createStaticContainer(Registry.Resource.ITEMS,
|
||||||
(namespace, properties) -> new MaterialImpl(Registry.material(namespace, properties)));
|
(namespace, properties) -> new MaterialImpl(Registry.material(namespace, properties)));
|
||||||
|
|
||||||
static Material get(@NotNull String namespace) {
|
static Material get(@NotNull String namespace) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ package net.minestom.server.item.armor;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
@ -12,7 +12,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface TrimMaterial extends ProtocolObject {
|
public interface TrimMaterial extends StaticProtocolObject {
|
||||||
static @NotNull TrimMaterial create(@NotNull NamespaceID namespace,
|
static @NotNull TrimMaterial create(@NotNull NamespaceID namespace,
|
||||||
@NotNull String assetName,
|
@NotNull String assetName,
|
||||||
@NotNull Material ingredient,
|
@NotNull Material ingredient,
|
||||||
|
|
|
@ -15,7 +15,7 @@ record TrimMaterialImpl(Registry.TrimMaterialEntry registry, int id) implements
|
||||||
private static final Registry.Container<TrimMaterial> CONTAINER;
|
private static final Registry.Container<TrimMaterial> CONTAINER;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
CONTAINER = Registry.createContainer(Registry.Resource.TRIM_MATERIALS,
|
CONTAINER = Registry.createStaticContainer(Registry.Resource.TRIM_MATERIALS,
|
||||||
(namespace, properties) -> new TrimMaterialImpl(Registry.trimMaterial(namespace, properties)));
|
(namespace, properties) -> new TrimMaterialImpl(Registry.trimMaterial(namespace, properties)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package net.minestom.server.item.armor;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
@ -11,7 +11,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public interface TrimPattern extends ProtocolObject {
|
public interface TrimPattern extends StaticProtocolObject {
|
||||||
static @NotNull TrimPattern create(@NotNull NamespaceID namespace,
|
static @NotNull TrimPattern create(@NotNull NamespaceID namespace,
|
||||||
@NotNull NamespaceID assetID,
|
@NotNull NamespaceID assetID,
|
||||||
@NotNull Material template,
|
@NotNull Material template,
|
||||||
|
|
|
@ -13,7 +13,7 @@ record TrimPatternImpl(Registry.TrimPatternEntry registry, int id) implements Tr
|
||||||
private static final Registry.Container<TrimPattern> CONTAINER;
|
private static final Registry.Container<TrimPattern> CONTAINER;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
CONTAINER = Registry.createContainer(Registry.Resource.TRIM_PATTERNS,
|
CONTAINER = Registry.createStaticContainer(Registry.Resource.TRIM_PATTERNS,
|
||||||
(namespace, properties) -> new TrimPatternImpl(Registry.trimPattern(namespace, properties)));
|
(namespace, properties) -> new TrimPatternImpl(Registry.trimPattern(namespace, properties)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import net.minestom.server.color.Color;
|
||||||
import net.minestom.server.item.ItemMetaView;
|
import net.minestom.server.item.ItemMetaView;
|
||||||
import net.minestom.server.potion.CustomPotionEffect;
|
import net.minestom.server.potion.CustomPotionEffect;
|
||||||
import net.minestom.server.potion.PotionType;
|
import net.minestom.server.potion.PotionType;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.tag.*;
|
import net.minestom.server.tag.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -13,7 +13,7 @@ import org.jetbrains.annotations.UnknownNullability;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public record PotionMeta(TagReadable readable) implements ItemMetaView<PotionMeta.Builder> {
|
public record PotionMeta(TagReadable readable) implements ItemMetaView<PotionMeta.Builder> {
|
||||||
private static final Tag<PotionType> POTION_TYPE = Tag.String("Potion").map(PotionType::fromNamespaceId, ProtocolObject::name).defaultValue(PotionType.EMPTY);
|
private static final Tag<PotionType> POTION_TYPE = Tag.String("Potion").map(PotionType::fromNamespaceId, StaticProtocolObject::name).defaultValue(PotionType.EMPTY);
|
||||||
private static final Tag<List<CustomPotionEffect>> CUSTOM_POTION_EFFECTS = Tag.Structure("CustomPotionEffects", new TagSerializer<CustomPotionEffect>() {
|
private static final Tag<List<CustomPotionEffect>> CUSTOM_POTION_EFFECTS = Tag.Structure("CustomPotionEffects", new TagSerializer<CustomPotionEffect>() {
|
||||||
@Override
|
@Override
|
||||||
public @Nullable CustomPotionEffect read(@NotNull TagReadable reader) {
|
public @Nullable CustomPotionEffect read(@NotNull TagReadable reader) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import net.minestom.server.network.ConnectionState;
|
||||||
import net.minestom.server.network.NetworkBuffer;
|
import net.minestom.server.network.NetworkBuffer;
|
||||||
import net.minestom.server.network.packet.server.ServerPacket;
|
import net.minestom.server.network.packet.server.ServerPacket;
|
||||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.utils.PacketUtils;
|
import net.minestom.server.utils.PacketUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ public record DeclareCommandsPacket(@NotNull List<Node> nodes,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isArgument()) {
|
if (isArgument()) {
|
||||||
final ProtocolObject object = Argument.CONTAINER.getId(reader.read(VAR_INT));
|
final StaticProtocolObject object = Argument.CONTAINER.getId(reader.read(VAR_INT));
|
||||||
parser = object.name();
|
parser = object.name();
|
||||||
properties = getProperties(reader, parser);
|
properties = getProperties(reader, parser);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package net.minestom.server.particle;
|
package net.minestom.server.particle;
|
||||||
|
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface Particle extends ProtocolObject, Particles permits ParticleImpl {
|
public sealed interface Particle extends StaticProtocolObject, Particles permits ParticleImpl {
|
||||||
|
|
||||||
static @NotNull Collection<@NotNull Particle> values() {
|
static @NotNull Collection<@NotNull Particle> values() {
|
||||||
return ParticleImpl.values();
|
return ParticleImpl.values();
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
record ParticleImpl(NamespaceID namespace, int id) implements Particle {
|
record ParticleImpl(NamespaceID namespace, int id) implements Particle {
|
||||||
private static final Registry.Container<Particle> CONTAINER = Registry.createContainer(Registry.Resource.PARTICLES,
|
private static final Registry.Container<Particle> CONTAINER = Registry.createStaticContainer(Registry.Resource.PARTICLES,
|
||||||
(namespace, properties) -> new ParticleImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
(namespace, properties) -> new ParticleImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
||||||
|
|
||||||
static Particle get(@NotNull String namespace) {
|
static Particle get(@NotNull String namespace) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package net.minestom.server.potion;
|
package net.minestom.server.potion;
|
||||||
|
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.registry.Registry;
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface PotionEffect extends ProtocolObject, PotionEffects permits PotionEffectImpl {
|
public sealed interface PotionEffect extends StaticProtocolObject, PotionEffects permits PotionEffectImpl {
|
||||||
|
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
@NotNull Registry.PotionEffectEntry registry();
|
@NotNull Registry.PotionEffectEntry registry();
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
record PotionEffectImpl(Registry.PotionEffectEntry registry) implements PotionEffect {
|
record PotionEffectImpl(Registry.PotionEffectEntry registry) implements PotionEffect {
|
||||||
private static final Registry.Container<PotionEffect> CONTAINER = Registry.createContainer(Registry.Resource.POTION_EFFECTS,
|
private static final Registry.Container<PotionEffect> CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_EFFECTS,
|
||||||
(namespace, properties) -> new PotionEffectImpl(Registry.potionEffect(namespace, properties)));
|
(namespace, properties) -> new PotionEffectImpl(Registry.potionEffect(namespace, properties)));
|
||||||
|
|
||||||
static PotionEffect get(@NotNull String namespace) {
|
static PotionEffect get(@NotNull String namespace) {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package net.minestom.server.potion;
|
package net.minestom.server.potion;
|
||||||
|
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface PotionType extends ProtocolObject, PotionTypes permits PotionTypeImpl {
|
public sealed interface PotionType extends StaticProtocolObject, PotionTypes permits PotionTypeImpl {
|
||||||
|
|
||||||
static @NotNull Collection<@NotNull PotionType> values() {
|
static @NotNull Collection<@NotNull PotionType> values() {
|
||||||
return PotionTypeImpl.values();
|
return PotionTypeImpl.values();
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
record PotionTypeImpl(NamespaceID namespace, int id) implements PotionType {
|
record PotionTypeImpl(NamespaceID namespace, int id) implements PotionType {
|
||||||
private static final Registry.Container<PotionType> CONTAINER = Registry.createContainer(Registry.Resource.POTION_TYPES,
|
private static final Registry.Container<PotionType> CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_TYPES,
|
||||||
(namespace, properties) -> new PotionTypeImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
(namespace, properties) -> new PotionTypeImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
||||||
|
|
||||||
static PotionType get(@NotNull String namespace) {
|
static PotionType get(@NotNull String namespace) {
|
||||||
|
|
|
@ -11,17 +11,14 @@ public interface ProtocolObject extends Keyed {
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
@NotNull NamespaceID namespace();
|
@NotNull NamespaceID namespace();
|
||||||
|
|
||||||
@Override
|
|
||||||
@Contract(pure = true)
|
|
||||||
default @NotNull Key key() {
|
|
||||||
return namespace();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
default @NotNull String name() {
|
default @NotNull String name() {
|
||||||
return namespace().asString();
|
return namespace().asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
int id();
|
default @NotNull Key key() {
|
||||||
|
return namespace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles registry data, used by {@link ProtocolObject} implementations and is strictly internal.
|
* Handles registry data, used by {@link StaticProtocolObject} implementations and is strictly internal.
|
||||||
* Use at your own risk.
|
* Use at your own risk.
|
||||||
*/
|
*/
|
||||||
public final class Registry {
|
public final class Registry {
|
||||||
|
@ -37,6 +37,11 @@ public final class Registry {
|
||||||
return new BlockEntry(namespace, main, null);
|
return new BlockEntry(namespace, main, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static BiomeEntry biome(String namespace, Properties properties) {
|
||||||
|
return new BiomeEntry(namespace, properties, null);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public static MaterialEntry material(String namespace, @NotNull Properties main) {
|
public static MaterialEntry material(String namespace, @NotNull Properties main) {
|
||||||
return new MaterialEntry(namespace, main, null);
|
return new MaterialEntry(namespace, main, null);
|
||||||
|
@ -89,7 +94,7 @@ public final class Registry {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public static <T extends ProtocolObject> Container<T> createContainer(Resource resource, Container.Loader<T> loader) {
|
public static <T extends StaticProtocolObject> Container<T> createStaticContainer(Resource resource, Container.Loader<T> loader) {
|
||||||
var entries = Registry.load(resource);
|
var entries = Registry.load(resource);
|
||||||
Map<String, T> namespaces = new HashMap<>(entries.size());
|
Map<String, T> namespaces = new HashMap<>(entries.size());
|
||||||
ObjectArray<T> ids = ObjectArray.singleThread(entries.size());
|
ObjectArray<T> ids = ObjectArray.singleThread(entries.size());
|
||||||
|
@ -104,9 +109,9 @@ public final class Registry {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public record Container<T extends ProtocolObject>(Resource resource,
|
public record Container<T extends StaticProtocolObject>(Resource resource,
|
||||||
Map<String, T> namespaces,
|
Map<String, T> namespaces,
|
||||||
ObjectArray<T> ids) {
|
ObjectArray<T> ids) {
|
||||||
public Container {
|
public Container {
|
||||||
namespaces = Map.copyOf(namespaces);
|
namespaces = Map.copyOf(namespaces);
|
||||||
ids.trim();
|
ids.trim();
|
||||||
|
@ -149,6 +154,54 @@ public final class Registry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static <T extends ProtocolObject> DynamicContainer<T> createDynamicContainer(Resource resource, Container.Loader<T> loader) {
|
||||||
|
var entries = Registry.load(resource);
|
||||||
|
Map<String, T> namespaces = new HashMap<>(entries.size());
|
||||||
|
for (var entry : entries.entrySet()) {
|
||||||
|
final String namespace = entry.getKey();
|
||||||
|
final Properties properties = Properties.fromMap(entry.getValue());
|
||||||
|
final T value = loader.get(namespace, properties);
|
||||||
|
namespaces.put(value.name(), value);
|
||||||
|
}
|
||||||
|
return new DynamicContainer<>(resource, namespaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public record DynamicContainer<T>(Resource resource, Map<String, T> namespaces) {
|
||||||
|
public DynamicContainer {
|
||||||
|
namespaces = Map.copyOf(namespaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T get(@NotNull String namespace) {
|
||||||
|
return namespaces.get(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getSafe(@NotNull String namespace) {
|
||||||
|
return get(namespace.contains(":") ? namespace : "minecraft:" + namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<T> values() {
|
||||||
|
return namespaces.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof Container<?> container)) return false;
|
||||||
|
return resource == container.resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Loader<T extends ProtocolObject> {
|
||||||
|
T get(String namespace, Properties properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public enum Resource {
|
public enum Resource {
|
||||||
BLOCKS("blocks.json"),
|
BLOCKS("blocks.json"),
|
||||||
|
@ -168,7 +221,8 @@ public final class Registry {
|
||||||
ENTITY_TYPE_TAGS("tags/entity_type_tags.json"),
|
ENTITY_TYPE_TAGS("tags/entity_type_tags.json"),
|
||||||
FLUID_TAGS("tags/fluid_tags.json"),
|
FLUID_TAGS("tags/fluid_tags.json"),
|
||||||
GAMEPLAY_TAGS("tags/gameplay_tags.json"),
|
GAMEPLAY_TAGS("tags/gameplay_tags.json"),
|
||||||
ITEM_TAGS("tags/item_tags.json");
|
ITEM_TAGS("tags/item_tags.json"),
|
||||||
|
BIOMES("biomes.json");
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
@ -323,6 +377,81 @@ public final class Registry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class BiomeEntry implements Entry {
|
||||||
|
private final Properties custom;
|
||||||
|
private final NamespaceID namespace;
|
||||||
|
private final Integer foliageColor;
|
||||||
|
private final Integer grassColor;
|
||||||
|
private final Integer skyColor;
|
||||||
|
private final Integer waterColor;
|
||||||
|
private final Integer waterFogColor;
|
||||||
|
private final Integer fogColor;
|
||||||
|
private final float temperature;
|
||||||
|
private final float downfall;
|
||||||
|
private final boolean hasPrecipitation;
|
||||||
|
|
||||||
|
private BiomeEntry(String namespace, Properties main, Properties custom) {
|
||||||
|
this.custom = custom;
|
||||||
|
this.namespace = NamespaceID.from(namespace);
|
||||||
|
|
||||||
|
this.foliageColor = main.containsKey("foliageColor") ? main.getInt("foliageColor") : null;
|
||||||
|
this.grassColor = main.containsKey("grassColor") ? main.getInt("grassColor") : null;
|
||||||
|
this.skyColor = main.containsKey("skyColor") ? main.getInt("skyColor") : null;
|
||||||
|
this.waterColor = main.containsKey("waterColor") ? main.getInt("waterColor") : null;
|
||||||
|
this.waterFogColor = main.containsKey("waterFogColor") ? main.getInt("waterFogColor") : null;
|
||||||
|
this.fogColor = main.containsKey("fogColor") ? main.getInt("fogColor") : null;
|
||||||
|
|
||||||
|
this.temperature = (float) main.getDouble("temperature", 0.5F);
|
||||||
|
this.downfall = (float) main.getDouble("downfall", 0.5F);
|
||||||
|
this.hasPrecipitation = main.getBoolean("has_precipitation", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Properties custom() {
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull NamespaceID namespace() {
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer foliageColor() {
|
||||||
|
return foliageColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer grassColor() {
|
||||||
|
return grassColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer skyColor() {
|
||||||
|
return skyColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer waterColor() {
|
||||||
|
return waterColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer waterFogColor() {
|
||||||
|
return waterFogColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer fogColor() {
|
||||||
|
return fogColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float temperature() {
|
||||||
|
return temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float downfall() {
|
||||||
|
return downfall;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPrecipitation() {
|
||||||
|
return hasPrecipitation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final class MaterialEntry implements Entry {
|
public static final class MaterialEntry implements Entry {
|
||||||
private final NamespaceID namespace;
|
private final NamespaceID namespace;
|
||||||
private final int id;
|
private final int id;
|
||||||
|
@ -600,6 +729,11 @@ public final class Registry {
|
||||||
return new PropertiesMap(map);
|
return new PropertiesMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(String name) {
|
||||||
|
return map.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> asMap() {
|
public Map<String, Object> asMap() {
|
||||||
return map;
|
return map;
|
||||||
|
@ -642,6 +776,8 @@ public final class Registry {
|
||||||
|
|
||||||
Properties section(String name);
|
Properties section(String name);
|
||||||
|
|
||||||
|
boolean containsKey(String name);
|
||||||
|
|
||||||
Map<String, Object> asMap();
|
Map<String, Object> asMap();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package net.minestom.server.registry;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
|
||||||
|
public interface StaticProtocolObject extends ProtocolObject {
|
||||||
|
|
||||||
|
@Contract(pure = true)
|
||||||
|
int id();
|
||||||
|
}
|
|
@ -2,14 +2,14 @@ package net.minestom.server.sound;
|
||||||
|
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import net.kyori.adventure.sound.Sound;
|
import net.kyori.adventure.sound.Sound;
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface SoundEvent extends ProtocolObject, Sound.Type, SoundEvents permits SoundEventImpl {
|
public sealed interface SoundEvent extends StaticProtocolObject, Sound.Type, SoundEvents permits SoundEventImpl {
|
||||||
|
|
||||||
static @NotNull Collection<@NotNull SoundEvent> values() {
|
static @NotNull Collection<@NotNull SoundEvent> values() {
|
||||||
return SoundEventImpl.values();
|
return SoundEventImpl.values();
|
||||||
|
@ -29,6 +29,6 @@ public sealed interface SoundEvent extends ProtocolObject, Sound.Type, SoundEven
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default @NotNull Key key() {
|
default @NotNull Key key() {
|
||||||
return ProtocolObject.super.key();
|
return StaticProtocolObject.super.key();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
record SoundEventImpl(NamespaceID namespace, int id) implements SoundEvent {
|
record SoundEventImpl(NamespaceID namespace, int id) implements SoundEvent {
|
||||||
private static final Registry.Container<SoundEvent> CONTAINER = Registry.createContainer(Registry.Resource.SOUNDS,
|
private static final Registry.Container<SoundEvent> CONTAINER = Registry.createStaticContainer(Registry.Resource.SOUNDS,
|
||||||
(namespace, properties) -> new SoundEventImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
(namespace, properties) -> new SoundEventImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
||||||
|
|
||||||
static SoundEvent get(@NotNull String namespace) {
|
static SoundEvent get(@NotNull String namespace) {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package net.minestom.server.statistic;
|
package net.minestom.server.statistic;
|
||||||
|
|
||||||
import net.minestom.server.registry.ProtocolObject;
|
import net.minestom.server.registry.StaticProtocolObject;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public sealed interface StatisticType extends ProtocolObject, StatisticTypes permits StatisticTypeImpl {
|
public sealed interface StatisticType extends StaticProtocolObject, StatisticTypes permits StatisticTypeImpl {
|
||||||
|
|
||||||
static @NotNull Collection<@NotNull StatisticType> values() {
|
static @NotNull Collection<@NotNull StatisticType> values() {
|
||||||
return StatisticTypeImpl.values();
|
return StatisticTypeImpl.values();
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
record StatisticTypeImpl(NamespaceID namespace, int id) implements StatisticType {
|
record StatisticTypeImpl(NamespaceID namespace, int id) implements StatisticType {
|
||||||
private static final Registry.Container<StatisticType> CONTAINER = Registry.createContainer(Registry.Resource.STATISTICS,
|
private static final Registry.Container<StatisticType> CONTAINER = Registry.createStaticContainer(Registry.Resource.STATISTICS,
|
||||||
(namespace, properties) -> new StatisticTypeImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
(namespace, properties) -> new StatisticTypeImpl(NamespaceID.from(namespace), properties.getInt("id")));
|
||||||
|
|
||||||
static StatisticType get(@NotNull String namespace) {
|
static StatisticType get(@NotNull String namespace) {
|
||||||
|
|
|
@ -1,206 +1,46 @@
|
||||||
package net.minestom.server.world.biomes;
|
package net.minestom.server.world.biomes;
|
||||||
|
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.registry.ProtocolObject;
|
||||||
|
import net.minestom.server.registry.Registry;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import net.minestom.server.utils.validate.Check;
|
import net.minestom.server.utils.validate.Check;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public final class Biome {
|
sealed public interface Biome extends ProtocolObject permits BiomeImpl {
|
||||||
public static final AtomicInteger ID_COUNTER = new AtomicInteger(0);
|
/**
|
||||||
private static final BiomeEffects DEFAULT_EFFECTS = BiomeEffects.builder()
|
* Returns the entity registry.
|
||||||
.fogColor(0xC0D8FF)
|
*
|
||||||
.skyColor(0x78A7FF)
|
* @return the entity registry or null if it was created with a builder
|
||||||
.waterColor(0x3F76E4)
|
*/
|
||||||
.waterFogColor(0x50533)
|
@Contract(pure = true)
|
||||||
.build();
|
@Nullable Registry.BiomeEntry registry();
|
||||||
|
|
||||||
//A plains biome has to be registered or else minecraft will crash
|
@Override
|
||||||
public static final Biome PLAINS = Biome.builder()
|
@NotNull NamespaceID namespace();
|
||||||
.category(Category.NONE)
|
float depth();
|
||||||
.name(NamespaceID.from("minecraft:plains"))
|
float temperature();
|
||||||
.temperature(0.8F)
|
float scale();
|
||||||
.downfall(0.4F)
|
float downfall();
|
||||||
.depth(0.125F)
|
@NotNull BiomeEffects effects();
|
||||||
.scale(0.05F)
|
@NotNull Precipitation precipitation();
|
||||||
.effects(DEFAULT_EFFECTS)
|
@NotNull TemperatureModifier temperatureModifier();
|
||||||
.build();
|
|
||||||
|
|
||||||
private final int id = ID_COUNTER.getAndIncrement();
|
enum Precipitation {
|
||||||
|
|
||||||
private final NamespaceID name;
|
|
||||||
private final float depth;
|
|
||||||
private final float temperature;
|
|
||||||
private final float scale;
|
|
||||||
private final float downfall;
|
|
||||||
private final Category category;
|
|
||||||
private final BiomeEffects effects;
|
|
||||||
private final Precipitation precipitation;
|
|
||||||
private final TemperatureModifier temperatureModifier;
|
|
||||||
|
|
||||||
Biome(NamespaceID name, float depth, float temperature, float scale, float downfall, Category category, BiomeEffects effects, Precipitation precipitation, TemperatureModifier temperatureModifier) {
|
|
||||||
this.name = name;
|
|
||||||
this.depth = depth;
|
|
||||||
this.temperature = temperature;
|
|
||||||
this.scale = scale;
|
|
||||||
this.downfall = downfall;
|
|
||||||
this.category = category;
|
|
||||||
this.effects = effects;
|
|
||||||
this.precipitation = precipitation;
|
|
||||||
this.temperatureModifier = temperatureModifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Builder builder() {
|
|
||||||
return new Builder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull NBTCompound toNbt() {
|
|
||||||
Check.notNull(name, "The biome namespace cannot be null");
|
|
||||||
Check.notNull(effects, "The biome effects cannot be null");
|
|
||||||
|
|
||||||
return NBT.Compound(nbt -> {
|
|
||||||
nbt.setString("name", name.toString());
|
|
||||||
nbt.setInt("id", id());
|
|
||||||
|
|
||||||
nbt.set("element", NBT.Compound(element -> {
|
|
||||||
element.setFloat("depth", depth);
|
|
||||||
element.setFloat("temperature", temperature);
|
|
||||||
element.setFloat("scale", scale);
|
|
||||||
element.setFloat("downfall", downfall);
|
|
||||||
element.setString("category", category.name().toLowerCase(Locale.ROOT));
|
|
||||||
element.setByte("has_precipitation", (byte) (precipitation == Precipitation.NONE ? 0 : 1));
|
|
||||||
element.setString("precipitation", precipitation.name().toLowerCase(Locale.ROOT));
|
|
||||||
if (temperatureModifier != TemperatureModifier.NONE)
|
|
||||||
element.setString("temperature_modifier", temperatureModifier.name().toLowerCase(Locale.ROOT));
|
|
||||||
element.set("effects", effects.toNbt());
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public int id() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NamespaceID name() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float depth() {
|
|
||||||
return this.depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float temperature() {
|
|
||||||
return this.temperature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float scale() {
|
|
||||||
return this.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float downfall() {
|
|
||||||
return this.downfall;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Category category() {
|
|
||||||
return this.category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BiomeEffects effects() {
|
|
||||||
return this.effects;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Precipitation precipitation() {
|
|
||||||
return this.precipitation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TemperatureModifier temperatureModifier() {
|
|
||||||
return this.temperatureModifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Precipitation {
|
|
||||||
NONE, RAIN, SNOW;
|
NONE, RAIN, SNOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Category {
|
enum TemperatureModifier {
|
||||||
NONE, TAIGA, EXTREME_HILLS, JUNGLE, MESA, PLAINS,
|
|
||||||
SAVANNA, ICY, THE_END, BEACH, FOREST, OCEAN,
|
|
||||||
DESERT, RIVER, SWAMP, MUSHROOM, NETHER, UNDERGROUND,
|
|
||||||
MOUNTAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum TemperatureModifier {
|
|
||||||
NONE, FROZEN;
|
NONE, FROZEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder {
|
interface Setter {
|
||||||
private NamespaceID name;
|
|
||||||
private float depth = 0.2f;
|
|
||||||
private float temperature = 0.25f;
|
|
||||||
private float scale = 0.2f;
|
|
||||||
private float downfall = 0.8f;
|
|
||||||
private Category category = Category.NONE;
|
|
||||||
private BiomeEffects effects = DEFAULT_EFFECTS;
|
|
||||||
private Precipitation precipitation = Precipitation.RAIN;
|
|
||||||
private TemperatureModifier temperatureModifier = TemperatureModifier.NONE;
|
|
||||||
|
|
||||||
Builder() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder name(NamespaceID name) {
|
|
||||||
this.name = name;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder depth(float depth) {
|
|
||||||
this.depth = depth;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder temperature(float temperature) {
|
|
||||||
this.temperature = temperature;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder scale(float scale) {
|
|
||||||
this.scale = scale;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder downfall(float downfall) {
|
|
||||||
this.downfall = downfall;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder category(Category category) {
|
|
||||||
this.category = category;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder effects(BiomeEffects effects) {
|
|
||||||
this.effects = effects;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder precipitation(Precipitation precipitation) {
|
|
||||||
this.precipitation = precipitation;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder temperatureModifier(TemperatureModifier temperatureModifier) {
|
|
||||||
this.temperatureModifier = temperatureModifier;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Biome build() {
|
|
||||||
return new Biome(name, depth, temperature, scale, downfall, category, effects, precipitation, temperatureModifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Setter {
|
|
||||||
void setBiome(int x, int y, int z, @NotNull Biome biome);
|
void setBiome(int x, int y, int z, @NotNull Biome biome);
|
||||||
|
|
||||||
default void setBiome(@NotNull Point blockPosition, @NotNull Biome biome) {
|
default void setBiome(@NotNull Point blockPosition, @NotNull Biome biome) {
|
||||||
|
@ -208,11 +48,103 @@ public final class Biome {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Getter {
|
interface Getter {
|
||||||
@NotNull Biome getBiome(int x, int y, int z);
|
@NotNull Biome getBiome(int x, int y, int z);
|
||||||
|
|
||||||
default @NotNull Biome getBiome(@NotNull Point point) {
|
default @NotNull Biome getBiome(@NotNull Point point) {
|
||||||
return getBiome(point.blockX(), point.blockY(), point.blockZ());
|
return getBiome(point.blockX(), point.blockY(), point.blockZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default @NotNull NBTCompound toNbt() {
|
||||||
|
Check.notNull(name(), "The biome namespace cannot be null");
|
||||||
|
Check.notNull(effects(), "The biome effects cannot be null");
|
||||||
|
|
||||||
|
return NBT.Compound(element -> {
|
||||||
|
element.setFloat("depth", depth());
|
||||||
|
element.setFloat("temperature", temperature());
|
||||||
|
element.setFloat("scale", scale());
|
||||||
|
element.setFloat("downfall", downfall());
|
||||||
|
element.setByte("has_precipitation", (byte) (precipitation() == Precipitation.NONE ? 0 : 1));
|
||||||
|
element.setString("precipitation", precipitation().name().toLowerCase(Locale.ROOT));
|
||||||
|
if (temperatureModifier() != TemperatureModifier.NONE)
|
||||||
|
element.setString("temperature_modifier", temperatureModifier().name().toLowerCase(Locale.ROOT));
|
||||||
|
element.set("effects", effects().toNbt());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static @NotNull Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Builder {
|
||||||
|
private static final BiomeEffects DEFAULT_EFFECTS = BiomeEffects.builder()
|
||||||
|
.fogColor(0xC0D8FF)
|
||||||
|
.skyColor(0x78A7FF)
|
||||||
|
.waterColor(0x3F76E4)
|
||||||
|
.waterFogColor(0x50533)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private NamespaceID name;
|
||||||
|
private float depth = 0.2f;
|
||||||
|
private float temperature = 0.25f;
|
||||||
|
private float scale = 0.2f;
|
||||||
|
private float downfall = 0.8f;
|
||||||
|
private BiomeEffects effects = DEFAULT_EFFECTS;
|
||||||
|
private Precipitation precipitation = Precipitation.RAIN;
|
||||||
|
private TemperatureModifier temperatureModifier = TemperatureModifier.NONE;
|
||||||
|
|
||||||
|
@Contract(value = "_ -> this", pure = true)
|
||||||
|
public @NotNull Builder name(@NotNull NamespaceID name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(value = "_ -> this", pure = true)
|
||||||
|
public @NotNull Builder depth(float depth) {
|
||||||
|
this.depth = depth;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(value = "_ -> this", pure = true)
|
||||||
|
public @NotNull Builder temperature(float temperature) {
|
||||||
|
this.temperature = temperature;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(value = "_ -> this", pure = true)
|
||||||
|
public @NotNull Builder scale(float scale) {
|
||||||
|
this.scale = scale;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(value = "_ -> this", pure = true)
|
||||||
|
public @NotNull Builder downfall(float downfall) {
|
||||||
|
this.downfall = downfall;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(value = "_ -> this", pure = true)
|
||||||
|
public @NotNull Builder effects(@NotNull BiomeEffects effects) {
|
||||||
|
this.effects = effects;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(value = "_ -> this", pure = true)
|
||||||
|
public @NotNull Builder precipitation(@NotNull Biome.Precipitation precipitation) {
|
||||||
|
this.precipitation = precipitation;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(value = "_ -> this", pure = true)
|
||||||
|
public @NotNull Builder temperatureModifier(@NotNull TemperatureModifier temperatureModifier) {
|
||||||
|
this.temperatureModifier = temperatureModifier;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract(pure = true)
|
||||||
|
public @NotNull Biome build() {
|
||||||
|
return new BiomeImpl(name, depth, temperature, scale, downfall, effects, precipitation, temperatureModifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
package net.minestom.server.world.biomes;
|
||||||
|
|
||||||
|
import net.minestom.server.registry.ProtocolObject;
|
||||||
|
import net.minestom.server.registry.Registry;
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
final class BiomeImpl implements ProtocolObject, Biome {
|
||||||
|
// https://minecraft.wiki/w/Rain
|
||||||
|
private final static Double SNOW_TEMPERATURE = 0.15;
|
||||||
|
|
||||||
|
private static final Registry.DynamicContainer<BiomeImpl> CONTAINER = Registry.createDynamicContainer(Registry.Resource.BIOMES,
|
||||||
|
(namespace, properties) -> new BiomeImpl(Registry.biome(namespace, properties)));
|
||||||
|
|
||||||
|
static Collection<BiomeImpl> values() {
|
||||||
|
return CONTAINER.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
static BiomeImpl get(@NotNull String namespace) {
|
||||||
|
return CONTAINER.get(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BiomeImpl getSafe(@NotNull String namespace) {
|
||||||
|
return CONTAINER.getSafe(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final NamespaceID name;
|
||||||
|
private final float depth;
|
||||||
|
private final float temperature;
|
||||||
|
private final float scale;
|
||||||
|
private final float downfall;
|
||||||
|
@NotNull
|
||||||
|
private final BiomeEffects effects;
|
||||||
|
@NotNull
|
||||||
|
private final Precipitation precipitation;
|
||||||
|
@NotNull
|
||||||
|
private final TemperatureModifier temperatureModifier;
|
||||||
|
|
||||||
|
BiomeImpl(NamespaceID name, float depth, float temperature, float scale, float downfall, BiomeEffects effects, Precipitation precipitation, TemperatureModifier temperatureModifier) {
|
||||||
|
this.name = name;
|
||||||
|
this.depth = depth;
|
||||||
|
this.temperature = temperature;
|
||||||
|
this.scale = scale;
|
||||||
|
this.downfall = downfall;
|
||||||
|
this.effects = effects;
|
||||||
|
this.precipitation = precipitation;
|
||||||
|
this.temperatureModifier = temperatureModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
BiomeImpl(Registry.BiomeEntry entry) {
|
||||||
|
this.name = entry.namespace();
|
||||||
|
this.depth = 0.2f;
|
||||||
|
this.scale = 0.2f;
|
||||||
|
this.temperature = entry.temperature();
|
||||||
|
|
||||||
|
BiomeEffects.Builder effectsBuilder = getBuilder(entry);
|
||||||
|
this.effects = effectsBuilder.build();
|
||||||
|
|
||||||
|
this.precipitation = entry.hasPrecipitation()
|
||||||
|
? temperature < SNOW_TEMPERATURE
|
||||||
|
? Biome.Precipitation.SNOW
|
||||||
|
: Biome.Precipitation.RAIN
|
||||||
|
: Biome.Precipitation.NONE;
|
||||||
|
|
||||||
|
this.downfall = entry.downfall();
|
||||||
|
this.temperatureModifier = entry.temperature() < SNOW_TEMPERATURE ? TemperatureModifier.FROZEN : TemperatureModifier.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static BiomeEffects.Builder getBuilder(Registry.BiomeEntry entry) {
|
||||||
|
BiomeEffects.Builder effectsBuilder = BiomeEffects.builder();
|
||||||
|
if (entry.foliageColor() != null) effectsBuilder.foliageColor(entry.foliageColor());
|
||||||
|
if (entry.grassColor() != null) effectsBuilder.grassColor(entry.grassColor());
|
||||||
|
if (entry.skyColor() != null) effectsBuilder.skyColor(entry.skyColor());
|
||||||
|
if (entry.waterColor() != null) effectsBuilder.waterColor(entry.waterColor());
|
||||||
|
if (entry.waterFogColor() != null) effectsBuilder.waterFogColor(entry.waterFogColor());
|
||||||
|
if (entry.fogColor() != null) effectsBuilder.fogColor(entry.fogColor());
|
||||||
|
return effectsBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Registry.BiomeEntry registry() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NamespaceID namespace() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float depth() {
|
||||||
|
return this.depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float temperature() {
|
||||||
|
return this.temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float scale() {
|
||||||
|
return this.scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float downfall() {
|
||||||
|
return this.downfall;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull BiomeEffects effects() {
|
||||||
|
return this.effects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Precipitation precipitation() {
|
||||||
|
return this.precipitation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull TemperatureModifier temperatureModifier() {
|
||||||
|
return this.temperatureModifier;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
package net.minestom.server.world.biomes;
|
package net.minestom.server.world.biomes;
|
||||||
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
import net.minestom.server.utils.validate.Check;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||||
|
@ -9,18 +12,32 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows servers to register custom dimensions. Also used during player joining to send the list of all existing dimensions.
|
* Allows servers to register custom dimensions. Also used during player joining to send the list of all existing dimensions.
|
||||||
* <p>
|
* <p>
|
||||||
* Contains {@link Biome#PLAINS} by default but can be removed.
|
|
||||||
*/
|
*/
|
||||||
public final class BiomeManager {
|
public final class BiomeManager {
|
||||||
private final Map<Integer, Biome> biomes = new ConcurrentHashMap<>();
|
private final Map<Integer, Biome> biomes = new ConcurrentHashMap<>();
|
||||||
|
private final Map<NamespaceID, Biome> biomesByName = new ConcurrentHashMap<>();
|
||||||
|
private final Map<NamespaceID, Integer> idMappings = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private final AtomicInteger ID_COUNTER = new AtomicInteger(0);
|
||||||
|
private NBTCompound nbtCache = null;
|
||||||
|
|
||||||
public BiomeManager() {
|
public BiomeManager() {
|
||||||
addBiome(Biome.PLAINS);
|
// Need to register plains for the client to work properly
|
||||||
|
// Plains is always ID 0
|
||||||
|
addBiome(BiomeImpl.get("minecraft:plains"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadVanillaBiomes() {
|
||||||
|
for (BiomeImpl biome : BiomeImpl.values()) {
|
||||||
|
if (getByName(biome.namespace()) == null)
|
||||||
|
addBiome(biome);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,8 +45,14 @@ public final class BiomeManager {
|
||||||
*
|
*
|
||||||
* @param biome the biome to add
|
* @param biome the biome to add
|
||||||
*/
|
*/
|
||||||
public void addBiome(Biome biome) {
|
public void addBiome(@NotNull Biome biome) {
|
||||||
this.biomes.put(biome.id(), biome);
|
Check.stateCondition(getByName(biome.namespace()) != null, "The biome " + biome.namespace() + " has already been registered");
|
||||||
|
|
||||||
|
var id = ID_COUNTER.getAndIncrement();
|
||||||
|
this.biomes.put(id, biome);
|
||||||
|
this.biomesByName.put(biome.namespace(), biome);
|
||||||
|
this.idMappings.put(biome.namespace(), id);
|
||||||
|
nbtCache = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,8 +60,14 @@ public final class BiomeManager {
|
||||||
*
|
*
|
||||||
* @param biome the biome to remove
|
* @param biome the biome to remove
|
||||||
*/
|
*/
|
||||||
public void removeBiome(Biome biome) {
|
public void removeBiome(@NotNull Biome biome) {
|
||||||
this.biomes.remove(biome.id());
|
var id = idMappings.get(biome.namespace());
|
||||||
|
if (id != null) {
|
||||||
|
biomes.remove(id);
|
||||||
|
biomesByName.remove(biome.namespace());
|
||||||
|
idMappings.remove(biome.namespace());
|
||||||
|
nbtCache = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,24 +85,44 @@ public final class BiomeManager {
|
||||||
* @param id the id of the biome
|
* @param id the id of the biome
|
||||||
* @return the {@link Biome} linked to this id
|
* @return the {@link Biome} linked to this id
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public Biome getById(int id) {
|
public Biome getById(int id) {
|
||||||
return biomes.get(id);
|
return biomes.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Biome getByName(NamespaceID namespaceID) {
|
@Nullable
|
||||||
Biome biome = null;
|
public Biome getByName(@NotNull NamespaceID namespaceID) {
|
||||||
for (final Biome biomeT : biomes.values()) {
|
return biomesByName.get(namespaceID);
|
||||||
if (biomeT.name().equals(namespaceID)) {
|
|
||||||
biome = biomeT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return biome;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTCompound toNBT() {
|
@Nullable
|
||||||
return NBT.Compound(Map.of(
|
public Biome getByName(@NotNull String namespaceID) {
|
||||||
|
NamespaceID namespace = NamespaceID.from(namespaceID);
|
||||||
|
return getByName(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull NBTCompound toNBT() {
|
||||||
|
if (nbtCache != null) return nbtCache;
|
||||||
|
nbtCache = NBT.Compound(Map.of(
|
||||||
"type", NBT.String("minecraft:worldgen/biome"),
|
"type", NBT.String("minecraft:worldgen/biome"),
|
||||||
"value", NBT.List(NBTType.TAG_Compound, biomes.values().stream().map(Biome::toNbt).toList())));
|
"value", NBT.List(NBTType.TAG_Compound, biomes.values().stream().map(biome -> {
|
||||||
|
return NBT.Compound(Map.of(
|
||||||
|
"id", NBT.Int(getId(biome)),
|
||||||
|
"name", NBT.String(biome.namespace().toString()),
|
||||||
|
"element", biome.toNbt()
|
||||||
|
));
|
||||||
|
}).toList())));
|
||||||
|
|
||||||
|
return nbtCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the id of a biome.
|
||||||
|
*`
|
||||||
|
* @param biome
|
||||||
|
* @return the id of the biome, or -1 if the biome is not registered
|
||||||
|
*/
|
||||||
|
public int getId(Biome biome) {
|
||||||
|
return idMappings.getOrDefault(biome.namespace(), -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
package net.minestom.server.world.biomes;
|
||||||
|
|
||||||
|
final public class VanillaBiome implements Biomes {
|
||||||
|
}
|
|
@ -70,13 +70,11 @@ public class AnvilLoaderIntegrationTest {
|
||||||
assertEquals(-4, chunk.getMinSection());
|
assertEquals(-4, chunk.getMinSection());
|
||||||
assertEquals(20, chunk.getMaxSection());
|
assertEquals(20, chunk.getMaxSection());
|
||||||
|
|
||||||
// TODO: skylight
|
|
||||||
// TODO: block light
|
|
||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
Biome b = chunk.getBiome(x, y, z);
|
Biome b = chunk.getBiome(x, y, z);
|
||||||
assertEquals(NamespaceID.from("minecraft:plains"), b.name());
|
assertEquals(NamespaceID.from("minecraft:plains"), b.namespace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package net.minestom.server.instance;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.instance.generator.Generator;
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
import net.minestom.server.world.biomes.Biome;
|
||||||
|
import net.minestom.testing.Env;
|
||||||
|
import net.minestom.testing.EnvTest;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
@EnvTest
|
||||||
|
public class BiomeIntegrationTest {
|
||||||
|
private static Biome PLAINS;
|
||||||
|
private static int PLAINS_ID;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void prepareTest(Env env) {
|
||||||
|
PLAINS = MinecraftServer.getBiomeManager().getByName(NamespaceID.from("minecraft:plains"));
|
||||||
|
PLAINS_ID = MinecraftServer.getBiomeManager().getId(PLAINS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void chunkBiomeSet(Env env) {
|
||||||
|
final int minSection = -1;
|
||||||
|
final int maxSection = 5;
|
||||||
|
final int chunkX = 3;
|
||||||
|
final int chunkZ = -2;
|
||||||
|
final int sectionCount = maxSection - minSection;
|
||||||
|
Section[] sections = new Section[sectionCount];
|
||||||
|
Arrays.setAll(sections, i -> new Section());
|
||||||
|
var chunkUnits = GeneratorImpl.chunk(minSection, maxSection, List.of(sections), chunkX, chunkZ);
|
||||||
|
Generator generator = chunk -> {
|
||||||
|
var modifier = chunk.modifier();
|
||||||
|
modifier.setBiome(48, 0, -32, PLAINS);
|
||||||
|
modifier.setBiome(48 + 8, 0, -32, PLAINS);
|
||||||
|
};
|
||||||
|
generator.generate(chunkUnits);
|
||||||
|
|
||||||
|
assertEquals(PLAINS_ID, sections[0].biomePalette().get(0, 0, 0));
|
||||||
|
assertEquals(0, sections[0].biomePalette().get(1, 0, 0));
|
||||||
|
assertEquals(PLAINS_ID, sections[0].biomePalette().get(2, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void chunkBiomeFill(Env env) {
|
||||||
|
final int minSection = -1;
|
||||||
|
final int maxSection = 5;
|
||||||
|
final int chunkX = 3;
|
||||||
|
final int chunkZ = -2;
|
||||||
|
final int sectionCount = maxSection - minSection;
|
||||||
|
Section[] sections = new Section[sectionCount];
|
||||||
|
Arrays.setAll(sections, i -> new Section());
|
||||||
|
var chunkUnits = GeneratorImpl.chunk(minSection, maxSection, List.of(sections), chunkX, chunkZ);
|
||||||
|
Generator generator = chunk -> {
|
||||||
|
var modifier = chunk.modifier();
|
||||||
|
modifier.fillBiome(PLAINS);
|
||||||
|
};
|
||||||
|
generator.generate(chunkUnits);
|
||||||
|
for (var section : sections) {
|
||||||
|
section.biomePalette().getAll((x, y, z, value) ->
|
||||||
|
assertEquals(PLAINS_ID, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,12 @@
|
||||||
package net.minestom.server.instance;
|
package net.minestom.server.instance;
|
||||||
|
|
||||||
import net.minestom.testing.Env;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.testing.EnvTest;
|
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.instance.generator.GenerationUnit;
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
import net.minestom.server.world.biomes.Biome;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
import net.minestom.testing.Env;
|
||||||
|
import net.minestom.testing.EnvTest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
@ -97,11 +98,13 @@ public class GeneratorForkIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void biome(Env env) {
|
public void biome(Env env) {
|
||||||
var manager = env.process().instance();
|
var manager = env.process().instance();
|
||||||
|
|
||||||
|
var plains = MinecraftServer.getBiomeManager().getByName(NamespaceID.from("minecraft:plains"));
|
||||||
var instance = manager.createInstanceContainer();
|
var instance = manager.createInstanceContainer();
|
||||||
instance.setGenerator(unit -> {
|
instance.setGenerator(unit -> {
|
||||||
var u = unit.fork(unit.absoluteStart(), unit.absoluteEnd().add(16, 0, 16));
|
var u = unit.fork(unit.absoluteStart(), unit.absoluteEnd().add(16, 0, 16));
|
||||||
assertThrows(IllegalStateException.class, () -> u.modifier().setBiome(16, 0, 0, Biome.PLAINS));
|
assertThrows(IllegalStateException.class, () -> u.modifier().setBiome(16, 0, 0, plains));
|
||||||
assertThrows(IllegalStateException.class, () -> u.modifier().fillBiome(Biome.PLAINS));
|
assertThrows(IllegalStateException.class, () -> u.modifier().fillBiome(plains));
|
||||||
});
|
});
|
||||||
instance.loadChunk(0, 0).join();
|
instance.loadChunk(0, 0).join();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,10 @@ import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.instance.generator.GenerationUnit;
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
import net.minestom.server.instance.generator.Generator;
|
import net.minestom.server.instance.generator.Generator;
|
||||||
import net.minestom.server.utils.MathUtils;
|
import net.minestom.server.utils.MathUtils;
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
import net.minestom.server.world.biomes.Biome;
|
import net.minestom.server.world.biomes.Biome;
|
||||||
|
import net.minestom.server.world.biomes.BiomeEffects;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
@ -26,7 +28,6 @@ import static net.minestom.server.utils.chunk.ChunkUtils.floorSection;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
public class GeneratorTest {
|
public class GeneratorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unitSize() {
|
public void unitSize() {
|
||||||
assertDoesNotThrow(() -> dummyUnit(Vec.ZERO, new Vec(16)));
|
assertDoesNotThrow(() -> dummyUnit(Vec.ZERO, new Vec(16)));
|
||||||
|
@ -241,48 +242,6 @@ public class GeneratorTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void chunkBiomeSet() {
|
|
||||||
final int minSection = -1;
|
|
||||||
final int maxSection = 5;
|
|
||||||
final int chunkX = 3;
|
|
||||||
final int chunkZ = -2;
|
|
||||||
final int sectionCount = maxSection - minSection;
|
|
||||||
Section[] sections = new Section[sectionCount];
|
|
||||||
Arrays.setAll(sections, i -> new Section());
|
|
||||||
var chunkUnits = GeneratorImpl.chunk(minSection, maxSection, List.of(sections), chunkX, chunkZ);
|
|
||||||
Generator generator = chunk -> {
|
|
||||||
var modifier = chunk.modifier();
|
|
||||||
modifier.setBiome(48, 0, -32, Biome.PLAINS);
|
|
||||||
modifier.setBiome(48 + 8, 0, -32, Biome.PLAINS);
|
|
||||||
};
|
|
||||||
generator.generate(chunkUnits);
|
|
||||||
assertEquals(Biome.PLAINS.id(), sections[0].biomePalette().get(0, 0, 0));
|
|
||||||
assertEquals(0, sections[0].biomePalette().get(1, 0, 0));
|
|
||||||
assertEquals(Biome.PLAINS.id(), sections[0].biomePalette().get(2, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void chunkBiomeFill() {
|
|
||||||
final int minSection = -1;
|
|
||||||
final int maxSection = 5;
|
|
||||||
final int chunkX = 3;
|
|
||||||
final int chunkZ = -2;
|
|
||||||
final int sectionCount = maxSection - minSection;
|
|
||||||
Section[] sections = new Section[sectionCount];
|
|
||||||
Arrays.setAll(sections, i -> new Section());
|
|
||||||
var chunkUnits = GeneratorImpl.chunk(minSection, maxSection, List.of(sections), chunkX, chunkZ);
|
|
||||||
Generator generator = chunk -> {
|
|
||||||
var modifier = chunk.modifier();
|
|
||||||
modifier.fillBiome(Biome.PLAINS);
|
|
||||||
};
|
|
||||||
generator.generate(chunkUnits);
|
|
||||||
for (var section : sections) {
|
|
||||||
section.biomePalette().getAll((x, y, z, value) ->
|
|
||||||
assertEquals(Biome.PLAINS.id(), value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void chunkFillHeightExact() {
|
public void chunkFillHeightExact() {
|
||||||
final int minSection = -1;
|
final int minSection = -1;
|
||||||
|
|
Loading…
Reference in New Issue