| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- package me.lethunderhawk.dungeon.placement;
- import com.google.gson.Gson;
- import com.google.gson.JsonParseException;
- import com.sk89q.worldedit.EditSession;
- import com.sk89q.worldedit.WorldEdit;
- import com.sk89q.worldedit.extent.clipboard.Clipboard;
- import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
- import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
- import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
- import com.sk89q.worldedit.function.operation.Operation;
- import com.sk89q.worldedit.function.operation.Operations;
- import com.sk89q.worldedit.math.BlockVector3;
- import com.sk89q.worldedit.session.ClipboardHolder;
- import com.sk89q.worldedit.bukkit.BukkitAdapter;
- import me.lethunderhawk.world.util.schematic.Rotation;
- import me.lethunderhawk.world.util.schematic.Vector3i;
- import org.bukkit.Location;
- import org.bukkit.World;
- import org.bukkit.util.BoundingBox;
- import java.io.File;
- import java.io.FileReader;
- import java.io.IOException;
- public final class SchematicRoomPlacer {
- private static final Gson GSON = new Gson();
- private SchematicRoomPlacer() {}
- /**
- * Places a room schematic at a given anchor.
- *
- * @param schematicFile .schem file
- * @param world Bukkit world
- * @param anchor anchor location (world-space origin)
- * @param rotation rotation (NONE, CLOCKWISE_90, CLOCKWISE_180, CLOCKWISE_270)
- * @return true if successfully validated and placed
- */
- public static boolean placeRoom(
- File schematicFile,
- World world,
- Location anchor,
- Rotation rotation
- ) {
- if(schematicFile == null) return false;
- if (!schematicFile.exists()) return false;
- RoomMetadata meta = loadMetadata(schematicFile);
- if (meta == null) return false;
- Clipboard clipboard = loadClipboard(schematicFile);
- if (clipboard == null) return false;
- BoundingBox box = meta.boundingBox.rotated(rotation).shift(anchor.toVector());
- //if (!isAreaClear(world, box)) return false;
- return pasteClipboard(clipboard, world, anchor, meta.anchor, rotation);
- }
- // ---------- Internal ----------
- private static Clipboard loadClipboard(File file) {
- ClipboardFormat format = ClipboardFormats.findByPath(file.getAbsoluteFile().toPath());
- if (format == null) return null;
- try (ClipboardReader reader = format.getReader(new java.io.FileInputStream(file))) {
- return reader.read();
- } catch (IOException e) {
- return null;
- }
- }
- private static RoomMetadata loadMetadata(File schematic) {
- File metaFile = new File(schematic.getParent(), schematic.getName().replace(".schem", ".json"));
- if (!metaFile.exists()) return null;
- try (FileReader reader = new FileReader(metaFile)) {
- return GSON.fromJson(reader, RoomMetadata.class);
- } catch (IOException | JsonParseException e) {
- return null;
- }
- }
- private static boolean isAreaClear(World world, BoundingBox box) {
- int minX = (int) box.getMinX();
- int minY = (int) box.getMinY();
- int minZ = (int) box.getMinZ();
- int maxX = (int) box.getMaxX();
- int maxY = (int) box.getMaxY();
- int maxZ = (int) box.getMaxZ();
- for (int x = minX; x <= maxX; x++) {
- for (int y = minY; y <= maxY; y++) {
- for (int z = minZ; z <= maxZ; z++) {
- if (!world.getBlockAt(x, y, z).isEmpty()) {
- return false;
- }
- }
- }
- }
- return true;
- }
- private static boolean pasteClipboard(
- Clipboard clipboard,
- World world,
- Location anchor,
- Vector3i schematicAnchor,
- Rotation rotation
- ) {
- com.sk89q.worldedit.world.World weWorld = BukkitAdapter.adapt(world);
- BlockVector3 pastePos = BlockVector3.at(
- anchor.getBlockX() - schematicAnchor.x(),
- anchor.getBlockY() - schematicAnchor.y(),
- anchor.getBlockZ() - schematicAnchor.z()
- );
- try (EditSession session = WorldEdit.getInstance()
- .newEditSessionBuilder()
- .world(weWorld)
- .build()) {
- ClipboardHolder holder = new ClipboardHolder(clipboard);
- holder.setTransform(holder.getTransform().combine(rotation.toTransform()));
- Operation op = holder
- .createPaste(session)
- .to(pastePos)
- .ignoreAirBlocks(true)
- .build();
- Operations.complete(op);
- session.close();
- return true;
- } catch (Exception e) {
- return false;
- }
- }
- }
|