mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-05 18:27:17 +01:00
SPIGOT-2903: Add Structure API
By: Sander Knauff <sanderknauff@hotmail.com>
This commit is contained in:
parent
2d0a775210
commit
188d3b23d0
7 changed files with 436 additions and 0 deletions
|
@ -1,5 +1,16 @@
|
|||
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructure.java
|
||||
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructure.java
|
||||
@@ -64,8 +64,8 @@
|
||||
public static final String ENTITY_TAG_NBT = "nbt";
|
||||
public static final String SIZE_TAG = "size";
|
||||
static final int CHUNK_SIZE = 16;
|
||||
- private final List<DefinedStructure.a> palettes = Lists.newArrayList();
|
||||
- private final List<DefinedStructure.EntityInfo> entityInfoList = Lists.newArrayList();
|
||||
+ public final List<DefinedStructure.a> palettes = Lists.newArrayList(); // PAIL private->public
|
||||
+ public final List<DefinedStructure.EntityInfo> entityInfoList = Lists.newArrayList(); // PAIL private->public
|
||||
private BaseBlockPosition size;
|
||||
private String author;
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructureInfo.java
|
||||
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructureInfo.java
|
||||
@@ -24,7 +24,7 @@
|
||||
@Nullable
|
||||
private Random random;
|
||||
@Nullable
|
||||
- private int palette;
|
||||
+ public int palette = -1; // CraftBukkit - Set initial value so we know if the palette has been set forcefully
|
||||
private final List<DefinedStructureProcessor> processors;
|
||||
private boolean knownShape;
|
||||
private boolean finalizeEntities;
|
||||
@@ -151,6 +151,13 @@
|
||||
|
||||
if (i == 0) {
|
||||
throw new IllegalStateException("No palettes");
|
||||
+ // CraftBukkit start
|
||||
+ } else if (this.palette > 0) {
|
||||
+ if (this.palette >= i) {
|
||||
+ throw new IllegalArgumentException("Palette index out of bounds. Got " + this.palette + " where there are only " + i + " palettes available.");
|
||||
+ }
|
||||
+ return list.get(this.palette);
|
||||
+ // CraftBukkit end
|
||||
} else {
|
||||
return (DefinedStructure.a) list.get(this.b(blockposition).nextInt(i));
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructureManager.java
|
||||
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructureManager.java
|
||||
@@ -34,7 +34,7 @@
|
||||
private static final String STRUCTURE_DIRECTORY_NAME = "structures";
|
||||
private static final String STRUCTURE_FILE_EXTENSION = ".nbt";
|
||||
private static final String STRUCTURE_TEXT_FILE_EXTENSION = ".snbt";
|
||||
- private final Map<MinecraftKey, Optional<DefinedStructure>> structureRepository = Maps.newConcurrentMap();
|
||||
+ public final Map<MinecraftKey, Optional<DefinedStructure>> structureRepository = Maps.newConcurrentMap(); // PAIL private->public
|
||||
private final DataFixer fixerUpper;
|
||||
private IResourceManager resourceManager;
|
||||
private final Path generatedDir;
|
||||
@@ -71,7 +71,7 @@
|
||||
this.structureRepository.clear();
|
||||
}
|
||||
|
||||
- private Optional<DefinedStructure> e(MinecraftKey minecraftkey) {
|
||||
+ public Optional<DefinedStructure> e(MinecraftKey minecraftkey) { // PAIL private->public
|
||||
MinecraftKey minecraftkey1 = new MinecraftKey(minecraftkey.getNamespace(), "structures/" + minecraftkey.getKey() + ".nbt");
|
||||
|
||||
try {
|
||||
@@ -106,7 +106,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private Optional<DefinedStructure> f(MinecraftKey minecraftkey) {
|
||||
+ public Optional<DefinedStructure> f(MinecraftKey minecraftkey) { // PAIL private->public
|
||||
if (!this.generatedDir.toFile().isDirectory()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
@@ -140,7 +140,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private DefinedStructure a(InputStream inputstream) throws IOException {
|
||||
+ public DefinedStructure a(InputStream inputstream) throws IOException { //PAIL rename loadFromStream; private -> public
|
||||
NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a(inputstream);
|
||||
|
||||
return this.a(nbttagcompound);
|
||||
@@ -214,7 +214,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private Path b(MinecraftKey minecraftkey, String s) {
|
||||
+ public Path b(MinecraftKey minecraftkey, String s) { //PAIL private->public
|
||||
if (minecraftkey.getKey().contains("//")) {
|
||||
throw new ResourceKeyInvalidException("Invalid resource path: " + minecraftkey);
|
||||
} else {
|
|
@ -183,6 +183,7 @@ import org.bukkit.craftbukkit.metadata.WorldMetadataStore;
|
|||
import org.bukkit.craftbukkit.potion.CraftPotionBrewer;
|
||||
import org.bukkit.craftbukkit.scheduler.CraftScheduler;
|
||||
import org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager;
|
||||
import org.bukkit.craftbukkit.structure.CraftStructureManager;
|
||||
import org.bukkit.craftbukkit.tag.CraftBlockTag;
|
||||
import org.bukkit.craftbukkit.tag.CraftEntityTag;
|
||||
import org.bukkit.craftbukkit.tag.CraftFluidTag;
|
||||
|
@ -238,6 +239,7 @@ import org.bukkit.plugin.messaging.StandardMessenger;
|
|||
import org.bukkit.potion.Potion;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitWorker;
|
||||
import org.bukkit.structure.StructureManager;
|
||||
import org.bukkit.util.StringUtil;
|
||||
import org.bukkit.util.permissions.DefaultPermissions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
@ -255,6 +257,7 @@ public final class CraftServer implements Server {
|
|||
private final SimpleHelpMap helpMap = new SimpleHelpMap(this);
|
||||
private final StandardMessenger messenger = new StandardMessenger();
|
||||
private final SimplePluginManager pluginManager = new SimplePluginManager(this, commandMap);
|
||||
private final StructureManager structureManager;
|
||||
protected final DedicatedServer console;
|
||||
protected final DedicatedPlayerList playerList;
|
||||
private final Map<String, World> worlds = new LinkedHashMap<String, World>();
|
||||
|
@ -298,6 +301,7 @@ public final class CraftServer implements Server {
|
|||
}
|
||||
}));
|
||||
this.serverVersion = CraftServer.class.getPackage().getImplementationVersion();
|
||||
this.structureManager = new CraftStructureManager(console.getDefinedStructureManager());
|
||||
|
||||
Bukkit.setServer(this);
|
||||
|
||||
|
@ -2199,6 +2203,11 @@ public final class CraftServer implements Server {
|
|||
return new ArrayList<>(Lists.transform(nms, (entity) -> entity.getBukkitEntity()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureManager getStructureManager() {
|
||||
return structureManager;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public UnsafeValues getUnsafe() {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package org.bukkit.craftbukkit.structure;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.DefinedStructure;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockStates;
|
||||
import org.bukkit.structure.Palette;
|
||||
|
||||
public class CraftPalette implements Palette {
|
||||
|
||||
private final DefinedStructure.a palette;
|
||||
|
||||
public CraftPalette(DefinedStructure.a palette) {
|
||||
this.palette = palette;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockState> getBlocks() {
|
||||
List<BlockState> blocks = new ArrayList<>();
|
||||
for (DefinedStructure.BlockInfo blockInfo : palette.a()) {
|
||||
blocks.add(CraftBlockStates.getBlockState(blockInfo.pos, blockInfo.state, blockInfo.nbt));
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockCount() {
|
||||
return palette.a().size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package org.bukkit.craftbukkit.structure;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.level.block.EnumBlockMirror;
|
||||
import net.minecraft.world.level.block.EnumBlockRotation;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.DefinedStructure;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.DefinedStructureInfo;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.DefinedStructureProcessorRotation;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.RegionAccessor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.structure.Mirror;
|
||||
import org.bukkit.block.structure.StructureRotation;
|
||||
import org.bukkit.craftbukkit.CraftRegionAccessor;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.structure.Palette;
|
||||
import org.bukkit.structure.Structure;
|
||||
import org.bukkit.util.BlockVector;
|
||||
|
||||
public class CraftStructure implements Structure {
|
||||
|
||||
private final DefinedStructure structure;
|
||||
|
||||
public CraftStructure(DefinedStructure structure) {
|
||||
this.structure = structure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void place(Location location, boolean includeEntities, StructureRotation structureRotation, Mirror mirror, int palette, float integrity, Random random) {
|
||||
location.checkFinite();
|
||||
World world = location.getWorld();
|
||||
Validate.notNull(world, "location#getWorld() cannot be null");
|
||||
|
||||
BlockVector blockVector = new BlockVector(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
place(world, blockVector, includeEntities, structureRotation, mirror, palette, integrity, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void place(RegionAccessor regionAccessor, BlockVector location, boolean includeEntities, StructureRotation structureRotation, Mirror mirror, int palette, float integrity, Random random) {
|
||||
Validate.notNull(regionAccessor, "regionAccessor can not be null");
|
||||
location.checkFinite();
|
||||
|
||||
if (integrity < 0F || integrity > 1F) {
|
||||
throw new IllegalArgumentException("Integrity must be between 0 and 1 inclusive. Was \"" + integrity + "\"");
|
||||
}
|
||||
|
||||
DefinedStructureInfo definedstructureinfo = new DefinedStructureInfo()
|
||||
.a(EnumBlockMirror.valueOf(mirror.name())) // PAIL rename setMirror
|
||||
.a(EnumBlockRotation.valueOf(structureRotation.name())) // PAIL rename setRotation
|
||||
.a(!includeEntities) // PAIL rename setIgnoreEntities
|
||||
.a(new DefinedStructureProcessorRotation(integrity)) // PAIL rename addStructureProcessor
|
||||
.a(random); // PAIL rename setRandom
|
||||
definedstructureinfo.palette = palette;
|
||||
|
||||
BlockPosition blockPosition = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
structure.a(((CraftRegionAccessor) regionAccessor).getHandle(), blockPosition, blockPosition, definedstructureinfo, random, 2); // PAIL rename placeInWorld
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(Location corner1, Location corner2, boolean includeEntities) {
|
||||
Validate.notNull(corner1, "corner1 cannot be null");
|
||||
Validate.notNull(corner2, "corner2 cannot be null");
|
||||
World world = corner1.getWorld();
|
||||
Validate.notNull(world, "corner1#getWorld() cannot be null");
|
||||
|
||||
Location origin = new Location(world, Math.min(corner1.getBlockX(), corner2.getBlockX()), Math.min(corner1.getBlockY(), corner2.getBlockY()), Math.min(corner1.getBlockZ(), corner2.getBlockZ()));
|
||||
BlockVector size = new BlockVector(Math.abs(corner1.getBlockX() - corner2.getBlockX()), Math.abs(corner1.getBlockY() - corner2.getBlockY()), Math.abs(corner1.getBlockZ() - corner2.getBlockZ()));
|
||||
fill(origin, size, includeEntities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(Location origin, BlockVector size, boolean includeEntities) {
|
||||
Validate.notNull(origin, "origin cannot be null");
|
||||
World world = origin.getWorld();
|
||||
Validate.notNull(world, "origin#getWorld() cannot be null");
|
||||
Validate.notNull(size, "size cannot be null");
|
||||
if (size.getBlockX() < 1 || size.getBlockY() < 1 || size.getBlockZ() < 1) {
|
||||
throw new IllegalArgumentException("Size must be at least 1x1x1 but was " + size.getBlockX() + "x" + size.getBlockY() + "x" + size.getBlockZ());
|
||||
}
|
||||
|
||||
structure.a(((CraftWorld) world).getHandle(), new BlockPosition(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ()), new BlockPosition(size.getBlockX(), size.getBlockY(), size.getBlockZ()), includeEntities, null); // PAIL rename fillFromWorld
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector getSize() {
|
||||
return new BlockVector(structure.a().getX(), structure.a().getY(), structure.a().getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> getEntities() {
|
||||
List<Entity> entities = new ArrayList<>();
|
||||
for (DefinedStructure.EntityInfo entity : structure.entityInfoList) {
|
||||
EntityTypes.a(entity.nbt, ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle()).ifPresent(dummyEntity -> {
|
||||
dummyEntity.setPosition(entity.pos.x, entity.pos.y, entity.pos.z);
|
||||
entities.add(dummyEntity.getBukkitEntity());
|
||||
});
|
||||
}
|
||||
return Collections.unmodifiableList(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEntityCount() {
|
||||
return structure.entityInfoList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Palette> getPalettes() {
|
||||
return structure.palettes.stream().map(CraftPalette::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPaletteCount() {
|
||||
return structure.palettes.size();
|
||||
}
|
||||
|
||||
public DefinedStructure getHandle() {
|
||||
return structure;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
package org.bukkit.craftbukkit.structure;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.nbt.NBTCompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.resources.MinecraftKey;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.DefinedStructure;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.DefinedStructureManager;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.bukkit.structure.Structure;
|
||||
import org.bukkit.structure.StructureManager;
|
||||
|
||||
public class CraftStructureManager implements StructureManager {
|
||||
|
||||
private final DefinedStructureManager structureManager;
|
||||
|
||||
public CraftStructureManager(DefinedStructureManager structureManager) {
|
||||
this.structureManager = structureManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<NamespacedKey, Structure> getStructures() {
|
||||
Map<NamespacedKey, Structure> cachedStructures = new HashMap<>();
|
||||
for (Map.Entry<MinecraftKey, Optional<DefinedStructure>> entry : structureManager.structureRepository.entrySet()) {
|
||||
entry.getValue().ifPresent(definedStructure -> {
|
||||
cachedStructures.put(CraftNamespacedKey.fromMinecraft(entry.getKey()), new CraftStructure(definedStructure));
|
||||
});
|
||||
}
|
||||
return Collections.unmodifiableMap(cachedStructures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure getStructure(NamespacedKey structureKey) {
|
||||
Validate.notNull(structureKey, "structureKey cannot be null");
|
||||
|
||||
final Optional<DefinedStructure> definedStructure = structureManager.structureRepository.get(CraftNamespacedKey.toMinecraft(structureKey));
|
||||
if (definedStructure == null) {
|
||||
return null;
|
||||
}
|
||||
return definedStructure.map(CraftStructure::new).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure loadStructure(NamespacedKey structureKey, boolean register) {
|
||||
MinecraftKey minecraftKey = createAndValidateMinecraftStructureKey(structureKey);
|
||||
|
||||
Optional<DefinedStructure> structure = structureManager.structureRepository.get(minecraftKey);
|
||||
structure = structure == null ? Optional.empty() : structure;
|
||||
structure = structure.isPresent() ? structure : structureManager.f(minecraftKey);
|
||||
structure = structure.isPresent() ? structure : structureManager.e(minecraftKey);
|
||||
|
||||
if (register) {
|
||||
structureManager.structureRepository.put(minecraftKey, structure);
|
||||
}
|
||||
|
||||
return structure.map(CraftStructure::new).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure loadStructure(NamespacedKey structureKey) {
|
||||
return loadStructure(structureKey, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveStructure(NamespacedKey structureKey) {
|
||||
MinecraftKey minecraftKey = createAndValidateMinecraftStructureKey(structureKey);
|
||||
|
||||
structureManager.c(minecraftKey); // PAIL rename save
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveStructure(NamespacedKey structureKey, Structure structure) throws IOException {
|
||||
Validate.notNull(structure, "structure cannot be null");
|
||||
|
||||
File structureFile = getStructureFile(structureKey);
|
||||
Files.createDirectories(structureFile.toPath().getParent());
|
||||
saveStructure(structureFile, structure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure registerStructure(NamespacedKey structureKey, Structure structure) {
|
||||
Validate.notNull(structure, "structure cannot be null");
|
||||
MinecraftKey minecraftKey = createAndValidateMinecraftStructureKey(structureKey);
|
||||
|
||||
final Optional<DefinedStructure> optionalDefinedStructure = Optional.of(((CraftStructure) structure).getHandle());
|
||||
final Optional<DefinedStructure> previousStructure = structureManager.structureRepository.put(minecraftKey, optionalDefinedStructure);
|
||||
return previousStructure == null ? null : previousStructure.map(CraftStructure::new).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure unregisterStructure(NamespacedKey structureKey) {
|
||||
MinecraftKey minecraftKey = createAndValidateMinecraftStructureKey(structureKey);
|
||||
|
||||
final Optional<DefinedStructure> previousStructure = structureManager.structureRepository.remove(minecraftKey);
|
||||
return previousStructure == null ? null : previousStructure.map(CraftStructure::new).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteStructure(NamespacedKey structureKey) throws IOException {
|
||||
deleteStructure(structureKey, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteStructure(NamespacedKey structureKey, boolean unregister) throws IOException {
|
||||
MinecraftKey key = CraftNamespacedKey.toMinecraft(structureKey);
|
||||
|
||||
if (unregister) {
|
||||
structureManager.structureRepository.remove(key);
|
||||
}
|
||||
Path path = structureManager.b(key, ".nbt");
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getStructureFile(NamespacedKey structureKey) {
|
||||
MinecraftKey minecraftKey = createAndValidateMinecraftStructureKey(structureKey);
|
||||
return structureManager.b(minecraftKey, ".nbt").toFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure loadStructure(File file) throws IOException {
|
||||
Validate.notNull(file, "file cannot be null");
|
||||
|
||||
FileInputStream fileinputstream = new FileInputStream(file);
|
||||
return loadStructure(fileinputstream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure loadStructure(InputStream inputStream) throws IOException {
|
||||
Validate.notNull(inputStream, "inputStream cannot be null");
|
||||
|
||||
return new CraftStructure(structureManager.a(inputStream));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveStructure(File file, Structure structure) throws IOException {
|
||||
Validate.notNull(file, "file cannot be null");
|
||||
Validate.notNull(structure, "structure cannot be null");
|
||||
|
||||
FileOutputStream fileoutputstream = new FileOutputStream(file);
|
||||
saveStructure(fileoutputstream, structure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveStructure(OutputStream outputStream, Structure structure) throws IOException {
|
||||
Validate.notNull(outputStream, "outputStream cannot be null");
|
||||
Validate.notNull(structure, "structure cannot be null");
|
||||
|
||||
NBTTagCompound nbttagcompound = ((CraftStructure) structure).getHandle().a(new NBTTagCompound());
|
||||
NBTCompressedStreamTools.a(nbttagcompound, outputStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure createStructure() {
|
||||
return new CraftStructure(new DefinedStructure());
|
||||
}
|
||||
|
||||
private MinecraftKey createAndValidateMinecraftStructureKey(NamespacedKey structureKey) {
|
||||
Validate.notNull(structureKey, "structureKey cannot be null");
|
||||
|
||||
MinecraftKey minecraftkey = CraftNamespacedKey.toMinecraft(structureKey);
|
||||
if (minecraftkey.getKey().contains("//")) {
|
||||
throw new IllegalArgumentException("Resource key for Structures can not contain \"//\"");
|
||||
}
|
||||
return minecraftkey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure copy(Structure structure) {
|
||||
return new CraftStructure(structureManager.a(((CraftStructure) structure).getHandle().a(new NBTTagCompound())));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue