WorldEdit API Plugin

Discussion in 'Plugin Development' started by Techtony96, Dec 30, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Techtony96

    Could someone show me how to select an area with the WorldEdit API and then replace blocks in that selection?

    Lets have the selection be:
    X: -100
    Y: 0
    Z: -100
    to
    X: 100
    Y: 256
    Z: 100

    and replace grass to dirt

    Thanks!
     
  2. Offline

    LegoPal92

    Go to the blocks, right click with the wand for the first spot, then left click the second spot. then type:
    //replace grass dirt
     
  3. Offline

    Techtony96

    -.-

    i mean in java code for a plugin. Not in-game as a player
     
    zachoooo likes this.
  4. Offline

    1mpre55

  5. Offline

    c0mp

    Tagging Moderators = Bad
    Using Report Button = Good

    Moved to Plugin Development!
     
    colony88, chasechocolate and gomeow like this.
  6. Offline

    1mpre55

    Sorry, I'll keep that in mind.
     
  7. Offline

    c0mp

    NP!
     
  8. Offline

    fireblast709

  9. Offline

    Techtony96

    Thanks, i will reply here with some code and can you check if i did it correctly?

    This is my code so far. am i close? Also, i still dont know how to select the region:

    Code:
    public void stage1(){
     
    replace(null, null, null, null);
    }
     
     
    public void replace(CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException {
     
           Set<BaseBlock> from;
           Pattern to;
           if (args.argsLength() == 1) {
               from = null;
               to = we.getBlockPattern(player, args.getString(0));
           } else {
               from = we.getBlocks(player, args.getString(0), true, !args.hasFlag('f'));
               to = we.getBlockPattern(player, args.getString(1));
           }
     
           int affected = 0;
           if (to instanceof SingleBlockPattern) {
               affected = editSession.replaceBlocks(session.getSelection(player.getWorld()), from,
                       ((SingleBlockPattern) to).getBlock());
           } else {
               affected = editSession.replaceBlocks(session.getSelection(player.getWorld()), from, to);
           }
     
           player.print(affected + " block(s) have been replaced.");
       }
    
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  10. Offline

    Techtony96

    bump.

    awwww. No one?

    D:

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  11. Offline

    Techtony96

  12. Offline

    Scizzr

    If you're just trying to replace the blocks between two locations, you don't really need WorldEdit for that.
    Code:
    public void doReplace(Location min, Location max, Material replace, Material with) {
        for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
            for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
                for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
                    Block blk = min.getWorld().getBlockAt(new Location(min.getWorld(), x, y, z));
                    if (blk.getType() == replace) {
                        blk.setType(with);
                    }
                }
            }
        }
    }
    

    If you're actually trying to replace the blocks in the player's WorldEdit selection, the way I do this is the following:
    1) First, you need to get the main class for the WorldEdit plugin. I disable my plugin if I don't have it. It's optional though. This goes in your main class; in this example it's named MainClass.
    Code:
    //MainClass.class
    public class MainClass extends JavaPlugin {
        public Logger log = Logger.getLogger("Minecraft");
        public PluginManager pm;
     
        public WorldEditPlugin wep;
     
        OtherClass other;
       
        public void onEnable() {
            pm = Bukkit.getPluginManager();
       
            boolean dis = false;
            wep = getWorldEdit();
            if (wep == null) { log.info("WorldEdit could not be found. Plugin disabled."); dis = true; }
            if (dis) { pm.disablePlugin(this); }
           
            other = new OtherClass(this);
        }
       
        public WorldEditPlugin getWorldEdit() {
            Plugin plugin = pm.getPlugin("WorldEdit");
            if (plugin == null || !(plugin instanceof WorldEditPlugin)) { return null; }
            return (WorldEditPlugin)plugin;
        }
    }
    
    2) Next, you need to get the area that the player has selected. I'm going to require it to be a standard cuboid selection for this example, but you can edit it to your needs.
    Code:
    //OtherClass.class
    MainClass main;
     
    public OtherClass(MainClass main) {
        this.main = main
    }
     
    public void doReplace(Player p, Material replace, Material with) {
        Selection sel = sex.wep.getSelection(p);
     
        if (sel == null) {
            p.sendMessage("You don't have a selection."); return;
        }
     
        if (!(sel instanceof CuboidSelection)) {
            p.sendMessage("Your selection isn't a cuboid."); return;
        }
     
        Location min = sel.getMinimumPoint();
        Location max = sel.getMaximumPoint();
     
        for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
            for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
                for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
                    Block blk = min.getWorld().getBlockAt(new Location(min.getWorld(), x, y, z));
                    if (blk.getType() == replace) {
                        blk.setType(with);
                    }
                }
            }
        }
    }
    



    Anyways if you still need help, let us know. :)

    Good luck!
     
  13. Offline

    gomeow

    c0mp
    The term has been changed to Tahging now. Not tagging btw...
     
    colony88, chasechocolate and zachoooo like this.
  14. Offline

    Techtony96

    So if i wanted to use this code, i could initialize the variable globally, and then define them on one method, call this method to run, and it would run with those 2 block definitions. Are the variables as follows? I don't know how to define the material variables :/

    public void stage1(){
    World world = world;
    Location min = new Location(world, -100, 0, -100);
    Location max = new Location(world, 100, 256, 100);
    Material replace = 2;
    Material with = 3;
    //Grass to Dirt

    doReplace(min, max, replace, with);
    }
     
  15. Offline

    1mpre55

    Techtony96
    Material is enum, not Integer, you'll need to use Material replace = Material.getMaterial(2).
    Also, World world = world; will result in a compile-time error.
     
  16. Offline

    fireblast709

    Actually not always. I can think of a case where it will compile and run perfectly
    Code:java
    1. public class A
    2. {
    3. World world;
    4. public A(someWorld)
    5. {
    6. this.world = someWorld;
    7. }
    8.  
    9. public void stuff()
    10. {
    11. World world = world;
    12. }
    13. }
     
  17. Offline

    1mpre55

    What happens in line 11 is you're declaring a new World object called world and then immediately try to initialize it setting it to an object called world (itself) that was already declared but not initialized yet. You need to change it to "World world = this.world;" for it to work how you want it to. Try it.
     
  18. Offline

    fireblast709

    1mpre55 nope, compiles perfectly fine
     
  19. Offline

    1mpre55

  20. Offline

    fireblast709

    Weird now it does not let me... IDE derp :p
     
  21. Offline

    1mpre55

    Code:
    Bukkit.getServer().getWorlds().get(0);
    This will give you the world that was loaded the first, usually the default "overworld" world.
     
  22. Offline

    Techtony96

    Scizzr

    How would i only replace 10% of a block to another block? I'm trying to achieve a fade effect.
     
  23. Offline

    1mpre55


    Easy way:
    Code:
    if (Math.random() < .1) {
        // do stuff
    }
    A little bit more complicated:
    Code:
    Random random = new Random();
     
    if (random.nextDouble() < .1) {
        // do stuff
    }
    // OR
    if (random.nextInt(100) < 10) {
        // do stuff
    }
    In your case you should put the if statement right after the last for statement.
     
  24. Offline

    fireblast709

    that is not 10% of the blocks replaced, that is 10% chance it gets replaced. You should get 10% of the total blocks and replace them randomly.
    1. get a List of blocks
    2. get the size, and divide by 10 (for 10%) and set it to int remaining
    3. take a random between 0 and list.size()
    4. replace that block
    5. remove that block from the list and decrement remaining
    6. if(remaining > 0) goto 3
    7. you have replaced 10% of the blocks
     
    Scizzr likes this.
  25. Offline

    Scizzr

    Well said.


    Techtony96
    Here's some code. Enjoy.
    Code:
    public void doReplace(Player p, Material replace, Material with, int percent) {
        if (percent > 100) { p.sendMessage(String.format("You cannot replace %d%% of 100%%.", percent)); return; }
        
        Selection sel = sex.wep.getSelection(p);
        
        if (sel == null) {
            p.sendMessage("You don't have a selection."); return;
        }
        
        if (!(sel instanceof CuboidSelection)) {
            p.sendMessage("Your selection isn't a cuboid."); return;
        }
        
        Location min = sel.getMinimumPoint();
        Location max = sel.getMaximumPoint();
        
        List<Block> blocks = new ArrayList<Block>();
        
        for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
            for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
                for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
                    Block blk = min.getWorld().getBlockAt(new Location(min.getWorld(), x, y, z));
                    if (blk.getType() == replace) {
                        blocks.add(blk);
                    }
                }
            }
        }
        
        Collections.shuffle(blocks);
        
        int size = blocks.size();
        int toLeave = (int)Math.ceil(((double)percent/100)*size);
        int toReplace = size-toLeave;
        int count = 0;
        
        for (int i = 0; i < toReplace; i++) {
            blocks.remove(0);
            count++;
        }
        
        for (Block blk : blocks) {
            blk.setType(with);
        }
        
        //p.sendMessage(String.format("Replaced %d of %d blocks (%d left)", size-count, size, count));
    }
    
    Good luck! :)
     
    1mpre55 likes this.
  26. Offline

    1mpre55

    Eww, goto :eek:. And sorry, I thought OP wanted it to be random.
     
  27. Offline

    fireblast709

    goto as in pseudo code... And he wanted 10% of the blocks to be replaced, which is picked at random
     
  28. Offline

    Techtony96

    fireblast709 Scizzr

    Thanks for the code Scizzr :D
    And this is better than world edit as its A LOT simpler and seems to be faster. Question: Is this sending each individual block update to the client or as chunks? Also, will be integrating this code this weekend :D
     
    Scizzr likes this.
  29. Offline

    fireblast709

    it will set it serverside (so later the server will inform the client of the changes)
     
  30. Offline

    Scizzr

    It's changing them block by block.
     
Thread Status:
Not open for further replies.

Share This Page