#!/usr/bin/env python3 import sys from struct import unpack from PySide6.QtCore import ( QMargins, QSettings, QSize, Qt, ) from PySide6.QtGui import ( QBrush, QColor, QPen, ) from PySide6.QtWidgets import ( QApplication, QGraphicsRectItem, QGraphicsScene, QGraphicsView, QGridLayout, QLabel, QMainWindow, QMessageBox, QPushButton, QSizePolicy, QToolBar, QWidget, ) num_wizards = 6 num_heroes = 35 num_nodes = 30 num_items = 132 num_encounters = 102 num_cities = 100 num_units = 1009 num_events = 50 map_width = 60 map_height = 40 savefile = 'SAVE5.GAM' tile_size = 20 terrain_colors = { 'Ocean': (20, 20, 80), 'Shore': (40, 40, 120), 'Lake': (60, 60, 160), 'River': (60, 60, 160), 'Desert': (210, 200, 100), 'Swamp': (40, 10, 40), 'Grassland': (40, 120, 40), 'Forest': (20, 80, 20), 'Hills': (80, 120, 80), 'Mountain': (80, 80, 80), 'Tundra': (180, 180, 180), 'Node': (10, 10, 10), } terrain_hex_lookup = { 0x000: 'Ocean', 0x012: 'Lake', 0x0a2: 'Grassland', 0x0a3: 'Forest', 0x0a4: 'Mountain', 0x0a5: 'Desert', 0x0a6: 'Swamp', 0x0a7: 'Tundra', 0x0a8: 'Node', #sorcery 0x0a9: 'Node', #nature 0x0aa: 'Node', #chaos 0x0ab: 'Hills', 0x0ac: 'Grassland', 0x0ad: 'Grassland', 0x0ae: 'Desert', 0x0af: 'Desert', 0x0b0: 'Desert', 0x0b1: 'Swamp', 0x0b2: 'Swamp', 0x0b3: 'Node', #volcano 0x0b4: 'Grassland', 0x0b5: 'Tundra', 0x0b6: 'Tundra', 0x0b7: 'Forest', 0x0b8: 'Forest', 0x0c5: 'Lake', 0x0c6: 'Lake', 0x0c7: 'Lake', 0x0c8: 'Lake', 0x1d4: 'River', 0x1d5: 'River', 0x1d6: 'River', 0x1d7: 'River', 0x1d8: 'River', 0x259: 'Ocean', 0x26a: 'Tundra', } terrain_hex_ranges = { (0x002, 0x0a1): 'Shore', (0x0b9, 0x0c4): 'River', (0x0c9, 0x0e8): 'Shore', (0x0e9, 0x102): 'River', (0x103, 0x112): 'Mountain', (0x113, 0x123): 'Hills', (0x124, 0x1c3): 'Desert', (0x1c4, 0x1d3): 'Shore', (0x1d9, 0x258): 'Shore', (0x25a, 0x2ff): 'Tundra', } missed_hexes = [] def map_square_color(terrain_hex): color = (250, 60, 60) terrain = '' if terrain_hex in terrain_hex_lookup: terrain = terrain_hex_lookup[terrain_hex] else: for (r, t) in terrain_hex_ranges.items(): if r[0] <= terrain_hex <= r[1]: terrain = t if terrain in terrain_colors: color = terrain_colors[terrain] else: missed_hexes.append(terrain_hex) return color def map_square_terrain(terrain_hex): terrain = '' if terrain_hex in terrain_hex_lookup: terrain = terrain_hex_lookup[terrain_hex] else: for (r, t) in terrain_hex_ranges.items(): if r[0] <= terrain_hex <= r[1]: terrain = t return terrain class MapTile(QGraphicsRectItem): def __init__(self, x, y, tile_hex): super().__init__(0, 0, tile_size, tile_size) self.x = x self.y = y self.tile_hex = tile_hex self.terrain = map_square_terrain(tile_hex) self.color = (250, 60, 60) if self.terrain in terrain_colors: self.color = terrain_colors[self.terrain] brush = QBrush(QColor(self.color[0], self.color[1], self.color[2])) self.setBrush(brush) self.setPos(tile_size * self.x, tile_size * self.y) self.setHandlesChildEvents(True) def mousePressEvent(self, mousevent): print("clicked a %s at (%s, %s)" % (self.terrain, self.x, self.y)) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.data = {} self.setWindowTitle("MOM Save Editor") mapGridLayout = QGridLayout() mapGridLayout.setSpacing(0) mapGridLayout.setHorizontalSpacing(0) mapGridLayout.setVerticalSpacing(0) mapGridLayout.setContentsMargins(QMargins(0,0,0,0)) self.setCentralWidget(QWidget()) self.addToolBar(QToolBar()) self.centralWidget().setLayout(mapGridLayout) self.main_scene = QGraphicsScene(0, 0, 1200, 800) self.mirror_scene = QGraphicsScene(0, 0, 1200, 800) self.mapView = QGraphicsView(self.main_scene) # self.mapView.setDragMode(QGraphicsView.DragMode.ScrollHandDrag) self.current_map = "Arcanus" self.button = QPushButton("Switch to Myrror") self.button.clicked.connect(self.the_button_was_clicked) self.setMinimumSize(QSize(150,150)) mapGridLayout.addWidget(self.mapView) mapGridLayout.addWidget(self.button) # for x in range(map_height): # for y in range(map_width): # print(map_square_string(mirror_terrain[y][x]), end='') # print() def plot_map(self, main_data, mirror_data): for y in range(map_height): for x in range(map_width): atile = MapTile(x, y, main_data[x][y]) mtile = MapTile(x, y, mirror_data[x][y]) self.main_scene.addItem(atile) self.mirror_scene.addItem(mtile) self.mapView.show() def the_button_was_clicked(self): print("button clicked") if self.current_map == "Arcanus": self.button.setText("Switch to Arcanus") self.current_map = "Myrror" self.mapView.setScene(self.mirror_scene) self.mapView.show() else: self.button.setText("Switch to Myrror") self.current_map = "Arcanus" self.mapView.setScene(self.main_scene) self.mapView.show() if __name__ == '__main__': with open(savefile, 'rb') as sf: hero_stats = [] for w in range(num_wizards): for h in range(num_heroes): hero_stats.append(sf.read(12)) gamedata = sf.read(16) wizard_data = [] for w in range(num_wizards): wizard_data.append(sf.read(1224)) main_terrain = [ [ 0 for h in range(map_height) ] for w in range(map_width) ] for h in range(map_height): for w in range(map_width): main_terrain[w][h] = unpack("