Skip to content

Efnilite/neoschematic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NeoSchematic

Source · SpigotMC · by Efnilite

Features

  • Much easier and smaller than WorldEdit
  • Schematics are stored in JSON: allows for easy editing and reading
  • Storage size scales linearly with the amount of blocks: 1 million blocks ~= 1 MB

Todo

  • Add version migrations
  • Add support for entities
  • Add support for rotations

Including in your project

Maven

<repositories>
    <repository>
        <id>jitpack</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.github.Efnilite</groupId>
        <artifactId>neoschematic</artifactId>
        <version>v1.1.0</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

<build>
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.3.0</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <relocations>
                <relocation>
                    <pattern>dev.efnilite.neoschematic</pattern>
                    <!-- Replace 'com.yourpackage' with the package of your plugin ! -->
                    <shadedPattern>com.yourpackage.neoschematic</shadedPattern>
                </relocation>
            </relocations>
        </configuration>
    </plugin>
</plugins>
</build>

Gradle

plugins {
    id 'com.github.johnrengelman.shadow' version '8.1.1'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.github.Efnilite:neoschematic:v1.1.0'
}

shadowJar {
    // Replace 'com.yourpackage' with the package of your plugin 
    relocate 'dev.efnilite.neoschematic', 'com.yourpackage.neoschematic'
}

Manual

Copy the files into your project.

Usage

Create and save a schematic

Schematic schematic = Schematic.create(pos1, pos2);
boolean success = schematic.save("plugins/schematic.json");

Create and save a schematic asynchronously (Recommended)

Schematic.createAsync(pos1, pos2, plugin).thenAccept(schematic -> 
    schematic.saveAsync("plugins/schematic.json", plugin)
);

Paste existing schematic

Schematic schematic = Schematic.load("plugins/schematic.json");
List<Block> blocks = schematic.paste(location, true);

Load existing schematic asynchronously and paste (Recommended)

Schematic.loadAsync("plugins/schematic.json", plugin).thenAccept(schematic -> {
    Bukkit.getScheduler().runTask(plugin, () -> schematic.paste(location, true));
});

Example plugin

package dev.efnilite.neoschematic;

import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.List;

public class ExamplePlugin extends JavaPlugin implements CommandExecutor {

    @Override
    public void onEnable() {
        getCommand("example").setExecutor(this);
    }

    @Override
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, 
                             @NotNull String label, String[] args) {
        if (args.length == 0 || !(sender instanceof Player player)) return true;

        switch (args[0]) {
            case "save" -> {
                var coords1 = Arrays.stream(args[1].split(",")).mapToInt(Integer::parseInt).toArray();
                var coords2 = Arrays.stream(args[2].split(",")).mapToInt(Integer::parseInt).toArray();

                var pos1 = new Location(player.getWorld(), coords1[0], coords1[1], coords1[2]);
                var pos2 = new Location(player.getWorld(), coords2[0], coords2[1], coords2[2]);

                sender.sendMessage("Getting blocks...");

                Schematic.createAsync(pos1, pos2, this).thenAccept(schematic -> {
                    sender.sendMessage("Saving file...");

                    schematic.saveAsync("plugins/schematic.json", this).thenRun(() -> {
                        sender.sendMessage("Schematic saved as schematic.json");
                    });
                });
            }

            case "paste" -> {
                sender.sendMessage("Loading file...");

                Schematic.loadAsync("plugins/schematic.json", this).thenAccept(schematic -> {
                    if (schematic == null) {
                        player.sendMessage("Schematic not found.");
                        return;
                    }

                    sender.sendMessage("Pasting blocks...");

                    getServer().getScheduler().runTask(this, () -> {
                        List<Block> blocks = schematic.paste(player.getLocation(), true);
                        player.sendMessage("Pasted %s blocks".formatted(blocks.size()));
                    });
                });
            }
        }

        return true;
    }
}