Implement add/remove tile entity in block inspector

This commit is contained in:
David Vierra 2016-06-23 23:06:52 -10:00
parent f31a5b1f17
commit 9ea24fd283
4 changed files with 108 additions and 13 deletions

View File

@ -20,7 +20,7 @@
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="pageInspectBlock">
<layout class="QVBoxLayout" name="verticalLayout_2">
@ -275,6 +275,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addTileEntityButton">
<property name="text">
<string>Add Tile Entity</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeTileEntityButton">
<property name="text">

View File

@ -89,6 +89,9 @@ class InspectorWidget(QtGui.QWidget, Ui_inspectorWidget):
self.removeEntityButton.clicked.connect(self.removeEntity)
self.addTileEntityButton.clicked.connect(self.addTileEntity)
self.removeTileEntityButton.clicked.connect(self.removeTileEntity)
def _changed(self, value, idx):
if self.blockPos is None:
return
@ -149,13 +152,22 @@ class InspectorWidget(QtGui.QWidget, Ui_inspectorWidget):
self.blockInternalNameLabel.setText(block.internalName)
self.blockStateLabel.setText(str(block.blockState))
if self.blockEditorWidget:
self.blockTabWidget.removeTab(0)
self.blockEditorWidget = None
blockBox = BoundingBox((x, y, z), (1, 1, 1))
self.selectionNode.selectionBox = blockBox
self.updateTileEntity()
def updateTileEntity(self):
pos = self.blockPos
self.tileEntity = self.editorSession.currentDimension.getTileEntity(pos)
log.info("Inspecting TileEntity %s at %s", self.tileEntity, pos)
if self.blockEditorWidget:
self.blockTabWidget.removeTab(0)
self.blockEditorWidget = None
if self.tileEntity is not None:
editorClass = tileEntityEditorClasses.get(self.tileEntity.id)
if editorClass is not None:
@ -179,20 +191,47 @@ class InspectorWidget(QtGui.QWidget, Ui_inspectorWidget):
self.removeTileEntityButton.setEnabled(self.tileEntity is not None)
blockBox = BoundingBox((x, y, z), (1, 1, 1))
self.selectionNode.selectionBox = blockBox
if self.tileEntity is not None:
if self.tileEntity.id == "Control":
try:
commandObj = ParseCommand(self.tileEntity.Command)
visuals = CommandVisuals((x, y, z), commandObj)
visuals = CommandVisuals(pos, commandObj)
self.commandBlockVisualsNode = visuals
self.overlayNode.addChild(visuals)
self.editorSession.updateView()
except Exception as e:
log.warn("Failed to parse command.", exc_info=1)
_tileEntityIDs = {
"minecraft:command_block": "Control",
"minecraft:standing_sign": "Sign",
"minecraft:wall_sign": "Sign",
"minecraft:chest": "Chest",
"minecraft:hopper": "Hopper",
"minecraft:dispenser": "Trap",
}
def addTileEntity(self):
if self.tileEntity is not None:
return
block = self.editorSession.currentDimension.getBlock(*self.blockPos)
tileEntityID = self._tileEntityIDs[block.internalName]
ref = self.editorSession.worldEditor.TileEntityRef.create(tileEntityID)
ref.Position = self.blockPos
with self.editorSession.beginSimpleCommand("Create TileEntity"):
self.editorSession.currentDimension.addTileEntity(ref)
self.updateTileEntity()
def removeTileEntity(self):
if self.tileEntity is not None:
with self.editorSession.beginSimpleCommand("Remove TileEntity"):
self.editorSession.currentDimension.removeTileEntity(self.tileEntity)
self.updateTileEntity()
def inspectEntity(self, entity):
self.tileEntity = None

View File

@ -172,7 +172,7 @@ class _PCEntityRef(object):
cls = _entityClasses.get(entityID)
if cls is None:
log.info("No PC entity ref class found for %s", entityID)
return None
cls = PCEntityRefBase
ref = cls.create()
ref.id = entityID
return ref
@ -214,6 +214,8 @@ class PCEntityRefBase(object):
nbtattr.SetNBTDefaults(ref)
return ref
entityID = NotImplemented
id = nbtattr.NBTAttr("id", 't')
Position = nbtattr.NBTVectorAttr("Pos", 'd')
Motion = nbtattr.NBTVectorAttr("Motion", 'd')
@ -415,10 +417,24 @@ _entityClasses = {
}
def PCTileEntityRef(rootTag, chunk=None):
id = rootTag["id"].value
cls = _tileEntityClasses.get(id, PCTileEntityRefBase)
return cls(rootTag, chunk)
class _PCTileEntityRef(object):
def create(self, entityID):
cls = _tileEntityClasses.get(entityID)
if cls is None:
log.info("No PC tile entity ref class found for %s", entityID)
cls = PCTileEntityRefBase
ref = cls.create()
ref.id = entityID
return ref
def __call__(self, rootTag, chunk=None):
id = rootTag["id"].value
cls = _tileEntityClasses.get(id, PCEntityRefBase)
return cls(rootTag, chunk)
PCTileEntityRef = _PCTileEntityRef()
class PCTileEntityRefBase(object):
@ -429,6 +445,15 @@ class PCTileEntityRefBase(object):
def raw_tag(self):
return self.rootTag
@classmethod
def create(cls):
rootTag = nbt.TAG_Compound()
ref = cls(rootTag)
nbtattr.SetNBTDefaults(ref)
return ref
tileEntityID = NotImplemented
id = nbtattr.NBTAttr("id", 't')
Position = nbtattr.KeyedVectorAttr('x', 'y', 'z', nbt.TAG_Int, 0)

View File

@ -254,6 +254,7 @@ class WorldEditor(object):
def __repr__(self):
return "WorldEditor(adapter=%r)" % self.adapter
# --- Summary Info ---
@classmethod
@ -261,12 +262,24 @@ class WorldEditor(object):
worldInfo = findAdapter(filename, readonly=True, getInfo=True)
return worldInfo
# --- Forwarded from Adapter ---
@property
def EntityRef(self):
return self.adapter.EntityRef
@property
def TileEntityRef(self):
return self.adapter.TileEntityRef
# --- Debug ---
def setCacheLimit(self, size):
self._chunkDataCache.setCacheLimit(size)
# --- Undo/redo ---
def requireRevisions(self):
self.adapter.requireRevisions()
@ -865,6 +878,17 @@ class WorldEditorDimension(object):
chunk.addTileEntity(ref.copy())
def removeEntity(self, ref):
if ref.chunk is None:
return
ref.chunk.removeEntity(ref)
def removeTileEntity(self, ref):
if ref.chunk is None:
return
ref.chunk.removeTileEntity(ref)
# --- Import/Export ---
def copyBlocksIter(self, *a, **kw):