Basically entity editing done
Some checks failed
Build Dusk / build-linux (push) Failing after 43s
Build Dusk / build-psp (push) Failing after 49s

This commit is contained in:
2025-11-22 11:56:08 -06:00
parent 03218ce20f
commit 7daeaee6b5
10 changed files with 118 additions and 15 deletions

View File

@@ -1,4 +1,5 @@
from dusk.defs import ENTITY_TYPE_NULL, ENTITY_TYPE_NPC
from dusk.defs import ENTITY_TYPE_NULL, ENTITY_TYPE_NPC, CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, TILE_WIDTH, TILE_HEIGHT, TILE_DEPTH
from editortool.map.vertexbuffer import VertexBuffer
class Entity:
def __init__(self, chunk, localX=0, localY=0, localZ=0):
@@ -8,6 +9,7 @@ class Entity:
self.localY = localY
self.localZ = localZ
self.chunk = chunk
self.vertexBuffer = VertexBuffer()
pass
def load(self, obj):
@@ -15,11 +17,73 @@ class Entity:
self.localX = obj.get('x', 0)
self.localY = obj.get('y', 0)
self.localZ = obj.get('z', 0)
self.name = obj.get('name', "Untitled")
pass
def save(self, obj):
obj['type'] = self.type
obj['name'] = self.name
obj['x'] = self.localX
obj['y'] = self.localY
obj['z'] = self.localZ
pass
pass
def setType(self, entityType):
if self.type == entityType:
return
self.type = entityType
self.chunk.dirty = True
self.chunk.map.onEntityData.invoke()
def setName(self, name):
if self.name == name:
return
self.name = name
self.chunk.dirty = True
self.chunk.map.onEntityData.invoke()
def draw(self):
self.vertexBuffer.clear()
startX = (self.chunk.x * CHUNK_WIDTH + self.localX) * TILE_WIDTH
startY = (self.chunk.y * CHUNK_HEIGHT + self.localY) * TILE_HEIGHT
startZ = (self.chunk.z * CHUNK_DEPTH + self.localZ) * TILE_DEPTH
w = TILE_WIDTH
h = TILE_HEIGHT
d = TILE_DEPTH
# Center
startX -= w / 2
startY -= h / 2
startZ -= d / 2
# Offset upwards a little
startZ += 1
# Buffer simple quad at current position (need 6 positions)
self.vertexBuffer.vertices = [
startX, startY, startZ,
startX + w, startY, startZ,
startX + w, startY + h, startZ,
startX, startY, startZ,
startX + w, startY + h, startZ,
startX, startY + h, startZ,
]
self.vertexBuffer.colors = [
1.0, 0.0, 1.0, 1.0,
1.0, 0.0, 1.0, 1.0,
1.0, 0.0, 1.0, 1.0,
1.0, 0.0, 1.0, 1.0,
1.0, 0.0, 1.0, 1.0,
1.0, 0.0, 1.0, 1.0,
]
self.vertexBuffer.uvs = [
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 0.0,
1.0, 1.0,
0.0, 1.0,
]
self.vertexBuffer.buildData()
self.vertexBuffer.draw()

View File

@@ -144,6 +144,10 @@ class Map:
def draw(self):
for chunk in self.chunks.values():
chunk.draw()
for chunk in self.chunks.values():
for entity in chunk.entities.values():
entity.draw()
def getChunkAtWorldPos(self, x, y, z):
chunkX = x // CHUNK_WIDTH

View File

@@ -1,7 +1,7 @@
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QListWidget, QHBoxLayout, QPushButton, QLineEdit, QListWidgetItem
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QComboBox, QHBoxLayout, QPushButton, QLineEdit, QListWidget, QListWidgetItem
from PyQt5.QtCore import Qt
from dusk.entity import Entity
from dusk.defs import CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH
from dusk.defs import CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, ENTITY_TYPES, ENTITY_TYPE_NULL
class EntityPanel(QWidget):
def __init__(self, parent):
@@ -22,6 +22,15 @@ class EntityPanel(QWidget):
nameLayout.addWidget(self.nameInput)
layout.addLayout(nameLayout)
# Entity Type dropdown (single selection)
typeLayout = QHBoxLayout()
typeLabel = QLabel("Type:")
self.typeDropdown = QComboBox()
self.typeDropdown.addItems(ENTITY_TYPES)
typeLayout.addWidget(typeLabel)
typeLayout.addWidget(self.typeDropdown)
layout.addLayout(typeLayout)
# Entity list and buttons
self.entityList = QListWidget()
self.entityList.addItems([])
@@ -41,18 +50,22 @@ class EntityPanel(QWidget):
self.parent.map.onPositionChange.sub(self.onPositionChange)
self.entityList.itemClicked.connect(self.onEntityClicked)
self.entityList.itemDoubleClicked.connect(self.onEntityDoubleClicked)
self.typeDropdown.currentIndexChanged.connect(self.onTypeSelected)
self.nameInput.textChanged.connect(self.onNameChanged)
# Call once to populate
self.onEntityData()
self.onEntityUnselect()
def onEntityUnselect(self):
self.nameInput.setText("")
self.entityList.setCurrentItem(None)
self.nameInput.setText("")
self.typeDropdown.setCurrentIndex(ENTITY_TYPE_NULL)
def onEntitySelect(self, entity):
self.nameInput.setText(entity.name)
self.entityList.setCurrentItem(entity.item)
self.nameInput.setText(entity.name)
self.typeDropdown.setCurrentIndex(entity.type)
def onEntityDoubleClicked(self, item):
entity = item.data(Qt.UserRole)
@@ -76,6 +89,13 @@ class EntityPanel(QWidget):
)
def onRemoveEntity(self):
item = self.entityList.currentItem()
if item is None:
return
entity = item.data(Qt.UserRole)
if entity:
chunk = entity.chunk
chunk.removeEntity(entity)
pass
def onEntityData(self):
@@ -108,4 +128,20 @@ class EntityPanel(QWidget):
continue
self.onEntitySelect(ent)
self.entityList.setCurrentItem(ent.item)
break
break
def onTypeSelected(self, index):
item = self.entityList.currentItem()
if item is None:
return
entity = item.data(Qt.UserRole)
if entity:
entity.setType(index)
def onNameChanged(self, text):
item = self.entityList.currentItem()
if item is None:
return
entity = item.data(Qt.UserRole)
if entity:
entity.setName(text)

View File

@@ -31,7 +31,6 @@ class MapLeftPanel(QWidget):
# Tabs
self.tabs = QTabWidget()
self.chunkPanel = ChunkPanel(self.parent)
self.chunkPanel.setFixedWidth(250)
self.tabs.addTab(self.chunkPanel, "Tiles")
self.entityPanel = EntityPanel(self.parent)
self.tabs.addTab(self.entityPanel, "Entities")

View File

@@ -27,7 +27,7 @@ class MapWindow(QMainWindow):
# Window setup
self.setWindowTitle("Dusk Map Editor")
self.resize(1280, 720)
self.resize(1600, 900)
# Menubar (TESTING)
self.menubar = MapMenubar(self)
@@ -38,7 +38,7 @@ class MapWindow(QMainWindow):
# Left panel (tabs + nav buttons)
self.leftPanel = MapLeftPanel(self)
self.leftPanel.setFixedWidth(250)
self.leftPanel.setFixedWidth(350)
mainLayout.addWidget(self.leftPanel)
# Center panel (GLWidget + controls)