Jump to content

[1.11.2] swapping blocks in a chunk issue


salvestrom

Recommended Posts

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.

Spoiler

	@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
	}

 

 

Link to comment
Share on other sites

Just create a method yourself that takes in a x and z and iterate from y = 0 to the height you want.

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.

Link to comment
Share on other sites

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.

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.

Link to comment
Share on other sites

	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.

Link to comment
Share on other sites

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.

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.

Link to comment
Share on other sites

Spoiler

	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...

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.