[SNIPPET] Block Generation Class - Easy structure creation!

Discussion in 'Resources' started by AstramG, May 15, 2014.

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

    AstramG

    Today I was looking around the Bukkit forums and found a question in the plugin development section asking how to create structures in a world. I took initiative and decided to create a quick little class that will allow you to create your own structures with ease!

    This little amount of code will create a glass shell around the player:
    Code:java
    1.  
    2. new BlockGenerator(
    3.  
    4. new BlockLayer(";AGA")
    5. .setBlockType('G', Material.GLASS),
    6.  
    7. new BlockLayer("AGA;GAG;AG")
    8. .setBlockType('G', Material.GLASS),
    9.  
    10. new BlockLayer("AGA;GAG;AG")
    11. .setBlockType('G', Material.GLASS),
    12.  
    13. new BlockLayer(";AGA")
    14. .setBlockType('G', Material.GLASS))
    15.  
    16. .generate(player.getLocation().subtract(1, 1, 1), true);


    Following this simple syntax is very easy! If you are familiar with Bukkit's recipe system it'll be even easier for you, as it's based around the same idea. I'll break it down for you guys right now.

    A BlockGenerator is a container class for the BlockLayers. Just create a new BlockGenerator and for the constructors, place as many BlockLayers as you would like. A BlockLayer has a constructor of the format of the layer. Keep in mind that the BlockLayer will progress down the Z axis, unless you instruct it to move to the X value by using ';'. Then, by using .setBlockType which requires a character and a Material, you will be able to set the block's type for what is included in the constructor for the BlockLayer. If you don't set the block's type, then it will just be air. Also, if you haven't caught on, creating a new layer will make the Y axis increase.

    Just copy and paste this code into a new class called BlockGenerator:
    Code:java
    1. package me.astramg.resources;
    2.  
    3. import java.util.ArrayList;
    4. import java.util.HashMap;
    5. import java.util.List;
    6.  
    7. import org.bukkit.Effect;
    8. import org.bukkit.Location;
    9. import org.bukkit.Material;
    10. import org.bukkit.block.Block;
    11. import org.bukkit.plugin.Plugin;
    12. import org.bukkit.scheduler.BukkitRunnable;
    13.  
    14. public class BlockGenerator {
    15.  
    16. List<BlockLayer> layers = new ArrayList<BlockLayer>();
    17.  
    18. public BlockGenerator(BlockLayer... layers) {
    19. for (BlockLayer layer : layers) {
    20. this.layers.add(layer);
    21. }
    22. }
    23.  
    24. public void addLayer(BlockLayer layer) {
    25. layers.add(layer);
    26. }
    27.  
    28. private int i = 0;
    29.  
    30. public void generateWithTime(final Plugin plugin, final Location startLocation, final Long timeInTicks, final boolean effect) {
    31. long ticks = (long) Math.ceil(timeInTicks / layers.size());
    32. new BukkitRunnable() {
    33. public void run() {
    34. final BlockLayer layer = layers.get(i);
    35. final Location layerStart = startLocation.clone().add(0, layers.indexOf(layer), 0);
    36. new BukkitRunnable() {
    37. public void run() {
    38. layer.generateLayer(layerStart, effect);
    39. }
    40. }.runTask(plugin);
    41. i++;
    42. if (i == layers.size()) {
    43. i = 0;
    44. this.cancel();
    45. }
    46. }
    47. }.runTaskTimerAsynchronously(plugin, 1L, ticks);
    48. }
    49.  
    50. public void generate(Location startLocation, boolean effect) {
    51. for (BlockLayer layer : layers) {
    52. Location layerStart = startLocation.clone().add(0, layers.indexOf(layer), 0);
    53. layer.generateLayer(layerStart, effect);
    54. }
    55. }
    56.  
    57. public static class BlockLayer {
    58.  
    59. private String layer;
    60. private HashMap<Character, Material> chars = new HashMap<Character, Material>();
    61.  
    62. public BlockLayer(String layer) {
    63. this.layer = layer;
    64. }
    65.  
    66. public BlockLayer setBlockType(char character, Material material) {
    67. chars.put(character, material);
    68. return this;
    69. }
    70.  
    71. @SuppressWarnings("deprecation")
    72. public void generateLayer(Location start, boolean effect) {
    73. int skip = 0;
    74. int rowZ = 0;
    75. for (int i = 0; i < layer.length(); i++) {
    76. char character = layer.charAt(i);
    77. if (character == ';') {
    78. rowZ ++;
    79. skip = i + 1;
    80. } else {
    81. Block block = start.getWorld().getBlockAt(start.getBlockX() + i - skip, start.getBlockY(), start.getBlockZ() + rowZ);
    82. if (chars.containsKey(character)) {
    83. block.setType(chars.get(character));
    84. if (effect) {
    85. block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
    86. }
    87. }
    88. }
    89. }
    90. }
    91.  
    92. }
    93.  
    94. }
    95.  

    Changelog:

    • Added an effect boolean to the generate methods in the BlockGenerator class, to allow structures to generate with a nice effect!
    • Instead of making blank blocks air, it will make nothing occur. (Allows creation of better structures)
    • Added in a generate with time method that generates each layer at a certain amount of time asynchronously.
    Also, it's a very short class file which is a bonus! :)
     
    Plo124 and TryB4 like this.
  2. Offline

    XgXXSnipz

    Thanks!
     
    AstramG likes this.
  3. Offline

    TryB4

    AstramG
    that's cool :)


    EDIT:
    Maybe add a method which slowly generates layers? :)
     
    AstramG likes this.
  4. Offline

    AstramG

    You could add that in your plugin easily by doing BlockLayer.generate I think. But it requires a location. My next goal was to create the structure from a midpoint, instead of the start location.

    TryB4 Alright, I took your message into consideration and added that in to the class! I've edited the BlockGenerator class to include it!

    Here is a BlockGenerator for how to generate the beginnings to an entire house! It's sort of like a tunnel house but it is pretty cool!
    Code:java
    1. new BlockGenerator(
    2.  
    3. new BlockLayer("WWWWWWWWWWWWWWWW;"
    4. + "WWWWWWWGGGWWWWWW;"
    5. + "WWWWWWWGSGWWWWWW;"
    6. + "WWWWWWWGGGWWWWWW;"
    7. + "WWWWWWWWWWWWWWWW;")
    8. .setBlockType('W', Material.WOOD)
    9. .setBlockType('G', Material.GLASS)
    10. .setBlockType('S', Material.GLOWSTONE),
    11.  
    12. new BlockLayer("WWWWWWWWWWWWWWWW;"
    13. + "WAAAAAAAAAAAAAAW;"
    14. + "WAAAAAAAAAAAAAAW;"
    15. + "WAAAAAAAAAAAAAAW;"
    16. + "WWWWWWWWWWWWWWWW;")
    17. .setBlockType('W', Material.WOOD),
    18.  
    19. new BlockLayer("WWWWWWWWWWWWWWWW;"
    20. + "WAAAAAAAAAAAAAAW;"
    21. + "DAAAAAAAAAAAAAAW;"
    22. + "WAAAAAAAAAAAAAAW;"
    23. + "WWWWWWWWWWWWWWWW;")
    24. .setBlockType('W', Material.WOOD)
    25. .setBlockType('D', Material.WOOD_DOOR),
    26.  
    27. new BlockLayer("WWWWWWWWWWWWWWWW;"
    28. + "WTAAAAAAAAAAAAAW;"
    29. + "DAAAAAAAAAAAAATW;"
    30. + "WTAAAAAAAAAAAAAW;"
    31. + "WWWWWWWWWWWWWWWW;")
    32. .setBlockType('W', Material.WOOD)
    33. .setBlockType('D', Material.WOOD_DOOR)
    34. .setBlockType('T', Material.TORCH),
    35.  
    36. new BlockLayer("WWWWWWWWWWWWWWWW;"
    37. + "AAAAAAAAAAAAAAAW;"
    38. + "AAAAAAAAAAAAAAAW;"
    39. + "AAAAAAAAAAAAAAAW;"
    40. + "WWWWWWWWWWWWWWWW;")
    41. .setBlockType('A', Material.WOOD))
    42.  
    43. .generateWithTime(this, player.getLocation().subtract(1, 1, 1), 100L);


    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
Thread Status:
Not open for further replies.

Share This Page