anvil-parser icon indicating copy to clipboard operation
anvil-parser copied to clipboard

How to manipulate data?

Open alex4200 opened this issue 4 years ago • 5 comments

I want to use this module to manipulate data in an existing world, i.e. I want to do something like:

region = anvil.Region.from_file("r.0.0.mc")

# Create `Block` objects that are used to set blocks
dirt = anvil.Block('minecraft', 'dirt')

# Make a 16x16x16 cube of either stone or dirt blocks
for y in range(16):
    for z in range(16):
        for x in range(16):
            region.set_block(stone, x, y, z)

but that does not seem to be possible, as the region object is read only.

Can that be fixed please?

alex4200 avatar Jan 16 '21 12:01 alex4200

I wanted to ask the same question

GuillaudRemy avatar Mar 18 '21 18:03 GuillaudRemy

@GuillaudRemy Since I did not find any answer either I used the code of this repository as a basis in order to create a new repository which enables you to manipulate the data in a minecraft world:

https://github.com/alex4200/PyBlock

It is still in a draft version, but if you want to give it a try that would be great. And if you find some issues etc., please file a bug report.

That code not only allows you to manipulate data, but you can also search certain blocks, you can list all blocks in some certain area, and you can copy chunks even from different worlds in your world!

alex4200 avatar Mar 19 '21 06:03 alex4200

Thanks i will definitly check it out but i was trying to do it myself but i'm not familiar with this bytes reading how do i read those bytes string out cause i can't figure it out ?

GuillaudRemy avatar Mar 19 '21 20:03 GuillaudRemy

there isn't any easy way to convert a readonly Region or Chunk into its Empty counterpart, yet

matcool avatar Apr 17 '21 15:04 matcool

I don't understand why Region and EmptyRegion are completely separate classes, but I did find a workaround:

region_in = anvil.Region.from_file(region_name)
region_out = anvil.EmptyRegion(x, y)
for x in range(0, 32):
    for y in range(0, 32):
        try:
            chunk = anvil.Chunk.from_region(region_in, x, y)
            for tag in chunk.data.tags:
                if tag.name == 'Biomes':
                    tag.value = [biome_mapping.get(val, val) for val in tag.value]
                    break
            region_out.add_chunk(chunk)
        except ChunkNotFound:
            pass
region_out.save(region_name)

In this example i'm replacing all the biome IDs according to the biome_mapping dictionary. Definitely not the fastest since there is a lot of copying involved and about 1 million iterations per region, but it works in a pinch.

UncleThaodan avatar Jun 23 '21 12:06 UncleThaodan