[1.9] Pasting WorldEdit Schematic

Discussion in 'Spigot Plugin Development' started by tokyojack, May 19, 2016.

  1. Hey everyone!

    I'm wondering how you use the WorldEdit API to paste schematic. I've Googled a bunch of stuff, but all of it either doesn't work or is out dated. I intend to reset the map with pasting a schematic every so often.You can also help out with that, give me a direction on what I should do for it. <3.

    Cheers,
    Jack!
     
  2. I've a class for you !
    <3

    Code (Text):
    package fr.kwizzy.waroflegions.shelter.shelter;


    import com.sk89q.worldedit.CuboidClipboard;
    import com.sk89q.worldedit.MaxChangedBlocksException;
    import com.sk89q.worldedit.blocks.BaseBlock;
    import com.sk89q.worldedit.world.DataException;
    import fr.kwizzy.waroflegions.shelter.main.Shelter;
    import fr.waroflegions.api.utils.ReflectionUtils;
    import fr.waroflegions.api.utils.Utils;
    import org.bukkit.Effect;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Player;
    import org.bukkit.scheduler.BukkitRunnable;
    import java.io.File;
    import java.io.IOException;
    import java.util.LinkedHashMap;
    import java.util.Map;


    /**
    * Par Alexis le 21/04/2016.
    */
    @SuppressWarnings("deprecated")
    public class SchematicBuild
    {
        private ShelterType              s;
        private Location                 location;
        private Player                   p;
        private double                   blockpertick = 10;
        private double                   time         =  5;
        private Map<Location, BaseBlock> x            = new LinkedHashMap<Location, BaseBlock>();

        public SchematicBuild(ShelterType s, Player p, int blockpertick)
        {
            this.s = s;
            this.p = p;
            this.blockpertick = blockpertick;
            this.location = p.getLocation();
        }

        public void buildShematic(){

            build();

        }

        /**
         * Create the schematic
         * @param file File where is the .schem
         * @param origin Origin, the location where is paste the schematic (East - south --)
         * @throws DataException
         * @throws IOException
         * @throws MaxChangedBlocksException
         */
        public void getSchematicBlocks(final File file, Location origin)
                throws DataException, IOException, MaxChangedBlocksException
        {
            final CuboidClipboard cuboidClip = CuboidClipboard.loadSchematic(file);
            final Map<Location, BaseBlock> blocks = new LinkedHashMap<Location, BaseBlock>();
            try {
                final BaseBlock[][][] data = (BaseBlock[][][]) ReflectionUtils.getValue(cuboidClip, true, "data");
                for (int y = 0; y < cuboidClip.getHeight(); ++y) {
                    for (int x = 0; x < cuboidClip.getWidth(); ++x) {
                        for (int z = 0; z < cuboidClip.getLength(); ++z) {
                            final BaseBlock baseBlock = data[x][y][z];

                            if(baseBlock.getId() != Material.AIR.getId()) {
                                blocks.put(new Location(origin.getWorld(),
                                                       (double) x,
                                                       (double) y,
                                                       (double) z).add(origin), baseBlock);
                            }
                        }
                    }
                }
            }
            catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
                e.printStackTrace();
            }
            x =  blocks;
        }

        /**
         * Build the schematic with number
         * of block by time
         */
        public void build()
        {
            /**
             * Init the map where is store the datas of the schem
             */
            try {
                getSchematicBlocks(s.getSchemFile(), location);
            } catch (DataException | IOException | MaxChangedBlocksException  e) {
                e.printStackTrace();
                return;
            }

            if(x.isEmpty())
                return;

            new BukkitRunnable()
            {
                /**
                 * Count verification with size of the map
                 */
                int count = 0;
                @Override
                public void run()
                {
                    int i= 0;
                    for (Map.Entry<Location, BaseBlock> entry : x.entrySet()) {
                        /**
                         * Condition for more than 1 block per time
                         */
                        if (i <= count + blockpertick && i >= count - blockpertick) {
                            if(i> x.size())
                                break;

                            Location key = entry.getKey();
                            BaseBlock value = entry.getValue();

                            Material mat = giveMaterialById(value.getId());
                            byte dat = (byte) value.getData();
                            Block block = key.getBlock();
                            block.setType(mat);

                            if (dat != 0) {
                                block.setData(dat);
                            }

                            particle(block, block.getType());
                        }
                        i++;
                    }
                    count += blockpertick;

                    /**
                     * Count is > or = to size it's the end, schem is done
                     */
                    if (count >= x.size()) {
                        if(count > x.size())
                            count = x.size();
                        renaming(count, x.size());
                        this.cancel();
                    }

                    /**
                     * random send of a action bar for the percentage
                     */
                    if(Utils.randomInteger(0, 200) >= 50 && !(x.size() - count <=15)) {
                        renaming(count, x.size());
                    }
                }
            }.runTaskTimer(Shelter.getInstance(),1L, (int) time);
        }

        /**
         * Own function for translate id > Material
         * @param id id
         * @return Material by id
         */
        public Material giveMaterialById(int id){
            for (Material m : Material.values()){
                if(m.getId() == id)
                    return m;
            }
            return Material.AIR;
        }

        /**
         * Send a good visual effect
         * @param block Particle block & location
         * @param type Type of the particle
         */
        public void particle(Block block, final Material type){

            if(Utils.randomInteger(0, 100) >= 60) {
                final Location loc = block.getLocation();
                loc.getWorld().playEffect(loc, Effect.STEP_SOUND,
                                         (type == Material.AIR ? block.getType().getId() : type.getId()));
            }
        }

        /**
         * A1 Benchmark = 13s 10Blocks/5ticks
         * @param icount
         * @param bsize
         */
        public void renaming(double icount, double bsize){
            //Percentage algorithme
            double pc = (icount/ bsize) * 100.0;
            pc = Math.floor(pc);

            //Time algorithme
            double t = (time/20);
            double trenaming = (bsize - (icount)) * (t/10.);
            int timerenaming = (int) trenaming;

            Utils.sendActionBar(p, "§7Avancé : §e" + pc + "%, il reste environ : " +  timerenaming + " seconde" + ((timerenaming <= 1) ? "" : "s"));

        }



    }

     
     
  3. This looks butiful, I have to admit, but it seems you are using a custom API. I know how to do most of it(Action Bar, random number, ect), but I need to know what "Shelter", "ReflectionUtils.getValue(cuboidClip, true, "data");, and "ShelterType". You can just change it or send me the api, <3 Thanks once again!

    And another thing. I've tried googling things once more, but I've stumbled into a error. Whenever I try to run this is says in the console: http://pastebin.com/6eiJ3ZKv Something to do with not finding the class of "MaxChangedBlocksException"

    Code (Text):
     public static void pasteSchematic(File file, World world, int x, int y, int z) throws DataException, IOException, MaxChangedBlocksException {
                if (file.exists()) {
                    Vector vector = new Vector(x, y, z);
                    BukkitWorld bukkitWorld = new BukkitWorld(world);
                    EditSession editSession = new EditSession(bukkitWorld, 100);
                    CuboidClipboard clipboard = SchematicFormat.MCEDIT.load(file);
                    clipboard.place(editSession, vector, true);
                } else {
                    log.log(Level.SEVERE,
                            "Schematic {0} does not exist", file);
                }
            }