Finding blocks in a rendered world

Discussion in 'Spigot Plugin Development' started by spinnekoppie, May 16, 2016.

  1. Hi Folks
    I downloaded a world from planetminecraft but I now want to find all blocks of a certain type, eg. all diamond blocks. What would be the most sensible way to go about this? Is there a plugin or maybe a vanilla command that could give me such information or would I have to write my own code? If I have to write my own code, how do I determine which chunks have been rendered?

    I hope I have explained myself clearly. If not please just ask and I'll try to rephrase.
  2. Why would you need to do this? Also, just get the chunk, and check block types/materials.
  3. Why I want to do this is not really relevant. I'm busy with a plugin that requires it. I know how to get chunks and get block types. That is exactly what I want to do but how do I know which chunks already exist in the world?
  4. getLoadedChunks();
  5. Code (Text):

      // do something
    Something, in this case, would probably be several nested for loops, iterating over all the 16x16xHEIGHT blocks and checking the types, as MineOrity suggested.
  6. Uhhh, no.

    for (Chunk c : world.getLoadChunks()) {
    //get the materials/blocks here
  7. They asked how to tell if the already defined chunk is loaded, not how to get a list of all loaded chunks. While it is possible to determine if the specific chunk is within that array, it seems rather bulky to me.
  8. I did actually look at getLoadedChunks, but then I came to think that it would only be returning the chunks that are loaded at the time of play and not ALL the rendered chunks in the world. (I'm not sure if my use of the term "rendered" is correct). My understanding is that chunks are only loaded when players enter those chunks.

    Ah, I just thought of something that I should probably explain. I need to find these blocks that I want as part of my preparation of the world. I need to identify them before I allow players to play. So I am not trying to find the blocks "on the fly" while players are playing. I want to know exactly where in the world these blocks are because during the game I want to be able to detect when players find them. I am using a pre-rendered world that I downloaded, so all the blocks are already in place but I need to make a list of them and thus need to know where the world ,as it stands, starts and ends so that I can log where the blocks are before play starts. This program seems to do what I want to do: However it is quite old and seems to only work with a local world. Before going into the source of the program I thought I'd ask because I thought what I wanted was a fairly simple concept that could be answered in a sentence or two. If this is not the case I'll start digging in Blockfinder's code and hope it does what I think it does.

    BTW, I wasn't thinking of writing a separate program such as blockfinder. My idea was just to op my player, run a command that finds the blocks and writes the information to a file.
  9. Are you trying to get ALL chunks, just loaded ones, or what? WHAT EXACTLY ARE YOU TRYING TO DO? You keep re-wording it and it fucking confuses me.
  10. Assuming you know the size in chunks (or blocks, I guess) of the world, you can use loops to iterate over each chunk x,z position until the limit of your world size is reached, using world.getChunkAt(x, z) to get the chunk. Then, inside that chunk, you can do the same thing with the blocks, to check the type. As I believe you are aware, you'll want to load the chunk if it isn't loaded [see above chunk.isLoaded()] before checking the blocks. I believe this is as simple as chunk.load() .. this will be a very intensive process but you can also unload (chunk.unload()) the chunk once you're done with it and have cached the location information of the diamond blocks.
    The above is really only possible if you have the constraints of the world, since new chunks can be generated and the process would go on forever, but it seems to me you would have this information.
  11. It is fairly clear that they want to record the location of all the diamond blocks in a prebuilt world, so presumably not newly generated chunks.
  12. Thinking of it now.. since you said you want to know when a player finds the block.. do you mean literally interacts with it? Because that would be so much simpler. Or do you mean when they get near it.. thus requiring the pre-caching?
  13. If it frustates you so much that you have to resort to foul language then please don't try to help me. Though I do appreciate your time and effort. I am rewording because I'm trying to make clear what I want. Jagarti seems to get my point.
  14. In my plugin I take action when a player breaks a block of the specified type. But this doesn't really matter for what I need. I need to know beforehand where the blocks are. As a matter of fact I place the blocks where I want them before the games starts but because this is a pre-built world it has blocks (of the type I want) placed in places that I don't know of. So I need to find them to take note of their location or remove them if I don't want them there.
    However, I think you shed light on the problem in the previous post. I don't know what the constraints of the world are because I didn't create the world. I downloaded it and it was created by someone else. How can I determine what the constraints of the world are? Then I could probably do what you suggested before.
  15. "resort to foul language" I am struggling to hold back right now.
  16. That's good. I shows some restraint. Thank you.
  17. Just incase you are unaware, you can check a block's type when it is broken by a player with BlockBreakEvent but if you absolutely must check all the blocks at some point, find the lowest/highest chunk X/Z coordinates of what has already been built. You can do this in-game with the F3 overlay (that shows FPS and block location and all that other debugging info.. chunk coords are in there, too). Then, you'll need some fairly active loops. I'm not normally in the habit of doing this but I just threw together an example method. It's not complete or tested but I think it'll get you on the way.

    Code (Text):
    public void foo(World world){
            int lowestChunkX = 10;
            int highestChunkX = 99;
            int lowestChunkZ = 23;
            int highestChunkZ = 234;
            for(int x = lowestChunkX; x <= highestChunkX; x++){
                for(int z = lowestChunkZ; z <= highestChunkZ; z++){
                    Chunk chunk = world.getChunkAt(x, z);
                    if(!chunk.isLoaded()) chunk.load();
                    for(int blockX = 0; blockX < 16; blockX++){
                        for(int blockY = 0; blockY < world.getMaxHeight(); blockY++){
                            for(int blockZ = 0; blockZ < 16; blockZ++){
                                Block block = chunk.getBlock(blockX, blockY, blockZ);
                                if(block.getType() == Material.DIAMOND_BLOCK){
                                    // you found one!
    Those integers there are just examples.
    And don't let him bother you. Some people only try to help to attempt to prove their superiority.
    #17 Jagarti, May 16, 2016
    Last edited: May 16, 2016
  18. This is marvellous. I'm going to give it a go. Thank you so much. I have to admit. I'm fairly new to the game. I started in March this year after promising my son for the last few years that I would give it a go as soon as I finished PhD. So the weekend after I submitted I started playing and then came up with an idea for a plugin. So I'm trying to write the plugin, learning the API and learning the game at the same time. It is quite overwhelming as there is so much to this game now that it will probably take a lifetime to understand it all - by which time it all probably changed or became more complicated !

    I noticed ...
  19. You're quite welcome. We all start somewhere. Traditionally, people nag and nag and say read the JavaDocs, figure it out yourself, etc... but if you're like me, you learn better in a practical manner. If you care enough about what you're doing, being "spoon-fed" isn't bad, because you'll learn what's actually happening and grow from there. Bukkit/Spigot isn't all that complicated once you're used to it, things can get more complicated when you start to hook into the classic Minecraft server, in case you ever go there.

    I edited the method because of a misplaced variable, after your reply, it seems, so if you directly copied it, you may want to take the new edition for a test run.
    #19 Jagarti, May 16, 2016
    Last edited: May 16, 2016
  20. It doesn't take a lifetime, but certainly a lot of time. If you are new to the game and want to learn about some more specific things I recommend you to keep up with the change logs and watch some videos of what happened within an update (if an update comes out of course). You can also use this website Almost everything is on there with all sorts of information and gets updated to the newest version before an update is even out. Also take a look at the spigot javadocs and the methods they have. There is also a small description on there what different things represent. Do note that note everything is supported by spigot/craftbukkit and that you may want to do some tests in order to see what's actually happening. For example I can't see if a chunk is a lazy chunk at the moment. Would a lazy chunk be represented as loaded or not. Those are things you probably want to test, because there isn't a method to see the state of the chunk other than loaded or unloaded. Overall just have fun learning, it's quite overwhelming at first, but you don't have to know every aspect of the game. If you don't need to know how to do certain tings or how certain things work, it's fine. And if you want to learn about it than look up some information or videos. Just learn what you need to at first and later on you can learn other stuff (of course that doesn't mean that you shouldn't have any knowledge on java or spigot. You always need the basics and I encourage everyone to know them. However if it's not important for you how to work with doors for example that's totally fine).