Closed TheMelonHead286 closed 3 months ago
Hi, you appear to be doing some string manipulations that are not necessary and end up creating invalid block states which are discarded by Minecraft when the schematic is loaded.
The code below is untested and incomplete, but should be enough to illustrate what I mean.
I hope it all helps.
When you call Region.getblock()
, you get a BlockState
object as a result. You can use it directly, you do not need to create new one.
from litemapy import Region, BlockState, Schematic
schematic = Schematic.load("...")
region = list(schematic.regions.values())[0]
# Be careful with the width, height and length, they might be negative, and so can block coordinates.
new_region = Region(0, 0, 0, region.width, region.height, region.length)
save_schematic = new_region.as_schematic(...)
for x, y, z in region.allblockpos():
state = region.getblock(x, y, z)
new_region.setblock(x, y, z, state)
# You don't need to call updatemeta, it is done automatically for you by default.
save_schematic.save(...)
Or, with the latest version of Litemapy (0.9.0b0):
from litemapy import Region, BlockState, Schematic
schematic = Schematic.load("...")
region = list(schematic.regions.values())[0]
new_region = Region(0, 0, 0, region.width, region.height, region.length)
save_schematic = new_region.as_schematic(...)
for x, y, z in region.block_positions():
new_region[x, y, z] = region[x, y, z]
save_schematic.save(...)
I refer you to the documentation to understand how you can use Litemapy in more details.
You may also want to read a bit about Python object oriented programming if that's new to you, to understand how you can manipulate the objects from Litemapy.
RegBlock = Reg.getblock(x, y, z)
Block = RegBlock.blockid
NewReg.setblock(x, y, z, BlockState(f"{Block}"))
There are two problems here:
minecraft:oack_stairs
), and the block properties (e.g. facing=west
). When you create a new Block
variable from RegBlock.blockid
, you are getting a copy of that state's block id, which is a string. By creating a new BlockState
object from that variable alone, you are loosing all the information from the properties. This is why all your stairs are facing the same direction.BlockState(f"{Block}")
. This is not invalid by itself, but does not serve any purpose as your Block
variable is already a string.RegBlock = Reg.getblock(x, y, z)
Block = RegBlock.blockid
NewReg.setblock(x, y, z, BlockState(f"{RegBlock}"))
Using my console, I found that the block id and block states were fused together in one string.
No. The block id and block properties are stored together as separate fields within a BlockState
object. When you print that object to the console, you are forcing Python to convert it into a string, which it does by calling the __repr__
magic method Litemapy defines for BlockState
s. That method simply returns the usual string representation of block states you would use in commands (and other places).
The exact same thing happens when you use that variable in the format string. Since you pass that format string to the BlockState
constructor, you are creating a new state that has the full textual representation of the original block state as its id (e.g. minecraft:oak_stairs[facing=north]
). Since those ids are not valid for Minecraft, it discards the states when loading the schematic. That's why blocks disappear.
For context, I found this issue with a strange goal in mind, I wanted to take blocks from an existing litematica file into another litematica file, essentially fusing the two.
This was my first code attempt. It had the unwanted side-effect of removing the block state from all blocks to the litematica file it was pasted in...
My second attempt, however, because of how block states are formatted it failed. Using my console, I found that the block id and block states were fused together in one string.
My final attempt was to split them manually unfortunately I couldn't use a string as the basis of putting in the block data. Also here is the image of my console for the third attempt.
I was wondering if there is an easy way to have the block state carry over from getting the block from another litematica region. As putting in manually every state that a block could be would work, just extremely tedious.