| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- #!/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))
|