Compare commits

..

No commits in common. "0a1e3e0cad0447bbbfec2cdb65f79a2b21107ea3" and "bd7e1bc15df20ba6261109229d17a6177539bcb0" have entirely different histories.

6 changed files with 4642 additions and 2727 deletions

View File

@ -1,12 +1,3 @@
# OpenMFOR
# credits manually reinstated due to the comments being lost from the object code decompilation
# Original release is Copyright (C) 2022 Kazuto88
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Source Generated with Decompyle++ # Source Generated with Decompyle++
# File: Fusion_Graph.pyc (Python 3.8) # File: Fusion_Graph.pyc (Python 3.8)
@ -14,8 +5,8 @@ import struct
import sys import sys
class Game: class Game:
def __init__(self, vanillaGame, randoSettings=None): def __init__(self, vanillaGame, randoSettings = (None,)):
self.graph = dict() self.graph = dict()
self.areaConnections = dict() self.areaConnections = dict()
self.areaConnectionOffsets = dict() self.areaConnectionOffsets = dict()
@ -40,9 +31,9 @@ class Game:
self.minorItemLocations.clear() self.minorItemLocations.clear()
self.itemLocations.clear() self.itemLocations.clear()
self.patcher.clear() self.patcher.clear()
# print('DEBUG: Opening ROM to pick stuff') # print('DEBUG: Opening ROM to pick stuff')
try: try:
with open(vanillaGame, 'rb') as sourceRom: with open(vanillaGame, 'rb') as sourceRom:
sourceRom.seek(3967888, 0) sourceRom.seek(3967888, 0)
@ -50,7 +41,7 @@ class Game:
sourceDoor = int.from_bytes(sourceRom.read(1), 'little') sourceDoor = int.from_bytes(sourceRom.read(1), 'little')
targetOffset = sourceRom.tell() targetOffset = sourceRom.tell()
targetArea = int.from_bytes(sourceRom.read(1), 'little') targetArea = int.from_bytes(sourceRom.read(1), 'little')
while sourceArea != 255: if sourceArea != 255:
self.areaConnections.update({ self.areaConnections.update({
'S{}-{:02X}'.format(sourceArea, sourceDoor): targetArea }) 'S{}-{:02X}'.format(sourceArea, sourceDoor): targetArea })
self.areaConnectionOffsets.update({ self.areaConnectionOffsets.update({
@ -67,7 +58,7 @@ class Game:
doorData = unpacked[0] - 134217728 doorData = unpacked[0] - 134217728
sourceRom.seek(doorData, 0) sourceRom.seek(doorData, 0)
doorNumber = 0 doorNumber = 0
while True: while True:
connectionType = int.from_bytes(sourceRom.read(1), 'little') connectionType = int.from_bytes(sourceRom.read(1), 'little')
roomNumber = int.from_bytes(sourceRom.read(1), 'little') roomNumber = int.from_bytes(sourceRom.read(1), 'little')
sourceRom.seek(4, 1) sourceRom.seek(4, 1)
@ -91,20 +82,20 @@ class Game:
doorString] doorString]
doorNumber += 1 doorNumber += 1
# print('DEBUG: Parsing seemingly done?') # print('DEBUG: Parsing seemingly done?')
except FileNotFoundError: except:
print('Error:', vanillaGame, 'could not be opened.') print('Error:', vanillaGame, 'could not be opened.')
sys.exit(1) sys.exit(1)
def set_setting(self, setting, value): def set_setting(self, setting, value):
self.settings[setting] = value self.settings[setting] = value
def get_setting(self, setting): def get_setting(self, setting):
return self.settings[setting] return self.settings[setting]
def AddNodeToRoom(self, room, node): def AddNodeToRoom(self, room, node):
nodeList = self.rooms.get(room) nodeList = self.rooms.get(room)
nodeList.append(node) nodeList.append(node)
@ -112,7 +103,7 @@ class Game:
self.rooms.update({ self.rooms.update({
room: nodeList }) room: nodeList })
def RemoveNodeFromRoom(self, room, node): def RemoveNodeFromRoom(self, room, node):
nodeList = self.rooms.get(room) nodeList = self.rooms.get(room)
if node in nodeList: if node in nodeList:
@ -121,17 +112,17 @@ class Game:
self.rooms.update({ self.rooms.update({
room: nodeList }) room: nodeList })
def ClearGraph(self): def ClearGraph(self):
self.graph.clear() self.graph.clear()
def ConnectAllNodes(self): def ConnectAllNodes(self):
self.ClearGraph() self.ClearGraph()
self.ConnectNodesInRooms() self.ConnectNodesInRooms()
self.ConnectNodesBetweenRooms() self.ConnectNodesBetweenRooms()
def ConnectNodesInRooms(self): def ConnectNodesInRooms(self):
for room in self.rooms: for room in self.rooms:
for start in self.rooms[room]: for start in self.rooms[room]:
@ -139,12 +130,12 @@ class Game:
if start != end: if start != end:
self.add_edges(start, end) self.add_edges(start, end)
def ConnectNodesBetweenRooms(self): def ConnectNodesBetweenRooms(self):
for connection in self.doorConnections.items(): for connection in self.doorConnections.items():
if len(connection) == 2: if len(connection) == 2:
self.add_directed_edge(connection[0], connection[1]) self.add_directed_edge(connection[0], connection[1])
def UpdateDoorConnection(self, source, destination): def UpdateDoorConnection(self, source, destination):
self.doorConnections.update({ self.doorConnections.update({
source: destination }) source: destination })
@ -154,7 +145,7 @@ class Game:
source: int(destination[1:2]) }) source: int(destination[1:2]) })
return self.areaConnectionOffsets.get(source) return self.areaConnectionOffsets.get(source)
def AddConnectedNodesToRoom(self, targetRoom, *nodes): def AddConnectedNodesToRoom(self, targetRoom, *nodes):
for currentNode in nodes: for currentNode in nodes:
if targetRoom in self.rooms: if targetRoom in self.rooms:
@ -174,82 +165,86 @@ class Game:
else: else:
self.graph[start] = [ self.graph[start] = [
end] end]
def add_edges(self, start, *nodes): def add_edges(self, start, *nodes):
for end in nodes: for end in nodes:
self.add_directed_edge(start, end) self.add_directed_edge(start, end)
self.add_directed_edge(end, start) self.add_directed_edge(end, start)
def add_to_majors(self, item): def add_to_majors(self, item):
if item not in self.itemLocations: if item not in self.itemLocations:
self.itemLocations.append(item) self.itemLocations.append(item)
if item not in self.majorItemLocations: if item not in self.majorItemLocations:
self.majorItemLocations.append(item) self.majorItemLocations.append(item)
def add_list_to_majors(self, locations): def add_list_to_majors(self, locations):
for item in locations: for item in locations:
if item not in self.itemLocations: if item not in self.itemLocations:
self.itemLocations.append(item) self.itemLocations.append(item)
if item not in self.majorItemLocations: if item not in self.majorItemLocations:
self.majorItemLocations.append(item) self.majorItemLocations.append(item)
def add_to_minors(self, item): def add_to_minors(self, item):
if item not in self.itemLocations: if item not in self.itemLocations:
self.itemLocations.append(item) self.itemLocations.append(item)
if item not in self.minorItemLocations: if item not in self.minorItemLocations:
self.minorItemLocations.append(item) self.minorItemLocations.append(item)
def add_list_to_minors(self, locations): def add_list_to_minors(self, locations):
for item in locations: for item in locations:
if item not in self.itemLocations: if item not in self.itemLocations:
self.itemLocations.append(item) self.itemLocations.append(item)
if item not in self.minorItemLocations: if item not in self.minorItemLocations:
self.minorItemLocations.append(item) self.minorItemLocations.append(item)
def get_requirements(self, start, end): def get_requirements(self, start, end):
checkRequirement = (start, end) checkRequirement = (start, end)
return self.requirements.get(checkRequirement) return self.requirements.get(checkRequirement)
def get_path(self, start, end, LimitArea=False, path=None, depth=100): def get_path(self, start, end, LimitArea, path, depth = (False, None, 100)):
if path == None: if path == None:
self.visited.clear() self.visited.clear()
self.queue.clear() self.queue.clear()
path = list() path = list()
path = path + [start] path = path + [
start]
if start not in self.graph: if start not in self.graph:
return None return None
if start == end: if None == end:
return path return path
if len(path) >= depth: # if None(path) >= depth:
if path >= depth:
return None return None
for point in self.graph[start]: for point in None.graph[start]:
if point in self.itemLocations: if point in self.itemLocations and point not in end:
if point not in end: continue
continue
if point in path: if point in path:
continue continue
if LimitArea: if LimitArea:
for area in range(0, 7): for area in range(0, 7):
if 'S{}'.format(area) in start: if 'S{}'.format(area) in start and 'S{}'.format(area) not in point:
if 'S{}'.format(area) not in point: return None
return None edge = (start, point)
edge = (start, point) self.queue.append(edge)
self.queue.append(edge) if self.queue:
while self.queue: edge = self.queue.pop()
edge = self.queue.pop() if edge not in self.visited:
if edge not in self.visited: self.visited.append(edge)
self.visited.append(edge) node = edge[1]
node = edge[1] pathReqs = self.get_requirements(start, node)
pathReqs = self.get_requirements(start, node) if pathReqs == None:
if pathReqs == None: newpath = self.get_path(node, end, LimitArea, path, depth)
newpath = self.get_path(node, end, LimitArea, path, depth) if newpath:
if newpath: path = path + [
path = path + [node] node]
return newpath return newpath
elif pathReqs == True: if pathReqs == True:
newpath = self.get_path(node, end, LimitArea, path, depth) newpath = self.get_path(node, end, LimitArea, path, depth)
if newpath: if newpath:
path = path + [node] path = path + [
return newpath node]
return newpath

View File

@ -1,12 +1,3 @@
# OpenMFOR
# credits manually reinstated due to the comments being lost from the object code decompilation
# Original release is Copyright (C) 2022 Kazuto88
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Source Generated with Decompyle++ # Source Generated with Decompyle++
# File: Fusion_Items.pyc (Python 3.8) # File: Fusion_Items.pyc (Python 3.8)

9
GUI.py
View File

@ -1,12 +1,3 @@
# OpenMFOR
# credits manually reinstated due to the comments being lost from the object code decompilation
# Original release is Copyright (C) 2022 Kazuto88
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Source Generated with Decompyle++ # Source Generated with Decompyle++
# File: GUI.pyc (Python 3.8) # File: GUI.pyc (Python 3.8)

View File

@ -1,12 +1,3 @@
# OpenMFOR
# credits manually reinstated due to the comments being lost from the object code decompilation
# Original release is Copyright (C) 2022 Kazuto88
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Source Generated with Decompyle++ # Source Generated with Decompyle++
# File: MFOR.pyc (Python 3.8) # File: MFOR.pyc (Python 3.8)

View File

@ -4,23 +4,13 @@ This is the official unofficial Git repository for the Metroid Fusion Open Rando
Considering the original repository states that the software is GPL-3.0 licensed, but no source was ever released, we're endeavouring on this (potentially failing) task of making MFOR Open Again Considering the original repository states that the software is GPL-3.0 licensed, but no source was ever released, we're endeavouring on this (potentially failing) task of making MFOR Open Again
## Links
* [OpenMFOR repository][] (This project, in case you are looking at a fork)
* The [original MFOR repository][] on Github
* The [original MFOR thread][] on Metroid Construction
[OpenMFOR]: https://git.inabaudonge.reisen/OpenMFOR/OpenMFOR
[original MFOR repository]: https://github.com/Kazuto88/MFOR
[original MFOR thread]: https://forum.metroidconstruction.com/index.php/topic,5376.0.html
## Project Status ## Project Status
- [x] Decent disassembly - [x] Decent disassembly
- [x] GUI - [x] GUI
- [x] CRC verification - [x] CRC verification
- [x] Logic - [ ] Logic
- [x] Reconstructing missing parts of code - [ ] Reconstructing missing parts of code
- [x] Patching - [x] Patching
- [ ] Generating BPS patches - [ ] Generating BPS patches

File diff suppressed because it is too large Load Diff