Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Code to set wall to air

Comments in 'Plugin Development' started by Kabluinc, Jul 8, 2016.

  1. Kabluinc
    Offline

    Kabluinc New Member

    Joined:
    Mar 2, 2016
    Posts:
    29
    Minecraft User:
    Kabluinc
    For a micro battles plugin I need to be able to set a glass wall to air

    What would be the code for this. For example in world edit I can set the lowest pos of the wall and highest pos and //set 0

    How can I do this with code so I can incorporate it into a plugin
  2. Survingo
    Offline

    Survingo Active Member

    Joined:
    Dec 6, 2015
    Posts:
    221
    You can array command sender's position while doing for example // pos1 and // pos2 and use PHP's + and - function.
    I'm not really sure about the code to do that....
  3. MyNameIsTriXz
    Offline

    MyNameIsTriXz Notable Member

    Joined:
    Aug 17, 2015
    Posts:
    538
    Minecraft User:
    MyNameIsTriXz
    The shape of the glass wall is a cross. So I am recommending a for() loop for removing the glass blocks.

    PHP:

    $wallX
    ;
    $wallZ;


    for(
    $x 0$x 20$x++){
    for(
    $y 0$y 10$y++){
    $level->setBlock(new Air(), new Vector3($x$y$wallZ));
    }}

    for(
    $z 0$z 20$z++){
    for(
    $y 0$y 10$y++){
    $level->setBlock(new Air(), new Vector3($wallX$y$z));
    }}

    wallZ and wallX are the constant X and Z positons of the wall.
    Survingo likes this.
  4. Kabluinc
    Offline

    Kabluinc New Member

    Joined:
    Mar 2, 2016
    Posts:
    29
    Minecraft User:
    Kabluinc
    What parts of your code do I need to change with my walls coordinates. and also which parts of the walls do I get coordinates from to add to the code
  5. Kabluinc
    Offline

    Kabluinc New Member

    Joined:
    Mar 2, 2016
    Posts:
    29
    Minecraft User:
    Kabluinc
    otherwise, can I give you an attachment of my micro battles world map so you could tell me what the code including coordinates would be to remove the walls?

    Many thanks,
  6. Survingo
    Offline

    Survingo Active Member

    Joined:
    Dec 6, 2015
    Posts:
    221
    What do you mean by changing the coordinates of walls?
    You show us an picture of your server and we say you: "That block is on 123, 65, 128"....?
    Last edited: Jul 8, 2016
  7. Kabluinc
    Offline

    Kabluinc New Member

    Joined:
    Mar 2, 2016
    Posts:
    29
    Minecraft User:
    Kabluinc
    I need to add the coordinates of my wall to the code so that the code can set the wall to air. but what do I have to change in the code.
  8. Survingo
    Offline

    Survingo Active Member

    Joined:
    Dec 6, 2015
    Posts:
    221
    Each block in your world have a position. A block have an x, y and z. If you want to add your coordinates of the wall you can make a command which return the position of the sender.
    PHP:
    use pocketmine\Player;
    use 
    pocketmine\command\CommandSender;
    use 
    pocketmine\command\Command;
    PHP:
    public function onCommand(CommandSender $senderCommand $command$label, array $args){
        switch(
    strtolower($command->getName())){
           case 
    "position":
              if(
    $sender instanceof Player){
                       
    $sender->sendMessage("Location of block under you: X §2" $sender->getX() . " §fY§2 " $sender->getY()-" §fZ§2 " $sender->getZ());
                    }
                 }
              }
    You can run the command if you stand on a block in the corner of your wall.
    Kabluinc likes this.
  9. MyNameIsTriXz
    Offline

    MyNameIsTriXz Notable Member

    Joined:
    Aug 17, 2015
    Posts:
    538
    Minecraft User:
    MyNameIsTriXz
    Kabluinc and Survingo like this.
  10. Jazzwhistle
    Offline

    Jazzwhistle Notable Member

    Joined:
    Dec 27, 2014
    Posts:
    364
    Minecraft User:
    Awzaw
    If you are going to write a plugin to remove a wall (or anything else), you might as well add a way to define the coordinates in the game too. That way you would avoid hard coding the xyz into the plugin, be able to define multiple walls to remove (if needed), move things around in your map without having to recode the plugin, and share the plugin with other players without them having to modify the code for their own maps.
  11. Kabluinc
    Offline

    Kabluinc New Member

    Joined:
    Mar 2, 2016
    Posts:
    29
    Minecraft User:
    Kabluinc
    @MyNameIsTriXz Heres the microbattles world I need the glass wall removal code to work with. Thanks ever so much for your help

    Attached Files:

  12. MyNameIsTriXz
    Offline

    MyNameIsTriXz Notable Member

    Joined:
    Aug 17, 2015
    Posts:
    538
    Minecraft User:
    MyNameIsTriXz
    Umm, could you screenshot it? Anyways use my attached image on the posted link as your template. To get the coordinates just add:
    PHP:
    public function onInteract(PlayerInteractEvent $event){
    $b $event->getBlock();
    $event->getPlayer()->sendMessage("X: ".round($b->x)." Y: ".round($b->y)." Z: ".round($b->z));
    }
  13. Kabluinc
    Offline

    Kabluinc New Member

    Joined:
    Mar 2, 2016
    Posts:
    29
    Minecraft User:
    Kabluinc
    I attached a screenshot. I did see ur link but I couldnt quite understand it. Could u maybe point out in my screenshot where would i stand exactly to get the the minx maxX etc. That would be very helpful thanks allot!

    Attached Files:

  14. MyNameIsTriXz
    Offline

    MyNameIsTriXz Notable Member

    Joined:
    Aug 17, 2015
    Posts:
    538
    Minecraft User:
    MyNameIsTriXz
    http://m.imgur.com/s1TIr6B
  15. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    Or simply use some existing libraries to do that.
    The WorldEditArt plugin, although user interface never completed, has a working codebase for editing. (It is really ironic how many "developers" only declared the commands to do this and do that and the real command executors are always `// TODO: Implement this command`, those rubbish plugins on GitHub; while @PEMapModder always only has the code that actually does something, but he never wrote the code to declare those commands, totally the opposite)
    Therefore, you can borrow some code from WorldEditArt. How to do that? Copy the whole plugin, and merge the src folder with yours. You don't need to worry about WorldEditArt loaded as well, because as long as you don't change the `main` in your `plugin.yml`, that plugin won't get loaded, and as long as you don't call the wrong functions (I don't see why you would...), WorldEditArt won't automatically register the commands or do stuff.

    Using the WorldEditArt library has the advantage of executing the world editing block by block, a limited amount per tick, to ensure not exceeding a server load limit.

    Here is an example (would most likely fail because WorldEditArt hasn't been debugged, but the most complicated parts have been independently tested already, according to @PEMapModder, no citation available):

    PHP:
    use WorldEditArt\Utils\BulkJobManager;
    use 
    WorldEditArt\Utils\ProgressiveTask;
    use 
    pocketmine\plugin\Plugin;
    use 
    WorldEditArt\Objects\Space\Cuboid\CuboidSpace;
    use 
    pocketmine\math\Vector3;
    use 
    WorldEditArt\Objects\BlockStream\WeightedBlockList;
    use 
    WorldEditArt\Objects\BlockStream\WeightedBlockType;
    use 
    WorldEditArt\Objects\BlockStream\WeightedListBlockChanger;
    use 
    WorldEditArt\Objects\BlockStream\Cassette;
    use 
    WorldEditArt\Utils\BulkJob;

    // in the plugin startup, prepare a BulkJobManager that will manage all bulk world editing jobs
    $manager = new BulkJobManager();
    $server->getScheduler()->scheduleRepeatingTask// of course we still need to use the scheduler interface
        
    new class($plugin$manager) extends ProgressiveTask// wrap the manager with a ProgressiveTask
          
    public function __construct(Plugin $pluginBulkJobManager $manager){
            
    parent::__construct(new \WorldEditArt\WorldEditArt(), // ProgressiveTask expects a WorldEditArt instance, so here we are hacking it with a dummy placeholder right now
            
    $manager0.05 0.1); // 0.05 is the length of one standard server tick. 0.1 is 10%, which is the amount of server tick time we are allocating to this BulkJobManager to run per tick
            
    $this->owner $plugin// correct the PluginTask::$owner property
          
    }
        }, 
    1); // run it per tick

    $cuboidSpace = new CuboidSpace($level, new Vector3($x0$y0$z0), new Vector3($x1$y1$z1)); // select a cuboid from x0,y0,z0 to x1,y1,z1
    $blockStream $cuboidSpace->getSolidBlockStream(); // create a BlockStream that allows you to iterate over the cuboid space. Solid is in contrast to hollow.
    $list = new WeightedBlockList(); // create a WeightedBlockList, which can contain a weighted list of blocks to change to
    $list->add(new WeightedBlockType(100)); // adds a block type of ID 0 and damage 0 to the list. "1" is related to the chance of the block getting picked, but since we only have one block type, this doesn't matter (as long as it isn't 0)
    $blockChanger = new WeightedListBlockChanger($list); // create a BlockChanger for that list, which will keep returning random blocks from the list

    $cassette = new Cassette($blockStream$blockChanger); // create a Cassette, which is an object that will pull one position from BlockStream and pair it with a new value from BlockChanger, and store it in a queue
    $bulkJob = new class($cassette) implements BulkJob// we need a BulkJob object. WorldEditArt isn't very complete for external use, so we have to implement this ourselves
      
    public $cassette;
      public function 
    __construct($cassette){ $this->cassette $cassette; } // store the cassette in this object
      
    public function hasMore() : bool{
        return 
    $this->cassette->next() === null// if the next item from the cassette is null, the cassette is finished and we can stop executing this BulkJob
      
    }
      public function 
    doOnce(){
        list(
    $from$to) = $this->cassette->current(); // extract the current change from the cassette
        
    $from->getLevel()->setBlock($from$to); // change $from to $to
      
    }
    };

    $manager->add($bulkJob); // finally, add this BulkJob to the BulkJobManager and wait for the server to automatically execute it slowly!
    Sounds complicated? Trust me, this is already much simpler than the logic/maths part in WorldEditArt for these things:
    • block iteration (it is easy to do it with the for-loop, but much more difficult if you want to do it just once per function call! You can't use a for-loop at all!) (and actually there is also support for oblique cylinders and ellipsoids!)
    • weighted random block picking (OK, I also agree that @PEMapModder is too obsessive in adding these features)
    • handling multiple cassettes in a queue (this is easy as long as you are familiar with arrays, but...)
    • with undo support (that means, even after completing the cassette, you need to put it in an undo queue, and what's more...)
    • expect to undo, redo, then undo, then redo again in the middle of a cassette (the player is crazy, but @PEMapModder is even more crazy to spend time catering the needs of this player, and with cassettes in queue in front of and behind this single cassette!)
    • simplify everything into a linear stack that points straight from the while-loop inside the Task::eek:nRun() function straight to the Level::setBlock() function, without any other loops involved! (This is simple compared to the previous ones, but still...)
    • control the amount of CPU distributed to each BulkJob, where each BulkJob is a CassetteQueue for an individual player! This is a two-dimensional array of cassettes!
    One day it gets very hot (today in Hong Kong is the hottest July day in 50 years), we should all blame @PEMapModder for wasting our electricity on such useless and time-consuming features. He probably even took many deep breaths in the thinking process, which increases his carbon dioxide emission, thus also enhancing greenhouse effect. We must blame him for that.
    Last edited: Jul 9, 2016
  16. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    Well apart from the fact that I had to create two anonymous classes to overcome some limitations due to not using the WorldEditArt plugin directly and I had to hack the plugin by overriding its functions, it is still quite easy ;)
    After all, these are the only real API calls that happened:
    PHP:
    $cuboidSpace = new CuboidSpace($level, new Vector3($x0$y0$z0), new Vector3($x1$y1$z1));
    $blockStream $cuboidSpace->getSolidBlockStream();
    $list = new WeightedBlockList();
    $list->add(new WeightedBlockType(100));
    $blockChanger = new WeightedListBlockChanger($list);
    $cassette = new Cassette($blockStream$blockChanger); 
    $bulkJob = new SomeMoreFriendlyBulkJobImplementationThatWeNeed($cassette);
    $manager->add($bulkJob);
  17. MyNameIsTriXz
    Offline

    MyNameIsTriXz Notable Member

    Joined:
    Aug 17, 2015
    Posts:
    538
    Minecraft User:
    MyNameIsTriXz
    wat?




    It's... It's just a simple 8 line code.


    Why are you making such a study from it? Just use a for-loop and don't implement a whole plugin with about 30 classes, just for a simple code to remove a wall. And for the lagg issue, just run an AsyncTask. I don't understand how you can spend so much work... It's very kind of you to spend so much to solve his problem, but wouldn't the 8 line for-loop code be much overviewable and generally better?
    Survingo likes this.
  18. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    And this code will look really awesome if it is in Java and the classes get generalized:

    PHP:
    final Plugin plugin;
    BulkJob manager = new BulkJobManager();
    server.getScheduler().scheduleRepeatingTask(new ProgressiveTask(new WorldEditArt.WorldEditArt(), managerthreshold){
      public 
    BulkJob fix(){
        
    this.owner plugin;
        return 
    this;
      }
     }.
    fix(), 1);

    Space cuboidSpace = new CuboidSpace(level, new Vector3(x0y0z0), new Vector3(x1y1z1));
    BlockStream blockStream cuboidSpace.getSolidBlockStream();
    WeightedBlockList list = new WeightedBlockList().add(WeightedBlockType.builder()
      .
    weight(1.0f)
      .
    id(0).damage(0)
      .
    build());
    BlockChanger blockChanger = new WeightedListBlockChanger(list);
    final 
    Cassette cassette = new Cassette(blockStreamblockChanger);
    BulkJob bulkJob = new BulkJob(){
      public 
    boolean hasMore(){
        return 
    cassette.next() != null;
      }
      public 
    void doOnce(){
        
    Block[] blocks cassette.current();
        
    blocks[0].getLevel().setBlock(blocks[0], blocks[1]);
      }
    }.
    fix(plugin);
    manager.add(bulkJob);
  19. MyNameIsTriXz
    Offline

    MyNameIsTriXz Notable Member

    Joined:
    Aug 17, 2015
    Posts:
    538
    Minecraft User:
    MyNameIsTriXz
    Try to count up your post count?
  20. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    "Just use a for-loop and don't implement a whole plugin with about 30 classes, just for a simple code to remove a wall." I am very worried about lag.
    "And for the lagg issue, just run an AsyncTask." You can't use an AsyncTask to call setBlock directly, or you will be facing race conditions and nulled object references due to attempts to thread unthreaded objects. You must do it synchronously, and to prevent lag you must do it bit by bit.
    "Wouldn't the 8 line for-loop code be much overwiewable and generally better?" But I can eventually simplify my code into 8 lines of code as well, just that WorldEditArt requires some editing! ;)

Share This Page

Advertisement