Library Multiblock structures API - R1.3.1 - 18/10/16

Discussion in 'Resources' started by ShaneCraftDev, Aug 30, 2016.

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

    ShaneCraftDev

    Multiblock structures API

    release 1.3.1


    The following post is about a small library which adds support for multiblock structures for the Bukkit API and is not version dependent. The reason for posting is to help others who want to use multiblock structures in their plugin or are struggling with coming up with an alternate way of checking if a block is part of a multiblock structure. I couldn't find any posts about utilities for detecting multiblock structures on this forum, so here is one ;).

    Changelog
    Show Spoiler

    r.1.3.1 - 18/10/16 - even more materials
    - The API is updated with more defined, specific materials. Here is a list of all available materials: #list
    r.1.3 - 16/10/16 - more materials
    - MultiBlockPatterns now accept materials with block data, release 1.3 currently only provides different wool colors from within the API (it supports custom validators, though)

    r.1.2.1 - 04/09/16 - hotfix
    - Events no longer get triggerd multiple times when registering more than 1 multiblock

    r.1.2 - 02/09/16 - item support
    - Patterns now allow for items to be included
    - Assigning PatternEntity objects to use EntityType.DROPPED_ITEM will throw an exception, returns a message to use PatternItem objects instead
    r.1.1 - 01/09/16 - entity support
    - Patterns now allow for entities to be added
    r.1.0 - 30/08/16 - initial release



    API & Usage
    The API is completely open source and licensed under MIT, so it is free to use in any way, shape or form.
    A download is available on the following repository site: GITHUB
    This repository comes with an example plugin setup, but for an quick overview I've added an example of how to use the API below:

    ExampleMultiBlock.java
    Code:java
    1.  
    2. public class ExampleMultiBlock implements IMultiBlock {
    3.  
    4. @Override
    5. public void onActivate(Plugin plugin, Location location, Player player, MultiBlockActivationType activationType) {
    6. if (activationType == MultiBlockActivationType.CORE_PLACED) {
    7. // when all pattern blocks are present and the last block placed
    8. // is the core material block of the multiblock pattern, this block will run
    9.  
    10. player.sendMessage(ChatColor.GREEN + "Example multiblock constructed");
    11. } else if (activationType == MultiBlockActivationType.CORE_INTERACTED) {
    12. // when all pattern blocks, including the core material, are present
    13. // and the user interacts with the core material block
    14.  
    15. player.sendMessage(ChatColor.RED + "Interacted with example multiblock");
    16.  
    17. // Optionally you could check for a certain item to be used
    18. if (player.getInventory().getItemInMainHand().getType() == Material.LEVER) {
    19. // e.g. load custom gui
    20. }
    21. }
    22. }
    23.  
    24. @Override
    25. public MultiBlockPattern getMultiBlockPattern() {
    26. return new MultiBlockPattern(Material.WOOL, // optional parameter [patternFacing: {default: CARDINAL} ]
    27. // the cardinal parameter allows to check the pattern in any direction
    28. // or strict the pattern to face a certain one
    29.  
    30. // pattern objects are relative to the core block (WOOL Material)
    31. // NORTH: negative on Z-axis
    32. // EAST: positive on X-axis
    33. // SOUTH: positive on Z-axis
    34. // WEST: negative on X-axis
    35. new PatternBlock(Material.STONE, -2, 0, -2), // WEST - Y - NORTH
    36. new PatternBlock(Material.BRICK, 2, 0, -2), // EAST - Y - NORTH
    37. new PatternBlock(Material.WOOD, 2, 0, 2), // EAST - Y - SOUTH
    38. new PatternBlock(Material.COAL_BLOCK, -2, 0, 2) // WEST - Y - SOUTH
    39.  
    40. // r1.1 adds support for patterns with entities
    41. new PatternEntity(EntityType.CHICKEN, 0, 1, 0),
    42.  
    43. // r1.2 adds support for patterns with items
    44. new PatternItem(Material.BOWL, 0, 1, 0),
    45.  
    46. // r1.3 adds support for patterns with metadata
    47. // you can create a custom one using the IMaterial interface or
    48. // select a material from the SpecificMaterial enumerator
    49. new PatternBlock(SpecificMaterial.WOOL_RED, 0, -1, 0)
    50. );
    51. }
    52. }
    53.  


    ExamplePlugin.java
    Code:java
    1.  
    2. public class ExamplePlugin extends JavaPlugin {
    3.  
    4. @Override
    5. public void onEnable() {
    6. super.onEnable();
    7.  
    8. // must be registered on enable, this will initialize certain events
    9. MultiBlockFactory.INSTANCE.register(this, ExampleMultiBlock.class);
    10. }
    11. }
    12.  


    Ingame
    This is a small showcase of the first release of this library. The showcase is built from this commit, similar to the example above.



    The multiblock from the example is at most a 5x5x1 structure, in which the block materials are set to the corners of the build and the core (wool material) is located at the center. The core is what determines if the block is build accordingly. This is checked by interacting with or placing the core block.

    The pattern of the multiblock structure from the example is set to check in every cardinal direction(north, east, south and west), however this library does also support to make the pattern to be built in a certain cardinal direction. For instance you could have a multiblock structure have to be built facing the direction in which the sun/moon rises or sets, think of using sunflowers (sunflowers only face east) as biological energy to send a redstone signal or what ever you can come up with.

    Features
    Currently the API only supports right click interaction and placing the core block in the corresponding structure. Multiblock patterns can be forced to be build in a specific cardinal direction(north, east, south, west), default they will check every cardinal direction. Since release 1.3 it is possible to check for more specific materials. The API comes with some predefined custom materials which are present in-game, but are not directly registered in the Material enumerator (e.g. White Stained Glass Panes).

    Notes
    The library currently is in developmental stage and is currently more of a POC, for the next update I will try to add support for schematic files. Reading pattern blocks will not be that hard but somehow I will have to get the 'core' block from this file.

    Thanks for reading! If you have any tips or ideas to improve this API, please don't hesitate to ask or post below.
     
    Last edited: Oct 26, 2016
  2. Offline

    Zombie_Striker

    @ShaneCraftDev
    Seems like an interesting API, but what exactly to do mean by "multi block"? Can you post images, videos, gifs, ect. of what this plugin is meant to achieve?
     
  3. Offline

    ShaneCraftDev

    @Zombie_Striker
    Thanks for the suggestion, I have added a quick demo video.

    Essentially multiblock structures are meant to give a meaning to a certain built structure, it is most popular in Forge Mods where these multiblock structures are used to create some sort of machinery which has the potential for more in- and outputs for pumping fuels or sending/retrieving items to a tile entity, which in most cases is located at the core of the multiblock structure. The definition of a core is the block you will have to interact with to check for nearby required blocks (the structure) to determine if the structure was built correctly or make use of the tile entity.

    The purpose of this library is to create custom blocks or even something close to tile entities when used with a database. Currently I am writing a plugin which makes use of the enchantment table to enchant horse armors, but when a player interacts with a enchantment table, the enchantment GUI pops up and for this plugin I wrote a custom GUI instead. With this library I can determine when to use my custom GUI, just by checking for certain nearby blocks (I have used purpur blocks). If the multiblock structure was built as required, it will run the implemented method from my multiblock object in which I can open my custom GUI for the player who interacted with the enchantment table (in this scenario the enchantment table is the core block).
     
  4. @ShaneCraftDev This is extremely helpful especially since I needed this and really did not want to make my own. Thank you for sharing, I will be sure to use this!
     
  5. Offline

    ShaneCraftDev

    @bwfcwalshy
    Great! Any feedback or your personal user experience is highly appreciated.

    EDIT:

    Updated to r1.1.
    Patterns now support entities, as well as for each cardinal direction. Added changelog to main post for future updates.

    Updated to r.1.2.
    Patterns now support items.

    Updated to r.1.2.1
    Hotfix - Registering multiple multiblocks caused to trigger the registered events * [registered multiblock per plugin]
     
    Last edited: Sep 4, 2016
  6. Offline

    BramDeCreep

  7. Offline

    BramDeCreep

  8. Offline

    Zombie_Striker

    @BramDeCreep
    Please don't bump threads A) you did not create, and B) just to get the creator's attention. It has been less than one day.Give him some time.

    Also, we can't help you unless you tell us what is wrong. What is currently happening? What have you tried to fix the problem?
     
  9. Offline

    BramDeCreep

    Sorry, its my first time i comment on a site
    The problem is that nothing happens when i build the structure and nothing also happens when i interact with the core.
    I have Tried to change the blocks and the coordinates of them but nothing seems to work i also changed the core but still nothing happens there are no errors on eclipse and the plugin shows green on the server when i do /plugins
    I am using java 8
     
    Last edited: Oct 12, 2016
  10. Offline

    ShaneCraftDev

    @BramDeCreep
    Hi, I haven't really had any time to work with the Bukkit API nor will I have any time for a while, so I couldn't reply any earlier then now. I see you tried to implement the example I've posted on this forum and from the looks of it all that is necessary to register a multiblock is present. All I can think of right now is that you did not ship my API when exporting your plugin to a jar file. Are there any errors/exceptions in the console when you run the server with your plugin using this API? Mainly NoClassDefFoundError, which should point to missing a reference to any used class of my API.

    This API is version independent, however it was tested for mc 10.0.2. I might have made a mistake, but as far as I know all used functionalities are also present in older versions of Bukkit
     
  11. Offline

    BramDeCreep

    Yes i am having the NocClassDefFoundError.
    But i don't understand what i need to do now?
     
  12. Offline

    I Al Istannen

    @BramDeCreep
    What IDE do you use? How did you install the API? If you answer this, I can probably help you.
    Or you google what a NoClassDefFoundError is.
     
  13. Offline

    BramDeCreep

    I just got it fixed, i needed to export it as a runnable java file and extract the library's.
    Now i just want to know how to have colored wool or chiseled bricks as pattern blocks?
     
  14. Offline

    Zombie_Striker

    @BramDeCreep
    Looking at the source code, it seems he does not support durability yet.

    @ShaneCraftDev
    Can you add a feature to support blocks with different datas?
     
  15. Offline

    ShaneCraftDev

    @BramDeCreep
    I haven't thought about block metadata, good point.

    @Zombie_Striker
    I have added this feature, thanks for the request.

    Updated to r.1.3
    The API will work the same, but now accepts either Material or an instance of IMaterial for the MultiBlockPattern as coreblock, patternblock or patternitem. The API currently only supports different wool colors, I have yet to find all ways to check for different block data and keeping it Bukkit/MineCraft version independent (I am not sure if there are any blocks that have metadata that do not exist in other versions starting from 1.8 till now).
     
  16. Offline

    I Al Istannen

    @ShaneCraftDev
    Block#getData() should be okay. Yes, it is deprecated. But I don't know of any other method to distinguish andesite and normal stone for example.
     
  17. Offline

    ShaneCraftDev

    @I Al Istannen
    Yes, I have noticed that Block#getData is deprecated, unfortunately. I was surprised the materialdata object returned for carpet blocks does not use Wool as instance of materialdata. The returned block-data byte value can be mapped to an existing instance of DyeColor, and Wool objects only hold these objects for public access. To get the wool color from a carpet block I have to use the byte value of the block data, but I am not sure when they plan to remove this (or if they even will at all).
     
  18. Offline

    I Al Istannen

    @ShaneCraftDev
    I would still use the getData. I think it has been deprecated for a quite long time and it is the only real way I know.
    @Zombie_Striker any idea? You suggested it too :p
     
  19. @I Al Istannen @ShaneCraftDev @Zombie_Striker
    Now this is a bit confusing. Mostly because Spigot has failed to tell people how to use it. The answer is that you use MaterialData. If I wanted to set the colour of wool I'd do it like this:
    Code:java
    1. Block woolBlock = ...
    2. MaterialData woolData = woolBlock.getState().getData();
    3. ((Wool) woolData).setColor(DyeColor.RED);
    4. woolBlock.getState().setData((woolData));
    5. woolBlock.getState().update(true);
    Now, it should be noted that a couple blocks are missing from MaterialData, andesite, diorite and stone for example. So it's mostly a fail on Spigot's part.

    Also, side note, is BlockState#update() broken? Because I can't seem to get it to work..
     
  20. Offline

    ShaneCraftDev

    @AlvinB
    I am aware that I can do what you posted here above and is included in the latest version of this API (see WoolValidator.java), but I was surprised this does not work for carpet blocks, in MCP the materials for both of these blocks are the same. I have replaced the return value with the following:
    Code:java
    1.  
    2. DyeColor.getByWoolData(block.getData()) == dyeColor
    3.  


    But I am not sure if they plan to remove this in a later state of the API, as it has been marked as deprecated for quite some time now. Even DyeColor#getByWoolData is marked as deprecated.
     
  21. @ShaneCraftDev
    My guess is that Spigot has simply forgotten to implement/update this properly. The reason the old methods are deprecated is that Mojang decided that metadata was obsolete for blocks and decided to use what they call BlockStates (different from Bukkit's BlockStates). But knowing Bukkit, and it's backwards compatibility, I seriously doubt the old methods will ever be removed, so you should be fine using them. Although someone should really tell Spigot to fix this up.

    EDIT: Looking at the History on Spigot's stash, it seems these classes were created absolutely ages ago (14th of january 2011 in the case of the Wool.java) and the last real commit was on 19th of august 2013, which was before Spigot took over development of Bukkit, so it might be possible that Spigot aren't even aware this needs fixing.
     
    Last edited: Oct 18, 2016
    I Al Istannen likes this.
  22. Offline

    ShaneCraftDev

    @AlvinB
    Wow, that is really unfortunate. I've added new validators, and some of these are pretty dirty but there is no other way of checking for a certain condition (e.g. purpur block half-slabs are not registered in the Step enumerator).

    Updated to r.1.3.1
    The API now accepts more specific materials, below is a list of all added materials for release 1.3.1.
    Show Spoiler

    WOOL_WHITE
    WOOL_ORANGE
    WOOL_MAGENTA
    WOOL_LIGHT_BLUE
    WOOL_YELLOW
    WOOL_LIME_GREEN
    WOOL_PINK
    WOOL_GRAY
    WOOL_LIGHT_GRAY
    WOOL_CYAN
    WOOL_PURPLE
    WOOL_BLUE
    WOOL_BROWN
    WOOL_GREEN
    WOOL_RED
    WOOL_BLACK

    CARPET_WHITE
    CARPET_ORANGE
    CARPET_MAGENTA
    CARPET_LIGHT_BLUE
    CARPET_YELLOW
    CARPET_LIME_GREEN
    CARPET_PINK
    CARPET_GRAY
    CARPET_LIGHT_GRAY
    CARPET_CYAN
    CARPET_PURPLE
    CARPET_BLUE
    CARPET_BROWN
    CARPET_GREEN
    CARPET_RED
    CARPET_BLACK

    HARDENED_CLAY_WHITE
    HARDENED_CLAY_ORANGE
    HARDENED_CLAY_MAGENTA
    HARDENED_CLAY_LIGHT_BLUE
    HARDENED_CLAY_YELLOW
    HARDENED_CLAY_LIME_GREEN
    HARDENED_CLAY_PINK
    HARDENED_CLAY_GRAY
    HARDENED_CLAY_LIGHT_GRAY
    HARDENED_CLAY_CYAN
    HARDENED_CLAY_PURPLE
    HARDENED_CLAY_BLUE
    HARDENED_CLAY_BROWN
    HARDENED_CLAY_GREEN
    HARDENED_CLAY_RED
    HARDENED_CLAY_BLACK

    STAINED_GLASS_WHITE
    STAINED_GLASS_ORANGE
    STAINED_GLASS_MAGENTA
    STAINED_GLASS_LIGHT_BLUE
    STAINED_GLASS_YELLOW
    STAINED_GLASS_LIME_GREEN
    STAINED_GLASS_PINK
    STAINED_GLASS_GRAY
    STAINED_GLASS_LIGHT_GRAY
    STAINED_GLASS_CYAN
    STAINED_GLASS_PURPLE
    STAINED_GLASS_BLUE
    STAINED_GLASS_BROWN
    STAINED_GLASS_GREEN
    STAINED_GLASS_RED
    STAINED_GLASS_BLACK

    STAINED_GLASS_PANE_WHITE
    STAINED_GLASS_PANE_ORANGE
    STAINED_GLASS_PANE_MAGENTA
    STAINED_GLASS_PANE_LIGHT_BLUE
    STAINED_GLASS_PANE_YELLOW
    STAINED_GLASS_PANE_LIME_GREEN
    STAINED_GLASS_PANE_PINK
    STAINED_GLASS_PANE_GRAY
    STAINED_GLASS_PANE_LIGHT_GRAY
    STAINED_GLASS_PANE_CYAN
    STAINED_GLASS_PANE_PURPLE
    STAINED_GLASS_PANE_BLUE
    STAINED_GLASS_PANE_BROWN
    STAINED_GLASS_PANE_GREEN
    STAINED_GLASS_PANE_RED
    STAINED_GLASS_PANE_BLACK

    CAULDRON_EMPTY
    CAULDRON_USED_TWICE
    CAULDRON_USED_ONCE
    CAULDRON_FULL

    TALL_GRASS
    TALL_GRASS_FERN

    TALL_GRASS_STACKED
    TALL_GRASS_FERN_STACKED

    WOOD_OAK
    WOOD_BIRCH
    WOOD_SPRUCE
    WOOD_JUNGLE
    WOOD_DARK_OAK
    WOOD_ACACIA

    LOG_OAK
    LOG_BIRCH
    LOG_SPRUCE
    LOG_JUNGLE
    LOG_DARK_OAK
    LOG_ACACIA

    LOG_OAK_GENERATED
    LOG_BIRCH_GENERATED
    LOG_SPRUCE_GENERATED
    LOG_JUNGLE_GENERATED
    LOG_DARK_OAK_GENERATED
    LOG_ACACIA_GENERATED

    LEAVES_OAK
    LEAVES_BIRCH
    LEAVES_SPRUCE
    LEAVES_JUNGLE
    LEAVES_DARK_OAK
    LEAVES_ACACIA

    LEAVES_OAK_GENERATED
    LEAVES_BIRCH_GENERATED
    LEAVES_SPRUCE_GENERATED
    LEAVES_JUNGLE_GENERATED
    LEAVES_DARK_OAK_GENERATED
    LEAVES_ACACIA_GENERATED

    SAPLING_OAK_GENERATED
    SAPLING_BIRCH_GENERATED
    SAPLING_SPRUCE_GENERATED
    SAPLING_JUNGLE_GENERATED
    SAPLING_DARK_OAK_GENERATED
    SAPLING_ACACIA_GENERATED

    // slabs can be restricted to top, bottom or no side
    WOOD_SLAB_OAK
    WOOD_SLAB_OAK_DOWN
    WOOD_SLAB_OAK_UP

    WOOD_SLAB_BIRCH
    WOOD_SLAB_BIRCH_DOWN
    WOOD_SLAB_BIRCH_UP

    WOOD_SLAB_SPRUCE
    WOOD_SLAB_SPRUCE_DOWN
    WOOD_SLAB_SPRUCE_UP

    WOOD_SLAB_JUNGLES
    WOOD_SLAB_JUNGLE_DOWN
    WOOD_SLAB_JUNGLE_UP

    WOOD_SLAB_DARK_OAK
    WOOD_SLAB_DARK_OAK_DOWN
    WOOD_SLAB_DARK_OAK_UP

    WOOD_SLAB_ACACIA
    WOOD_SLAB_ACACIA_DOWN
    WOOD_SLAB_ACACIA_UP

    SLAB_STONE
    SLAB_STONE_DOWN
    SLAB_STONE_UP

    SLAB_SANDSTONE
    SLAB_SANDSTONE_DOWN
    SLAB_SANDSTONE_UP

    SLAB_COBBLESTONE
    SLAB_COBBLESTONE_DOWN
    SLAB_COBBLESTONE_UP

    SLAB_BRICK
    SLAB_BRICK_DOWN
    SLAB_BRICK_UP

    SLAB_SMOOTH_BRICK
    SLAB_SMOOTH_BRICK_DOWN
    SLAB_SMOOTH_BRICK_UP

    SLAB_QUARTZ
    SLAB_QUARTZ_DOWN
    SLAB_QUARTZ_UP

    SLAB_PURPUR
    SLAB_PURPUR_DOWN
    SLAB_PURPUR_UP

    usage:
    Code:java
    1.  
    2. // either use Material.[type] or SpecificMaterial.[type],
    3. // optionally you can create a custom object from an instance of nl.shanelab.multiblock.IMaterial
    4. new MultiBlockPattern(SpecificMaterial.HARDENED_CLAY_CYAN, new PatternBlock(SpecificMaterial.SLAB_STONE_UP, 0, 1, 0);
    5.  
     
  23. Offline

    PhantomUnicorns

    Your code says only wool colors, but your latest comment says all (if not most). Which one is true? :p And it's really nice XD
     
  24. Offline

    ShaneCraftDev

    @PhantomUnicorns
    1.3 Only support wool and custom ones, in 1.3.1. I have added support for more specific material types (my previous post has a list of all available materials). Thanks for pointing this possible confusion out, I've removed that sentence from the example code.
     
  25. Offline

    PhantomUnicorns

    Oh ok, I just was just making sure because it kind of bewildered me. Keep it up though, I really like it :D
     
Thread Status:
Not open for further replies.

Share This Page