john melesky пре 3 часа
родитељ
комит
1a93f502d7
1 измењених фајлова са 468 додато и 0 уклоњено
  1. 468 0
      mom-save-edit.py

+ 468 - 0
mom-save-edit.py

@@ -0,0 +1,468 @@
+#!/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("<H", sf.read(2))[0]
+        mirror_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):
+                mirror_terrain[w][h] = unpack("<H", sf.read(2))[0]
+        unused = sf.read(192*2)
+        landmass_main = [ [ 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):
+                landmass_main[w][h] = sf.read(1)
+        landmass_mirror = [ [ 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):
+                landmass_mirror[w][h] = sf.read(1)
+        nodes = []
+        for n in range(num_nodes):
+            nodes.append(sf.read(48))
+        fortresses = []
+        for f in range(num_wizards):
+            fortresses.append(sf.read(4))
+        towers = []
+        for t in range(num_wizards):
+            towers.append(sf.read(4))
+        encounter_zones = []
+        for e in range(num_encounters):
+            encounter_zones.append(sf.read(24))
+        items = []
+        for i in range(num_items):
+            items.append(sf.read(50))
+        queued_items = sf.read(50 * 4)
+        merchant_item = sf.read(50)
+        forging_item = sf.read(50)
+        cities = []
+        for c in range(num_cities):
+            cities.append(sf.read(114))
+        units = []
+        for u in range(num_units):
+            units.append(sf.read(32))
+        minerals_main = [ [ 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):
+                minerals_main[w][h] = sf.read(1)
+        minerals_mirror = [ [ 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):
+                minerals_mirror[w][h] = sf.read(1)
+        explored_main = [ [ 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):
+                explored_main[w][h] = sf.read(1)
+        explored_mirror = [ [ 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):
+                explored_mirror[w][h] = sf.read(1)
+        for i in range(12):
+            for h in range(map_height):
+                for w in range(map_width):
+                    throwaway = sf.read(1)
+        events = []
+        for e in range(num_events):
+            events.append(sf.read(2))
+        flags_main = [ [ 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):
+                flags_main[w][h] = sf.read(1)
+        flags_mirror = [ [ 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):
+                flags_mirror[w][h] = sf.read(1)
+        grand_vizer = sf.read(2)
+        items_in_game = sf.read(250)
+        hero_names = []
+        for h in range(num_heroes):
+            hero_names.append(sf.read(16))
+
+
+
+
+
+
+
+
+    for x in sorted(missed_hexes):
+        print(x)
+
+
+
+    app = QApplication(sys.argv)
+
+    window = MainWindow()
+    window.data['main_terrain'] = main_terrain
+    window.data['mirror_terrain'] = mirror_terrain
+    window.show()
+
+    window.plot_map(main_terrain, mirror_terrain)
+
+    app.exec()
+
+
+
+
+#####################################
+# 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("<H", sf.read(2))[0]
+#    mirror_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):
+#            mirror_terrain[w][h] = unpack("<H", sf.read(2))[0]
+#    unused = sf.read(192*2)
+#    landmass_main = [ [ 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):
+#            landmass_main[w][h] = sf.read(1)
+#    landmass_mirror = [ [ 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):
+#            landmass_mirror[w][h] = sf.read(1)
+#    nodes = []
+#    for n in range(num_nodes):
+#        nodes.append(sf.read(48))
+#    fortresses = []
+#    for f in range(num_wizards):
+#        fortresses.append(sf.read(4))
+#    towers = []
+#    for t in range(num_wizards):
+#        towers.append(sf.read(4))
+#    encounter_zones = []
+#    for e in range(num_encounters):
+#        encounter_zones.append(sf.read(24))
+#    items = []
+#    for i in range(num_items):
+#        items.append(sf.read(50))
+#    queued_items = sf.read(50 * 4)
+#    merchant_item = sf.read(50)
+#    forging_item = sf.read(50)
+#    cities = []
+#    for c in range(num_cities):
+#        cities.append(sf.read(114))
+#    units = []
+#    for u in range(num_units):
+#        units.append(sf.read(36))
+#    minerals_main = [ [ 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):
+#            minerals_main[w][h] = sf.read(1)
+#    minerals_mirror = [ [ 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):
+#            minerals_mirror[w][h] = sf.read(1)
+#    explored_main = [ [ 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):
+#            explored_main[w][h] = sf.read(1)
+#    explored_mirror = [ [ 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):
+#            explored_mirror[w][h] = sf.read(1)
+#    for i in range(12):
+#        for h in range(map_height):
+#            for w in range(map_width):
+#                throwaway = sf.read(1)
+#    events = []
+#    for e in range(num_events):
+#        events.append(sf.read(2))
+#    flags_main = [ [ 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):
+#            flags_main[w][h] = sf.read(1)
+#    flags_mirror = [ [ 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):
+#            flags_mirror[w][h] = sf.read(1)
+#    grand_vizer = sf.read(2)
+#    items_in_game = sf.read(250)
+#    hero_names = []
+#    for h in range(num_heroes):
+#        hero_names.append(sf.read(16))