salvestrom Posted February 16, 2017 Posted February 16, 2017 The spoiler code below is something I found in another thread (the poster said it was diesenben's). i added the height check. the goal is to replace all the stone below half the terrain height with something else. This all works, with one annoying issue: the returned y location from getHeightValue is including leaves and trees. i was expecting/would like the height value to be the "ground" so to speak. All paths lead to Rome, that I've found, i.e calling event.getWorld().getHeight(stuff) ultimately calls getHeightValue in the chunk class. Reveal hidden contents @SubscribeEvent public void blockSwap(PopulateChunkEvent.Pre pce) { Chunk chunk = pce.getWorld().getChunkFromChunkCoords(pce.getChunkX(), pce.getChunkZ()); Block tobeReplaced = Blocks.STONE; for (ExtendedBlockStorage storage : chunk.getBlockStorageArray()) if(storage != null) { { for (int x = 0; x < 16; ++x) { for (int y = 0; y < 16; ++y) { for (int z = 0; z < 16; ++z) { int a = chunk.getHeightValue(x, z) / 2; //pce.getWorld().getHeight(pce.getChunkX()*16 + x, pce.getChunkZ()*16 + z)/2; if (storage.get(x, y, z) == tobeReplaced.getDefaultState() && storage.getYLocation() + y < a) { storage.set(x, y, z, Blocks.SANDSTONE.getDefaultState()); } } } } } } chunk.setModified(true); // this is important as it marks it to be saved } Quote
Animefan8888 Posted February 16, 2017 Posted February 16, 2017 Just create a method yourself that takes in a x and z and iterate from y = 0 to the height you want. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
Draco18s Posted February 16, 2017 Posted February 16, 2017 Actually, iterate from world.getSeaLevel (world.provider.getSeaHeight? Something along those lines) upwards. There's no need to check from 0 to 60 in the overworld. You know those are going to be stone, air, or water. And look for areas with sunlight > 5 or so. And look for the last stone, sand, gravel, or dirt block (looking for grass won't help, because it'll just iterate up the trunk of a tree) before finding sunlight. Alternatively you could use the value returned by getHeightValue and iterate downwards until you find sand/grass/dirt/stone/water/lava. That'll get you the best result, I think. You could also check all adjacent blocks to the column being searched and if any meet the criteria for "what is ground" and average the result. Note: vertical cave entrances will give slightly wonky values because their "surface" point will be below the surrounding area, but this may not be a big deal. Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
salvestrom Posted February 16, 2017 Author Posted February 16, 2017 public int findGroundHeight(int x, int y, int z, Chunk chunk, ExtendedBlockStorage storage, Block toRemove, Block toPlace) { int cy = chunk.getHeightValue(x, z); while(chunk.getWorld().getBlockState(new BlockPos(chunk.xPosition * 16 + x, cy, chunk.zPosition * 16 + z)) != toRemove.getDefaultState()) { cy = cy - 1; } return cy; } i'm using the above atm, calling the method from the op code at the "int a = " line. although, as draco noted, exposed tunnels and ravines throw things off, it works to ignore trees. however, the terrain eventually stops loading and is alittle laggy even before that. i appreciate that what i'm doing is going to slow things down alot, so i'm more interested in whats causing the terrain to just give up. even after reloading the same region will lock up. Quote
Draco18s Posted February 16, 2017 Posted February 16, 2017 So, a couple things. chunk.getWorld().getBlockState(...) This can be better. Option 1: store the result of chunk.getWorld() to a local variable and use world.getBlockState() Option 2: skip the world object and use chunk.getBlockState() new BlockPos(...) Don't do this. BlockPos objects are (sort of) mutable. Use a local variable and pos = pos.down() instead. Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
salvestrom Posted February 17, 2017 Author Posted February 17, 2017 Reveal hidden contents public int findGroundHeight(int x, int y, int z, Chunk chunk, ExtendedBlockStorage storage, Block toRemove, Block toPlace) { int cy = chunk.getHeightValue(x, z); BlockPos pos = new BlockPos(chunk.xPosition * 16 + x, cy, chunk.zPosition * 16 + z); while(chunk.getBlockState(pos) != toRemove.getDefaultState()) { pos = pos.down(); } return pos.getY(); } The method is now as above. This helped a little with the load time, but did not resolve the locking up. i disabled the code and reloaded the world to determine what is in the region. an extreme hills biome. a large, tall one. but i figure if the game is checking the entirety of every loading chunk its not going to matter what that chunk contains. i keep wondering if some special circumstance is causing the while() statement to get stuck in an infinite loop. the method in the op already has a null check on the ExtendedBlockStorage, so it's not that. hmm. perhaps i shall try throwing in a break if y < 0... Quote
salvestrom Posted February 17, 2017 Author Posted February 17, 2017 Adding pos.getY() > 0 to the while statement allowed the extreme hills to load, and after 5 min roaming have yet to find another area that locked the game up. the only thing i can think of, bizarre as it sounds, is that some column in a chunk contained no stone, allowing the while loop to go all the way down to bedrock and on into the void. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.