Add KeyedVectorAttr, make adapter.metadata accessible through WorldEditor
Add AnvilWorldMetadata.Spawn Add KeyedVectorAttr, used for Spawn and TileEntity Position Remove get/setWorldSpawnPosition
This commit is contained in:
parent
123b4ea063
commit
168bbfa563
@ -693,7 +693,7 @@ class EditorSession(QtCore.QObject):
|
||||
pass
|
||||
except PlayerNotFound:
|
||||
try:
|
||||
center = self.worldEditor.worldSpawnPosition()
|
||||
center = self.worldEditor.getWorldMetadata().Spawn
|
||||
log.info("Centering on spawn position.")
|
||||
except AttributeError:
|
||||
log.info("Centering on world center")
|
||||
|
@ -90,7 +90,7 @@ class WorldInfoPanel(QtGui.QWidget):
|
||||
self.generatorSeedLineEdit.setText(str(self.worldMeta.RandomSeed))
|
||||
self.generatorOptionsLineEdit.setText(self.worldMeta.generatorOptions)
|
||||
|
||||
sx, sy, sz = self.worldMeta.worldSpawnPosition()
|
||||
sx, sy, sz = self.worldMeta.Spawn
|
||||
self.spawnX.setValue(sx)
|
||||
self.spawnY.setValue(sy)
|
||||
self.spawnZ.setValue(sz)
|
||||
@ -201,7 +201,7 @@ class WorldInfoPanel(QtGui.QWidget):
|
||||
|
||||
command = WorldMetaEditCommand(self.editorSession, self.tr('Change Spawn Coordinates'))
|
||||
with command.begin():
|
||||
self.worldMeta.setWorldSpawnPosition(self.spawnX.value(), self.spawnY.value(), self.spawnZ.value())
|
||||
self.worldMeta.Spawn = self.spawnX.value(), self.spawnY.value(), self.spawnZ.value()
|
||||
self.editorSession.pushCommand(command)
|
||||
|
||||
def timeChanged(self):
|
||||
|
@ -384,7 +384,7 @@ class WorldListWidget(QtGui.QDialog):
|
||||
log.info("Centering on single-player player.")
|
||||
except PlayerNotFound:
|
||||
try:
|
||||
center = worldEditor.worldSpawnPosition()
|
||||
center = worldEditor.getWorldMetadata().Spawn
|
||||
log.info("Centering on spawn position.")
|
||||
except AttributeError:
|
||||
log.info("Centering on world center")
|
||||
|
@ -374,25 +374,20 @@ class AnvilWorldMetadata(object):
|
||||
|
||||
version = nbtattr.NBTAttr('version', nbt.TAG_Int, VERSION_ANVIL)
|
||||
|
||||
def worldSpawnPosition(self):
|
||||
return Vector(*[self.rootTag[i].value for i in ("SpawnX", "SpawnY", "SpawnZ")])
|
||||
|
||||
def setWorldSpawnPosition(self, pos):
|
||||
for name, val in zip(("SpawnX", "SpawnY", "SpawnZ"), pos):
|
||||
self.rootTag[name] = nbt.TAG_Int(val)
|
||||
Spawn = nbtattr.KeyedVectorAttr('SpawnX', 'SpawnY', 'SpawnZ', nbt.TAG_Int)
|
||||
|
||||
def is1_8World(self):
|
||||
# Minecraft 1.8 adds a dozen tags to level.dat/Data. These tags are removed if
|
||||
# the world is played in 1.7 (and all of the items are removed too!)
|
||||
# Use some of these tags to decide whether to use 1.7 format ItemStacks or 1.8 format ones.
|
||||
# In 1.8, the stack's "id" is a string, but in 1.7 it is an int.
|
||||
tags = (t in self.rootTag for t in (
|
||||
# In 1.8, the stack's "id" is a TAG_String, but in 1.7 it is a TAG_Short.
|
||||
tags = (
|
||||
'BorderCenterX', 'BorderCenterZ',
|
||||
'BorderDamagePerBlock',
|
||||
'BorderSafeZone',
|
||||
'BorderSize'
|
||||
))
|
||||
return any(tags)
|
||||
)
|
||||
return any(tag in self.rootTag for tag in tags)
|
||||
|
||||
class AnvilWorldAdapter(object):
|
||||
"""
|
||||
|
@ -63,15 +63,7 @@ class PCTileEntityRefBase(object):
|
||||
return self.rootTag
|
||||
|
||||
id = nbtattr.NBTAttr("id", nbt.TAG_String)
|
||||
|
||||
@property
|
||||
def Position(self):
|
||||
return Vector(*[self.rootTag[c].value for c in 'xyz'])
|
||||
|
||||
@Position.setter
|
||||
def Position(self, pos):
|
||||
for a, p in zip('xyz', pos):
|
||||
self.rootTag[a] = nbt.TAG_Int(p)
|
||||
Position = nbtattr.KeyedVectorAttr('x', 'y', 'z', nbt.TAG_Int, 0)
|
||||
|
||||
def copy(self):
|
||||
return self.copyWithOffset(Vector(0, 0, 0))
|
||||
|
@ -356,7 +356,7 @@ class MCServerChunkGenerator(object):
|
||||
|
||||
def generateAtPositionIter(self, tempWorld, tempDir, cx, cz, simulate=False):
|
||||
tempWorldRW = worldeditor.WorldEditor(tempWorld.filename)
|
||||
tempWorldRW.setWorldSpawnPosition((cx * 16, 64, cz * 16))
|
||||
tempWorldRW.getWorldMetadata().Spawn = cx * 16, 64, cz * 16
|
||||
tempWorldRW.saveChanges()
|
||||
tempWorldRW.close()
|
||||
del tempWorldRW
|
||||
|
@ -275,6 +275,37 @@ class NBTVectorAttr(NBTListAttr):
|
||||
return Vector(*val)
|
||||
|
||||
|
||||
class KeyedVectorAttr(object):
|
||||
"""
|
||||
This attr is useful when a Vector is represented as a trio of named tags in a compound
|
||||
instead of as a list of tags. For example, the world spawn position (SpawnX, SpawnY,
|
||||
SpawnZ) and a TileEntity's position (x, y, z).
|
||||
"""
|
||||
def __init__(self, xKey, yKey, zKey, tagType, default=None):
|
||||
self.tagType = tagType
|
||||
self.default = default
|
||||
self.keys = xKey, yKey, zKey
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
tag = instance.rootTag
|
||||
for key in self.keys:
|
||||
if key not in tag:
|
||||
tag[key] = self.tagType(value=self.default)
|
||||
|
||||
return Vector(*[tag[k].value for k in self.keys])
|
||||
|
||||
def __set__(self, instance, value):
|
||||
tag = instance.rootTag
|
||||
for key, val in zip(self.keys, value):
|
||||
if key not in tag:
|
||||
tag[key] = self.tagType(val)
|
||||
else:
|
||||
tag[key].value = val
|
||||
|
||||
instance.dirty = True
|
||||
|
||||
|
||||
|
||||
def SetNBTDefaults(ref):
|
||||
"""
|
||||
Given an object whose class has several members of type `NBT[*]Attr`,
|
||||
|
@ -529,21 +529,21 @@ class WorldEditor(object):
|
||||
if self._allChunks is not None:
|
||||
self._allChunks[dimName].discard((cx, cz))
|
||||
|
||||
# --- Player and spawn manipulation ---
|
||||
# --- World metadata ---
|
||||
|
||||
def worldSpawnPosition(self):
|
||||
def getWorldMetadata(self):
|
||||
"""
|
||||
Return the world's default spawn position.
|
||||
"""
|
||||
return self.adapter.metadata.worldSpawnPosition()
|
||||
Return an object containing global info about the world.
|
||||
|
||||
def setWorldSpawnPosition(self, pos):
|
||||
"""
|
||||
Change the world's default spawn position.
|
||||
Different level formats can return different objects for the world metadata.
|
||||
At the very least, you can expect the object to have Spawn and Seed attributes.
|
||||
|
||||
:param pos: (x, y, z) coordinates
|
||||
Currently, only AnvilWorldMetadata is ever returned.
|
||||
:return:
|
||||
"""
|
||||
self.adapter.metadata.setWorldSpawnPosition(pos)
|
||||
return self.adapter.metadata
|
||||
|
||||
# --- Players ---
|
||||
|
||||
def listPlayers(self):
|
||||
return self.adapter.listPlayers()
|
||||
|
Reference in New Issue
Block a user