Begin adding entities to editor
This commit is contained in:
@@ -54,6 +54,7 @@ def processChunk(chunk):
|
||||
buffer.extend(b'DCF')# Header
|
||||
buffer.extend(len(chunk.tiles).to_bytes(4, 'little')) # Number of tiles
|
||||
buffer.extend(len(models).to_bytes(1, 'little')) # Number of models
|
||||
buffer.extend(len(chunk.entities).to_bytes(1, 'little')) # Number of entities
|
||||
|
||||
# Buffer tile data as array of uint8_t
|
||||
for tileIndex, tile in chunk.tiles.items():
|
||||
@@ -79,6 +80,14 @@ def processChunk(chunk):
|
||||
buffer.extend(bytearray(struct.pack('<f', vertex[0])))
|
||||
buffer.extend(bytearray(struct.pack('<f', vertex[1])))
|
||||
buffer.extend(bytearray(struct.pack('<f', vertex[2])))
|
||||
|
||||
# For each entity
|
||||
for entity in chunk.entities.values():
|
||||
buffer.extend(entity.type.to_bytes(1, 'little'))
|
||||
buffer.extend(entity.localX.to_bytes(1, 'little'))
|
||||
buffer.extend(entity.localY.to_bytes(1, 'little'))
|
||||
buffer.extend(entity.localZ.to_bytes(1, 'little'))
|
||||
pass
|
||||
|
||||
# Write out map file
|
||||
relative = getAssetRelativePath(chunk.getFilename())
|
||||
|
||||
@@ -3,6 +3,7 @@ import os
|
||||
from dusk.event import Event
|
||||
from dusk.defs import CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, CHUNK_VERTEX_COUNT_MAX, TILE_SHAPE_NULL
|
||||
from dusk.tile import Tile
|
||||
from dusk.entity import Entity
|
||||
from editortool.map.vertexbuffer import VertexBuffer
|
||||
from OpenGL.GL import *
|
||||
|
||||
@@ -14,12 +15,16 @@ class Chunk:
|
||||
self.z = z
|
||||
self.current = {}
|
||||
self.original = {}
|
||||
self.entities = {}
|
||||
self.onChunkData = Event()
|
||||
self.dirty = False
|
||||
|
||||
self.tiles = {}
|
||||
self.vertexBuffer = VertexBuffer()
|
||||
|
||||
# TEST
|
||||
self.addEntity()
|
||||
|
||||
tileIndex = 0
|
||||
for tz in range(CHUNK_DEPTH):
|
||||
for ty in range(CHUNK_HEIGHT):
|
||||
@@ -100,4 +105,18 @@ class Chunk:
|
||||
return f"{dir_path}/{self.x}_{self.y}_{self.z}.json"
|
||||
|
||||
def draw(self):
|
||||
self.vertexBuffer.draw()
|
||||
self.vertexBuffer.draw()
|
||||
|
||||
def addEntity(self):
|
||||
ent = Entity()
|
||||
self.entities[len(self.entities)] = ent
|
||||
self.map.onEntityData.invoke()
|
||||
return ent
|
||||
|
||||
def removeEntity(self, entity):
|
||||
for key, val in list(self.entities.items()):
|
||||
if val == entity:
|
||||
del self.entities[key]
|
||||
self.map.onEntityData.invoke()
|
||||
return True
|
||||
return False
|
||||
@@ -37,4 +37,11 @@ TILE_SHAPES = {}
|
||||
for key in defs.keys():
|
||||
if key.startswith('TILE_SHAPE_'):
|
||||
globals()[key] = int(defs.get(key))
|
||||
TILE_SHAPES[key] = int(defs.get(key))
|
||||
TILE_SHAPES[key] = int(defs.get(key))
|
||||
|
||||
ENTITY_TYPES = {}
|
||||
for key in defs.keys():
|
||||
if key.startswith('ENTITY_TYPE_'):
|
||||
globals()[key] = int(defs.get(key))
|
||||
if key != 'ENTITY_TYPE_COUNT':
|
||||
ENTITY_TYPES[key] = int(defs.get(key))
|
||||
9
tools/dusk/entity.py
Normal file
9
tools/dusk/entity.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from dusk.defs import ENTITY_TYPE_NULL, ENTITY_TYPE_NPC
|
||||
|
||||
class Entity:
|
||||
def __init__(self):
|
||||
self.type = ENTITY_TYPE_NPC
|
||||
self.localX = 0
|
||||
self.localY = 8
|
||||
self.localZ = 1
|
||||
pass
|
||||
@@ -19,6 +19,7 @@ class Map:
|
||||
self.chunks = {}
|
||||
self.onMapData = Event()
|
||||
self.onPositionChange = Event()
|
||||
self.onEntityData = Event()
|
||||
self.mapFileName = None
|
||||
self.lastFile = None
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QGridLayout, QTreeWidget, QTreeWidgetItem, QComboBox
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QGridLayout, QTreeWidget, QTreeWidgetItem, QComboBox
|
||||
from dusk.defs import CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, TILE_SHAPES
|
||||
|
||||
class ChunkPanel(QWidget):
|
||||
@@ -6,25 +6,6 @@ class ChunkPanel(QWidget):
|
||||
super().__init__(parent)
|
||||
self.parent = parent
|
||||
layout = QVBoxLayout(self)
|
||||
self.chunkInfoLabel = QLabel("Tile Information")
|
||||
layout.addWidget(self.chunkInfoLabel)
|
||||
|
||||
# Nav buttons
|
||||
grid = QGridLayout()
|
||||
self.btnUp = QPushButton("U")
|
||||
self.btnN = QPushButton("N")
|
||||
self.btnDown = QPushButton("D")
|
||||
self.btnW = QPushButton("W")
|
||||
self.btnS = QPushButton("S")
|
||||
self.btnE = QPushButton("E")
|
||||
|
||||
grid.addWidget(self.btnUp, 0, 0)
|
||||
grid.addWidget(self.btnN, 0, 1)
|
||||
grid.addWidget(self.btnDown, 0, 2)
|
||||
grid.addWidget(self.btnW, 1, 0)
|
||||
grid.addWidget(self.btnS, 1, 1)
|
||||
grid.addWidget(self.btnE, 1, 2)
|
||||
layout.addLayout(grid)
|
||||
|
||||
# Tile shape dropdown
|
||||
self.tileShapeDropdown = QComboBox()
|
||||
@@ -39,16 +20,9 @@ class ChunkPanel(QWidget):
|
||||
layout.addWidget(self.tree) # Removed invalid stretch factor
|
||||
|
||||
# Add stretch so tree expands
|
||||
layout.setStretchFactor(grid, 0)
|
||||
layout.setStretchFactor(self.tree, 1)
|
||||
|
||||
# Event subscriptions
|
||||
self.btnN.clicked.connect(lambda: self.parent.map.moveRelative(0, -1, 0))
|
||||
self.btnS.clicked.connect(lambda: self.parent.map.moveRelative(0, 1, 0))
|
||||
self.btnE.clicked.connect(lambda: self.parent.map.moveRelative(1, 0, 0))
|
||||
self.btnW.clicked.connect(lambda: self.parent.map.moveRelative(-1, 0, 0))
|
||||
self.btnUp.clicked.connect(lambda: self.parent.map.moveRelative(0, 0, 1))
|
||||
self.btnDown.clicked.connect(lambda: self.parent.map.moveRelative(0, 0, -1))
|
||||
self.parent.map.onMapData.sub(self.onMapData)
|
||||
self.parent.map.onPositionChange.sub(self.onPositionChange)
|
||||
self.tileShapeDropdown.currentTextChanged.connect(self.onTileShapeChanged)
|
||||
|
||||
70
tools/editortool/map/entitypanel.py
Normal file
70
tools/editortool/map/entitypanel.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QListWidget, QHBoxLayout, QPushButton, QLineEdit
|
||||
from PyQt5.QtCore import Qt
|
||||
from dusk.entity import Entity
|
||||
|
||||
class EntityPanel(QWidget):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
self.parent = parent
|
||||
layout = QVBoxLayout(self)
|
||||
self.setLayout(layout)
|
||||
|
||||
# Top panel placeholder
|
||||
topWidget = QLabel("Entity Editor (top)")
|
||||
layout.addWidget(topWidget)
|
||||
|
||||
# Name input
|
||||
nameLayout = QHBoxLayout()
|
||||
nameLabel = QLabel("Name:")
|
||||
self.nameInput = QLineEdit()
|
||||
nameLayout.addWidget(nameLabel)
|
||||
nameLayout.addWidget(self.nameInput)
|
||||
layout.addLayout(nameLayout)
|
||||
|
||||
# Entity list and buttons
|
||||
self.entityList = QListWidget()
|
||||
self.entityList.addItems(["Entity 1", "Entity 2", "Entity 3"])
|
||||
layout.addWidget(self.entityList, stretch=1)
|
||||
|
||||
btnLayout = QHBoxLayout()
|
||||
self.btnAdd = QPushButton("Add")
|
||||
self.btnRemove = QPushButton("Remove")
|
||||
btnLayout.addWidget(self.btnAdd)
|
||||
btnLayout.addWidget(self.btnRemove)
|
||||
layout.addLayout(btnLayout)
|
||||
|
||||
# Events
|
||||
self.btnAdd.clicked.connect(self.onAddEntity)
|
||||
self.btnRemove.clicked.connect(self.onRemoveEntity)
|
||||
self.parent.map.onEntityData.sub(self.onEntityData)
|
||||
self.entityList.itemClicked.connect(self.onEntityClicked)
|
||||
self.entityList.itemDoubleClicked.connect(self.onEntityDoubleClicked)
|
||||
|
||||
# Call once to populate
|
||||
self.onEntityData()
|
||||
self.onEntityUnselect()
|
||||
|
||||
def onEntityUnselect(self):
|
||||
self.nameInput.setText("")
|
||||
|
||||
def onEntityDoubleClicked(self, item):
|
||||
print(f"Double clicked: {item.text()}")
|
||||
|
||||
def onEntityClicked(self, item):
|
||||
print(f"Clicked: {item.text()}")
|
||||
|
||||
def onAddEntity(self):
|
||||
chunk = self.parent.map.getChunkAtWorldPos(*self.parent.map.position)
|
||||
if chunk is None:
|
||||
return
|
||||
chunk.addEntity()
|
||||
|
||||
def onRemoveEntity(self):
|
||||
pass
|
||||
|
||||
def onEntityData(self):
|
||||
self.onEntityUnselect()
|
||||
self.entityList.clear()
|
||||
for chunk in self.parent.map.chunks.values():
|
||||
for entity_id, entity in chunk.entities.items():
|
||||
self.entityList.addItem(f"Entity {entity_id}")
|
||||
46
tools/editortool/map/mapleftpanel.py
Normal file
46
tools/editortool/map/mapleftpanel.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGridLayout, QPushButton, QTabWidget, QLabel
|
||||
from editortool.map.chunkpanel import ChunkPanel
|
||||
from editortool.map.entitypanel import EntityPanel
|
||||
|
||||
class MapLeftPanel(QWidget):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
self.parent = parent
|
||||
layout = QVBoxLayout(self)
|
||||
self.setLayout(layout)
|
||||
|
||||
# Nav buttons
|
||||
self.chunkInfoLabel = QLabel("Tile Information")
|
||||
layout.addWidget(self.chunkInfoLabel)
|
||||
grid = QGridLayout()
|
||||
self.btnUp = QPushButton("U")
|
||||
self.btnN = QPushButton("N")
|
||||
self.btnDown = QPushButton("D")
|
||||
self.btnW = QPushButton("W")
|
||||
self.btnS = QPushButton("S")
|
||||
self.btnE = QPushButton("E")
|
||||
|
||||
grid.addWidget(self.btnUp, 0, 0)
|
||||
grid.addWidget(self.btnN, 0, 1)
|
||||
grid.addWidget(self.btnDown, 0, 2)
|
||||
grid.addWidget(self.btnW, 1, 0)
|
||||
grid.addWidget(self.btnS, 1, 1)
|
||||
grid.addWidget(self.btnE, 1, 2)
|
||||
layout.addLayout(grid)
|
||||
|
||||
# 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")
|
||||
layout.addWidget(self.tabs)
|
||||
|
||||
# Event subscriptions
|
||||
self.btnN.clicked.connect(lambda: self.parent.map.moveRelative(0, -1, 0))
|
||||
self.btnS.clicked.connect(lambda: self.parent.map.moveRelative(0, 1, 0))
|
||||
self.btnE.clicked.connect(lambda: self.parent.map.moveRelative(1, 0, 0))
|
||||
self.btnW.clicked.connect(lambda: self.parent.map.moveRelative(-1, 0, 0))
|
||||
self.btnUp.clicked.connect(lambda: self.parent.map.moveRelative(0, 0, 1))
|
||||
self.btnDown.clicked.connect(lambda: self.parent.map.moveRelative(0, 0, -1))
|
||||
@@ -1,8 +1,8 @@
|
||||
import os
|
||||
from PyQt5.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QMessageBox, QTabWidget
|
||||
from PyQt5.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QMessageBox
|
||||
from PyQt5.QtCore import Qt
|
||||
from editortool.map.glwidget import GLWidget
|
||||
from editortool.map.chunkpanel import ChunkPanel
|
||||
from editortool.map.mapleftpanel import MapLeftPanel
|
||||
from editortool.map.mapinfopanel import MapInfoPanel
|
||||
from editortool.map.menubar import MapMenubar
|
||||
from editortool.map.statusbar import StatusBar
|
||||
@@ -36,14 +36,10 @@ class MapWindow(QMainWindow):
|
||||
self.setCentralWidget(central)
|
||||
mainLayout = QHBoxLayout(central)
|
||||
|
||||
# Tabs (left)
|
||||
self.tabs = QTabWidget()
|
||||
|
||||
self.chunkPanel = ChunkPanel(self)
|
||||
self.chunkPanel.setFixedWidth(200)
|
||||
self.tabs.addTab(self.chunkPanel, "Tile Editor")
|
||||
|
||||
mainLayout.addWidget(self.tabs)
|
||||
# Left panel (tabs + nav buttons)
|
||||
self.leftPanel = MapLeftPanel(self)
|
||||
self.leftPanel.setFixedWidth(250)
|
||||
mainLayout.addWidget(self.leftPanel)
|
||||
|
||||
# Center panel (GLWidget + controls)
|
||||
self.glWidget = GLWidget(self)
|
||||
|
||||
Reference in New Issue
Block a user