Tutorial Storing Blocks in the config! [spawn structures]

Discussion in 'Resources' started by Ganga, Jan 10, 2015.

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

    Ganga

    Hey guys!
    This is my first tutorial in bukkit so dont be to mean :rolleyes:

    Introduction:
    I experimented a whole day on how to storge blocks in a config to load them any other time.
    But that was pretty simple. Then I figured out how to spawn those blocks in relation to the player.
    And this is what Iam going to show you today.

    Useful usage of code:
    • sell buildings which can be spawned next to the player
    • duplicate structures
    • swap buildings with others who have this plugin!
    • Impress your friends!

    the tutorial:
    I wont explain how to setup the workspace and such stuff ;)
    First of all we need to create a void:
    Code:
        public void restoreBlocks(final Player p){
     
        }
    We have to include the player, because we want to get his location later as well.

    Now we create an Event Handler, to get blocks which were placed for example.
    We make an if clause to ask if the player is in a kind of edit mode. You can toggle this public boolean in a command for example.
    Code:
        @EventHandler
        public void onBlockPlace(BlockPlaceEvent event){
            if(ineditmode){
    
            }
        }
    Now my idea was to create a global integer which counts the placed blocks [cobble] (in edit mode).
    We are going to name it blockcount.
    Code:
    public int blockcount = 0;
    Then we save the locations of the block + his count + his material + his data in the config!

    Afterwards we need to get the location of the one who toggled himself into edit mode. His location will be saved as a global Location commandloc.
    Code:
        @EventHandler
        public void onBlockPlace(BlockPlaceEvent event){
            if(ineditmode){
                System.out.print("PLACED"); //to see if it works
                blockcount++; //here we add 1 to our blockcount when 1 block was safed.
                getConfig().set("BlockLocations." + blockcount+ ".X",event.getBlock().getX() - commandloc.getBlockX());
                getConfig().set("BlockLocations." + blockcount+ ".Y",event.getBlock().getY() - commandloc.getBlockY());
                getConfig().set("BlockLocations." + blockcount+ ".Z",event.getBlock().getZ() - commandloc.getBlockZ());
                getConfig().set("BlockLocations." + blockcount+ ".type", event.getBlock().getType().toString());
                getConfig().set("BlockLocations." + blockcount+ ".data",event.getBlock().getData());
                saveConfig();
            }
        }
    I think this isnt working that well when you use an array. Arrays will lead to more errors lateron when your going to load the blocks from the config. But feel free to use one.


    So. Now lets get to the more complicate part of this thread.
    We create a Runnable to add a cool effect when the blocks are placed.

    Now read the annotation in the code:
    Code:
        public void restoreBlocks(final Player p){
            reloadConfig(); //we need to reload the config to check for changes
            new BukkitRunnable() { //here we add the runnable
        
                int blockcount= (int) getConfig().get("Outpost.blocks"); //you could store the amount of blocks being saved for further usage. You set this value in your command block when you get out of edit mode.
                public void run() {
            if(blockcount>0){ //This if clause will reapeat until the blockcount counts down all the way to 1 (including 1)
    
            int X = commandloc.getBlockX(); // here we get the locations of the command user
            int Y = commandloc.getBlockY();
            int Z = commandloc.getBlockZ();
           // now we need to set the location of our restored block. therefore we restore his locations from the config and adding them to the user of the command. Then it will be created in releation to his location.
            Location targetLoc = new Location(p.getWorld(), (X) + getConfig().getInt("BlockLocations." + blockcount+ ".X"),(Y) + getConfig().getInt("BlockLocations." + blockcount+ ".Y"),(Z) + getConfig().getInt("BlockLocations." + blockcount+ ".Z"));
            Material mat = Material.getMaterial((getConfig().getString("BlockLocations." + blockcount+ ".type").toString()));
            targetLoc.getBlock().setType(mat);
            targetLoc0.getBlock().setData((byte) getConfig().get("BlockLocations." + blockcount+ ".data"));
            targetLoc.getBlock().getWorld().playEffect(targetLoc, Effect.STEP_SOUND, targetLoc.getBlock().getType()); //we add a cool effect on the placement of the block!
            blockcount--; //now this all will repeat and blockcount will be reduced by 1
            }
            else{
                this.cancel(); //when we reached 1 we dont want it to start again.
            }
                }
             }.runTaskTimer(this, 2, 2); //here we can set up the speed of the block placement. The higher the numbers, the slower it places the blocks.
     
        }
    Before you generade your building you have to exit the editmode and save your blockcount to the config!


    Your done! :D
    I hope you enjoyed my hint and hopefully you could use it in your code someday :)

    Feel free to ask if something is unclear! I know some parts could be optimized, but this is up to you;)
     
    Last edited: Jan 14, 2015
  2. Offline

    mrCookieSlime

    @Ganga
    1. You should probably also store the data of a block since the way you have it setup atm does not listen for colored Blocks or other Tree Types etc.
    2. Last snippet, line 14. getString() already returns a string. No need to call .toString()
    3. You never set the total blocks count to the config, even though you are accessing that value in your last snippet (line 5)
     
    Ganga likes this.
  3. Offline

    Ganga

    Thats right. BlockState could be added as well.

    But I tried it without .toString() and it gave me an error :eek:
    Thats why I included it. I made a thread on this in the general bukkit development.
    Maybe my server just wanted to troll me idk :oops:
     
  4. Offline

    mrCookieSlime

    @Ganga
    I added a third point as well and I wasnt referring to BlockState. I meant the Blocks data. The byte which you get by calling .getData()
    But adding the BlockState as well would be even better.
     
  5. Offline

    Ganga

    Ahh sorry for this. I made this in my command block when you get out of editmode. Ill add it.

    Ok I understand. :)
    Strange but I didnt made my mind up to that haha. Until now.
     
  6. Offline

    teej107

    [​IMG]
     
    xTrollxDudex, Skionz and Ganga like this.
  7. Offline

    Ganga

    ChipDev likes this.
  8. Offline

    Skionz

    @Ganga He means you shouldn't be doing:
    Code:
    if(true == true)
    Instead, you should be doing:
    Code:
    if(true)
     
    Ganga likes this.
  9. Offline

    ChipDev

    [​IMG]
     
  10. Offline

    Ganga

    @ChipDev
    ?! What do you mean by many booleans? :eek:
    Thats. Only. One?
     
  11. Offline

    ChipDev

    Many booleans from TJ's post
    'BOOLEAN INSIDE OF A BOOLEAN' ETC.
     
  12. Offline

    teej107

    Code:
    boolean boolean1 = boolean2 == true // <-- 3rd boolean 
     
  13. Offline

    ChipDev

    Would that even compile?
     
  14. Offline

    teej107

    @ChipDev Assuming "boolean2" exists and you haven't forgotten the semi-colon, yes!
     
    ChipDev likes this.
  15. Offline

    Ganga

    @teej107 @ChipDev
    But I've only one boolean: ineditmode
    Thats all.
    How would you do the editmode without a boolean?
     
    ChipDev likes this.
  16. Offline

    teej107

    @Ganga "ineditmode" is a boolean. The "true" you use to check is a boolean. The == part makes a boolean. 3 booleans.
    You have this in your second code tag:
    Code:
    if(ineditmode == true)
    but looks like you changed it in your third code tag.
     
    Ganga likes this.
  17. Offline

    Ganga

    @teej107
    Yes I did. I thought that it asks wether the boolean is true :eek:
    Ok then I mixed something up.
    But thx anyway
     
  18. Offline

    ChipDev

    It does!
    if(boolean) is simpler.
     
    Ganga likes this.
  19. This one is still using the triple boolean supreme :)

    Is there any reason this value is public? That seems a bad idea.

    Additionally, saving a config every time a block is placed sound like a bad idea too ;)
     
    Ganga likes this.
  20. Offline

    Ganga

    @AdamQpzm
    The config isnt saved every time a block is placed. Only if the player is in the edit mode. And that doesnt happen too often :)
    I know its hard work for the CPU:) But shit happens.:D
    [cake]
     
  21. Offline

    xTrollxDudex

    boolean isTrue;
    if ((boolean = (bool == true) == true)
     
  22. Offline

    ChipDev

    if(boolean)
     
  23. Offline

    Aqua

    Incorrect;
    if (bool)
     
  24. Offline

    ChipDev

    Meh,
     
Thread Status:
Not open for further replies.

Share This Page