From 9a59c222886d2e632d29d88f18ff0b2de77bfa67 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sun, 16 Nov 2025 15:02:18 -0600 Subject: [PATCH] Try load chunk data. --- tools/editortool/map/ChunkData.py | 36 +++++++++++++++++ tools/editortool/map/chunkdata.py | 53 +++++++++++++++++++++++++ tools/editortool/map/map.py | 5 +-- tools/editortool/map/mapdata.py | 45 +++++++++++++++++---- tools/editortool/{ => map}/statusbar.py | 0 tools/editortool/maptool.py | 2 +- 6 files changed, 129 insertions(+), 12 deletions(-) create mode 100644 tools/editortool/map/ChunkData.py create mode 100644 tools/editortool/map/chunkdata.py rename tools/editortool/{ => map}/statusbar.py (100%) diff --git a/tools/editortool/map/ChunkData.py b/tools/editortool/map/ChunkData.py new file mode 100644 index 0000000..4681375 --- /dev/null +++ b/tools/editortool/map/ChunkData.py @@ -0,0 +1,36 @@ +import json + +class ChunkData: + def __init__(self): + self.current = {} + self.original = {} + self.filename = None + + def load(self, filename): + try: + with open(filename, 'r') as f: + self.current = json.load(f) + self.filename = filename + self.original = json.loads(json.dumps(self.current)) # Deep copy + except Exception as e: + raise RuntimeError(f"Failed to load chunk file: {e}") + + def save(self, filename=None): + fname = filename if filename else self.filename + if not fname: + raise ValueError("No filename specified for saving chunk.") + try: + with open(fname, 'w') as f: + json.dump(self.current, f, indent=2) + self.original = json.loads(json.dumps(self.current)) # Deep copy + self.filename = fname + except Exception as e: + raise RuntimeError(f"Failed to save chunk file: {e}") + + def new(self): + self.current = {} + self.original = {} + self.filename = None + + def isDirty(self): + return json.dumps(self.current, sort_keys=True) != json.dumps(self.original, sort_keys=True) diff --git a/tools/editortool/map/chunkdata.py b/tools/editortool/map/chunkdata.py new file mode 100644 index 0000000..3a094c9 --- /dev/null +++ b/tools/editortool/map/chunkdata.py @@ -0,0 +1,53 @@ +import json +import os +from dusk.event import Event + +class ChunkData: + def __init__(self, mapData, x, y, z): + self.mapData = mapData + self.x = x + self.y = y + self.z = z + self.current = {} + self.original = {} + self.onChunkData = Event() + + def load(self): + fname = self.getFilename() + if not fname or not os.path.exists(fname): + self.new() + return + try: + with open(fname, 'r') as f: + self.current = json.load(f) + self.original = json.loads(json.dumps(self.current)) # Deep copy + self.onChunkData.invoke(self.current) + except Exception as e: + raise RuntimeError(f"Failed to load chunk file: {e}") + + def save(self): + fname = self.getFilename() + if not fname: + raise ValueError("No filename specified for saving chunk.") + try: + with open(fname, 'w') as f: + json.dump(self.current, f, indent=2) + self.original = json.loads(json.dumps(self.current)) # Deep copy + except Exception as e: + raise RuntimeError(f"Failed to save chunk file: {e}") + + def new(self): + self.current = {} + self.original = {} + self.onChunkData.invoke(self.current) + + def isDirty(self): + return json.dumps(self.current, sort_keys=True) != json.dumps(self.original, sort_keys=True) + + def getFilename(self): + if not self.mapData or not hasattr(self.mapData, 'getMapDirectory'): + return None + dir_path = self.mapData.getMapDirectory() + if dir_path is None: + return None + return f"{dir_path}/{self.x}_{self.y}_{self.z}.json" diff --git a/tools/editortool/map/map.py b/tools/editortool/map/map.py index 6d86334..f3711df 100644 --- a/tools/editortool/map/map.py +++ b/tools/editortool/map/map.py @@ -1,8 +1,5 @@ from dusk.event import Event - -MAP_WIDTH = 5 -MAP_HEIGHT = 5 -MAP_DEPTH = 3 +from editortool.map.mapdata import MAP_WIDTH, MAP_HEIGHT, MAP_DEPTH class Map: def __init__(self): diff --git a/tools/editortool/map/mapdata.py b/tools/editortool/map/mapdata.py index 40be67f..15f912d 100644 --- a/tools/editortool/map/mapdata.py +++ b/tools/editortool/map/mapdata.py @@ -3,9 +3,14 @@ from dusk.event import Event from PyQt5.QtWidgets import QFileDialog, QMessageBox from PyQt5.QtCore import QTimer import os +from editortool.map.chunkdata import ChunkData MAP_DEFAULT_PATH = os.path.join(os.path.dirname(__file__), '../../../assets/map/') EDITOR_CONFIG_PATH = os.path.join(os.path.dirname(__file__), '.editor') +MAP_WIDTH = 5 +MAP_HEIGHT = 5 +MAP_DEPTH = 3 +MAP_CHUNK_COUNT = MAP_WIDTH * MAP_HEIGHT * MAP_DEPTH class MapData: def __init__(self): @@ -13,7 +18,14 @@ class MapData: self.dataOriginal = {} self.onMapData = Event() self.mapFileName = None - + self.chunks = {} + + index = 0 + for x in range(MAP_WIDTH): + for y in range(MAP_HEIGHT): + for z in range(MAP_DEPTH): + self.chunks[index] = ChunkData(self, x, y, z) + index += 1 QTimer.singleShot(16, self.loadLastFile) def loadLastFile(self): @@ -29,7 +41,7 @@ class MapData: def updateEditorConfig(self): try: - config = {'lastFile': self.mapFileName if self.mapFileName else ""} + config = {'lastFile': self.getMapFilename() if self.getMapFilename() else ""} with open(EDITOR_CONFIG_PATH, 'w') as f: json.dump(config, f, indent=2) except Exception: @@ -39,23 +51,25 @@ class MapData: self.data = {} self.dataOriginal = {} self.mapFileName = None + for chunk in self.chunks.values(): + chunk.new() self.onMapData.invoke(self.data) self.updateEditorConfig() def save(self, fname=None): - if not self.mapFileName and fname is None: + if not self.getMapFilename() and fname is None: filePath, _ = QFileDialog.getSaveFileName(None, "Save Map File", MAP_DEFAULT_PATH, "Map Files (*.json)") if not filePath: return self.mapFileName = filePath if fname: self.mapFileName = fname - if not self.isMapFileDirty(): - return try: - with open(self.mapFileName, 'w') as f: + with open(self.getMapFilename(), 'w') as f: json.dump(self.data, f, indent=2) self.dataOriginal = json.loads(json.dumps(self.data)) # Deep copy + for chunk in self.chunks.values(): + chunk.save() self.updateEditorConfig() except Exception as e: QMessageBox.critical(None, "Save Error", f"Failed to save map file:\n{e}") @@ -66,6 +80,8 @@ class MapData: self.data = json.load(f) self.mapFileName = fileName self.dataOriginal = json.loads(json.dumps(self.data)) # Deep copy + for chunk in self.chunks.values(): + chunk.load() self.onMapData.invoke(self.data) self.updateEditorConfig() except Exception as e: @@ -75,4 +91,19 @@ class MapData: return json.dumps(self.data, sort_keys=True) != json.dumps(self.dataOriginal, sort_keys=True) def isDirty(self): - return self.isMapFileDirty() \ No newline at end of file + return self.isMapFileDirty() or self.anyChunksDirty() + + def getMapFilename(self): + return self.mapFileName if self.mapFileName else None + + def getMapDirectory(self): + fname = self.getMapFilename() + if not fname or not fname.endswith('.json'): + return None + return fname[:-5] # Remove '.json' extension + + def anyChunksDirty(self): + for chunk in self.chunks.values(): + if chunk.isDirty(): + return True + return False \ No newline at end of file diff --git a/tools/editortool/statusbar.py b/tools/editortool/map/statusbar.py similarity index 100% rename from tools/editortool/statusbar.py rename to tools/editortool/map/statusbar.py diff --git a/tools/editortool/maptool.py b/tools/editortool/maptool.py index 7ef2c4f..802a24a 100644 --- a/tools/editortool/maptool.py +++ b/tools/editortool/maptool.py @@ -5,7 +5,7 @@ from editortool.map.chunkpanel import ChunkPanel from editortool.map.mapinfopanel import MapInfoPanel from editortool.map.mapdata import MapData from editortool.map.toolbar import MapToolbar -from editortool.statusbar import StatusBar +from editortool.map.statusbar import StatusBar class MapWindow(QMainWindow):