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

View File

@ -89,6 +89,9 @@ class InspectorWidget(QtGui.QWidget, Ui_inspectorWidget):
self.removeEntityButton.clicked.connect(self.removeEntity) self.removeEntityButton.clicked.connect(self.removeEntity)
self.addTileEntityButton.clicked.connect(self.addTileEntity)
self.removeTileEntityButton.clicked.connect(self.removeTileEntity)
def _changed(self, value, idx): def _changed(self, value, idx):
if self.blockPos is None: if self.blockPos is None:
return return
@ -149,13 +152,22 @@ class InspectorWidget(QtGui.QWidget, Ui_inspectorWidget):
self.blockInternalNameLabel.setText(block.internalName) self.blockInternalNameLabel.setText(block.internalName)
self.blockStateLabel.setText(str(block.blockState)) self.blockStateLabel.setText(str(block.blockState))
if self.blockEditorWidget: blockBox = BoundingBox((x, y, z), (1, 1, 1))
self.blockTabWidget.removeTab(0)
self.blockEditorWidget = None self.selectionNode.selectionBox = blockBox
self.updateTileEntity()
def updateTileEntity(self):
pos = self.blockPos
self.tileEntity = self.editorSession.currentDimension.getTileEntity(pos) self.tileEntity = self.editorSession.currentDimension.getTileEntity(pos)
log.info("Inspecting TileEntity %s at %s", self.tileEntity, 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: if self.tileEntity is not None:
editorClass = tileEntityEditorClasses.get(self.tileEntity.id) editorClass = tileEntityEditorClasses.get(self.tileEntity.id)
if editorClass is not None: if editorClass is not None:
@ -179,20 +191,47 @@ class InspectorWidget(QtGui.QWidget, Ui_inspectorWidget):
self.removeTileEntityButton.setEnabled(self.tileEntity is not None) 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 is not None:
if self.tileEntity.id == "Control": if self.tileEntity.id == "Control":
try: try:
commandObj = ParseCommand(self.tileEntity.Command) commandObj = ParseCommand(self.tileEntity.Command)
visuals = CommandVisuals((x, y, z), commandObj) visuals = CommandVisuals(pos, commandObj)
self.commandBlockVisualsNode = visuals self.commandBlockVisualsNode = visuals
self.overlayNode.addChild(visuals) self.overlayNode.addChild(visuals)
self.editorSession.updateView() self.editorSession.updateView()
except Exception as e: except Exception as e:
log.warn("Failed to parse command.", exc_info=1) 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): def inspectEntity(self, entity):
self.tileEntity = None self.tileEntity = None

View File

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

View File

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