Block Data Querying

Hey all,

I am trying to port Flobi’s plugin called WhatIsIt to Sponge:
http://dev.bukkit.org/bukkit-plugins/whatisit/

The way what is it works is a player either looks at an object or hold an item in their hand. The plugin looks up a name based on the ID of the object that the player is holding or looking at.

Based on a conversation a few months ago, I was told that I could not get the data value of the item that the player was holding (1 for stone, 1:1 for granite, 89 for glowstone, etc.)

Is there a good way for me to implement Flobi’s plugin into Sponge? Sponge’s lack of a way to get the Minecraft entity value seems like a major shortcoming.

Thanks

Quite the opposite - it’s the way that Mojang are going and so including them is a major shortcoming. They are removing these static numeric IDs, all blocks have a string that represents them now - for example, Stone is “minecraft:stone”. Why add something to the API which is going away in the first place?

Have a look at https://docs.spongepowered.org/en/plugin/blocks/concepts.html for more on this. I imagine you’d also be interested in https://docs.spongepowered.org/en/plugin/items/index.html - this should give you more info on how things work in Sponge.

Finally - I imagine the following methods would be of interest to you:

Sponge.getRegistry().getAllOf(ItemType.class);
Sponge.getRegistry().getAllOf(BlockType.class);

These will return collections of all the Item types and Block types that are registered in the game, and you should be able to get the string IDs (which corresponds to the old numeric ID) and the traits (some of which used to be represented by damage values). Hopefully, this should be able to help you, I don’t think the Sponge devs will expose the numeric IDs that you ask for.

You CAN get it:

https://forums.spongepowered.org/t/how-to-get-block-variant

And for non-blocks:

https://forums.spongepowered.org/t/finding-the-variant-of-non-block-itemtype

But I agree with @dualspiral that you probably don’t want to (and the method I used there might not be supported for much longer). Only reason I did it that way was because of the way my plugin is set up.

Don’t forget that BlockStates are CatalogTypes as well, so you can do:

Sponge.getRegistry().getAllOf(BlockState.class);

An example gist of where I printed some out:

2 Likes

Thank you so much gabizou! That will be super helpful!

Hey Gabizou,

Thanks for your help. It has been tremendous! I have a question. How would I get the color of a block of wool?

Thanks,
wazupwiop

You can get ColoredData or Keys.COLOR from the wool BlockState.

Yeah, I need to get the human readable color name. I did not see any way to really do that.

Also, I don’t see any way to get the color from the item in someone’s inventory. Is there any way to translate the item to a BlockState with the same color value? I saw a method called getDefaultBlockstate or something like that, but when I used it, it always returned white.

Just use ItemStack.get() instead of BlockState.get().

Here’s some code I used in Bukkit* to convert an enum name (like DARK_RED, input is case-insensitive) to a human-readable name (“Dark Red”):

public static String toReadableName(String enumLikeName) {
   boolean uppercase = true;
   StringBuilder out = new StringBuilder(enumLikeName.length());
   for (char c : enumLikeName.toCharArray()) {
      if (Character.isLetter(c)) {
         if (uppercase) {
            c = Character.toUpperCase(c);
            uppercase = false;
         } else {
            c = Character.toLowerCase(c);
         }
      } else if (c == '_') {
         c = ' ';
         uppercase = true;
      }
      out.append(c);
   }
   return out.toString();
}

Call it like this:
String text = toReadableName(dyeColor.getId());

* The original took an `Enum` object; I modified it when posting to take a `String` instead.

Whatever happened to using dyeColor.getName()? There’s more than just the id of a CatalogType.

It doesn’t seem to do anything except return getId().

I have tried a few ways to get the color value from an itemstack. Every time I try to use Keys.Color, I get a “No value present” error. Any ideas? Here is some code I am using:


First I tried this:
itemStack.get(Keys.COLOR).get().equals(Color.WHITE)

Then I tried this:
itemStack.getValue(Keys.COLOR).get().get().equals(Color.WHITE)

I am trying this with a white-wool item stack. Both of these commands give the following error:

No value present
at java.util.Optional.get(Unknown Source) ~[?:1.8.0_73]
at WhatIsIt.NameFetcher.getItemName(NameFetcher.java:21)

It looks like the wool does not contain a color value… It’s kinda weird. IDK what to do.

Please, big text is annoying.

Use Keys.DYE_COLOR instead of Keys.COLOR
Note that calling the .get() method without first checking it’s present is a bad idea and that’s why you get an unhandled exception.
It’s best to check .isPresent() first, and if that returns false when you expect it to return true then that’s the error that you report.

Thanks for the feedback, Simon. I am aware that I should check the isPresent method. I am new to the DataAPI, and I am trying to figure out how everything works. I know that this code is not “production ready” yet.