minecraft-file-converter / scripts /make_world_samples.py
cpuai's picture
Deploy BlockBridge Minecraft file converter 2.1.0 with independent world conversion
7056f70 verified
Raw History Blame Contribute Delete
4.12 kB
"""生成含三维度、箱子、生物、本地玩家和地图的合成世界。"""
from pathlib import Path
import shutil,sys,tempfile,zipfile,uuid
import numpy as np
sys.path.insert(0,str(Path(__file__).resolve().parents[1]))
import amulet_nbt as n
from scripts.make_samples import sample_java
from converter.nbtio import compounds,doubles,floats,dump,ints
from converter.translate import Report
from converter.worlds import java_world,write_regions
from worldbridge.audit import region_records,java_dat
def make_java(root):
root=Path(root);scene=sample_java()
scene.entities=[n.CompoundTag({'id':n.StringTag('minecraft:pig'),'Pos':doubles((7.5,3,8.5)),
'Motion':doubles((0,0,0)),'Rotation':floats((0,0)),'Health':n.FloatTag(10),'Air':n.ShortTag(300),
'Fire':n.ShortTag(-1),'FallDistance':n.FloatTag(0),'OnGround':n.ByteTag(1),'PersistenceRequired':n.ByteTag(1),'Age':n.IntTag(0),'Saddle':n.ByteTag(0)})]
java_world(scene,root,Report(),offset=(-17,65,31),name='三维度测试世界')
for folder,biome,height in [('DIM-1','minecraft:nether_wastes',8),('DIM1','minecraft:the_end',16)]:
chunks=[]
for path in (root/'region').glob('*.mca'):
for pos,t in region_records(path):
t['sections']=compounds([s for s in t['sections'] if 0<=int(s['Y'])<height]);t['yPos']=n.IntTag(0)
for s in t['sections']:s['biomes']=n.CompoundTag({'palette':n.ListTag([n.StringTag(biome)])})
chunks.append((pos,t))
write_regions(root/folder/'region',chunks)
entity_chunks=[]
for path in (root/'entities').glob('*.mca'):
for pos,t in region_records(path):
for entity in t['Entities']:entity['UUID']=n.IntArrayTag(np.frombuffer(uuid.uuid4().bytes,dtype='>i4'))
entity_chunks.append((pos,t))
write_regions(root/folder/'entities',entity_chunks)
def item(name,count,slot,components=None):
t=n.CompoundTag({'id':n.StringTag('minecraft:'+name),'count':n.IntTag(count),'Slot':n.ByteTag(slot)})
if components:t['components']=components
return t
tag=java_dat(root/'level.dat');tag['Data']['Player']=n.CompoundTag({
'UUID':n.IntArrayTag([123456,123456,123456,123456]),'Pos':doubles((-20.5,69,33.5)),
'Motion':doubles((0,0,0)),'Rotation':floats((0,0)),'Dimension':n.StringTag('minecraft:overworld'),
'Health':n.FloatTag(20),'Air':n.ShortTag(300),'Fire':n.ShortTag(-1),'OnGround':n.ByteTag(1),
'foodLevel':n.IntTag(20),'foodSaturationLevel':n.FloatTag(5),'XpLevel':n.IntTag(7),'XpP':n.FloatTag(.25),'XpTotal':n.IntTag(100),
'playerGameType':n.IntTag(1),'SelectedItemSlot':n.IntTag(0),'abilities':n.CompoundTag({'mayfly':n.ByteTag(1),'instabuild':n.ByteTag(1),'invulnerable':n.ByteTag(1),'flying':n.ByteTag(0),'mayBuild':n.ByteTag(1),'walkSpeed':n.FloatTag(.1),'flySpeed':n.FloatTag(.05)}),
'Inventory':compounds([item('diamond',4,0),item('diamond_sword',1,1,n.CompoundTag({'minecraft:enchantments':n.CompoundTag({'levels':n.CompoundTag({'minecraft:unbreaking':n.IntTag(3)})})})),item('filled_map',1,2,n.CompoundTag({'minecraft:map_id':n.IntTag(0)}))]),
'EnderItems':compounds([item('emerald',2,0)])})
dump(tag,root/'level.dat',compressed=True);(root/'data').mkdir(exist_ok=True)
dump(n.CompoundTag({'DataVersion':n.IntTag(4189),'data':n.CompoundTag({'dimension':n.StringTag('minecraft:overworld'),'scale':n.ByteTag(0),'xCenter':n.IntTag(0),'zCenter':n.IntTag(0),'trackingPosition':n.ByteTag(1),'unlimitedTracking':n.ByteTag(0),'locked':n.ByteTag(0),'colors':n.ByteArrayTag([0]*16384)})}),root/'data/map_0.dat',compressed=True)
return root
def pack(root,path):
with zipfile.ZipFile(path,'w',zipfile.ZIP_DEFLATED) as z:
for f in sorted(Path(root).rglob('*')):
if f.is_file():z.write(f,'ThreeDimensions/'+f.relative_to(root).as_posix())
if __name__=='__main__':
out=Path(__file__).resolve().parents[1]/'samples'
with tempfile.TemporaryDirectory() as tmp:pack(make_java(Path(tmp)/'world'),out/'world-java.zip')
print(out/'world-java.zip')