OpenMFOR/Randomizer.py

5109 lines
199 KiB
Python

# 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++
# File: Randomizer.pyc (Python 3.8)
import struct
import random
import time
import re
import sys
import argparse
import json
import os
import zlib
import math
import Fusion_Graph as Graph
from Fusion_Items import *
from bps.apply import apply_to_files
from bps.diff import diff_bytearrays
from bps.io import write_bps
from bps.util import bps_progress
version = '0.11.6'
# FIXME: Debug should not be set here
# Debug = False
def ceiling(num, denom):
return -(num // -denom)
def fileHash(fileName):
with open(fileName, 'rb') as fh:
hash = 0
while True:
s = fh.read(65536)
if not s:
break
hash = zlib.crc32(s, hash)
return (hash & 0xFFFFFFFF)
def enable_item(graph, item):
globals()[item] = True
update_items(graph)
update_requirements(graph)
def disable_item(graph, item):
globals()[item] = False
update_items(graph)
update_requirements(graph)
def update_items(graph):
global BombJump
global Diffusion
global HiJump
global IBJ
global Ice
global IceMissiles
global MissileDamage
global Missiles
global PowerBombs
global SpringBall
global SuperMissiles
global UseBombs
global WallJump
if SeedSettings['MissilesWithoutMainData'] == True:
Missiles = MainMissiles or SuperMissileItem or IceMissileItem or DiffusionItem
else:
Missiles = MainMissiles
SuperMissiles = Missiles and SuperMissileItem
IceMissiles = Missiles and IceMissileItem
Diffusion = Missiles and DiffusionItem
Ice = IceMissiles or IceBeam
HiJump = HiJumpBoots or SpaceJump
SpringBall = HiJumpBoots
WallJump = SpaceJump or WallJumpSetting
if SeedSettings['PowerBombsWithoutBombs'] == True:
PowerBombs = MorphBall and MainPowerBombs
else:
PowerBombs = MorphBall and Bombs and MainPowerBombs
UseBombs = MorphBall and (Bombs or PowerBombs)
BombJump = MorphBall and (Bombs or SpringBall)
IBJ = MorphBall and Bombs and InfiniteBombJump
MissileDamage = 0
if Missiles:
if MainMissiles:
MissileDamage += 10
if IceMissiles:
MissileDamage += 10
if SuperMissiles:
MissileDamage += 20
if Diffusion:
MissileDamage += 5
def update_requirements(graph):
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and PowerBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall or PowerBombs:
pass
if not MorphBall or PowerBombs:
pass
if MorphBall:
pass
if not Missiles:
pass
if not Missiles:
pass
if not Missiles:
pass
if not Missiles and RedDoors and HiJump and WallJump:
pass
if not RedDoors and HiJump and WallJump:
pass
if not RedDoors and HiJump and WallJump:
pass
if not RedDoors and HiJump and WallJump:
pass
if GreenDoors:
if not ((HiJump or Ice) and Missiles or ChargeBeam) and SpaceJump and WallJump:
pass
if GreenDoors:
if not (HiJump and Ice and Missiles or ChargeBeam) and SpaceJump and WallJump:
pass
if GreenDoors:
if not ((HiJump or Ice) and Missiles or ChargeBeam) and SpaceJump and WallJump:
pass
if GreenDoors:
if not ((HiJump or Ice) and Missiles or ChargeBeam) and SpaceJump and WallJump:
pass
if GreenDoors:
if not ((HiJump or Ice) and Missiles or ChargeBeam) and SpaceJump and WallJump:
pass
if GreenDoors:
if not ((HiJump or Ice) and Missiles or ChargeBeam) and SpaceJump and WallJump:
pass
if PowerBombs:
pass
if not MorphBall and UseBombs:
pass
if PowerBombs:
pass
if not MorphBall and UseBombs:
pass
if PowerBombs:
pass
if not MorphBall and UseBombs:
pass
if PowerBombs:
pass
if not MorphBall and UseBombs:
pass
if not MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and PowerBombs:
pass
if not MorphBall and ScrewAttack and BombJump and HiJump and WallJump:
pass
if not MorphBall and ScrewAttack and BombJump and HiJump and WallJump:
pass
if MorphBall and ScrewAttack:
pass
if MorphBall and ScrewAttack:
pass
if MorphBall and ScrewAttack:
pass
if MorphBall and ScrewAttack:
pass
if not MorphBall and ScrewAttack and BombJump and HiJump and WallJump:
pass
if not MorphBall and ScrewAttack and BombJump and HiJump and WallJump:
pass
if not Missiles and PowerBombs:
pass
if not Missiles and PowerBombs:
pass
if not Missiles and PowerBombs:
pass
if not Missiles and PowerBombs:
pass
if not Missiles and PowerBombs:
pass
if not Missiles and PowerBombs:
pass
if not Ice:
if not (Missiles and ChargeBeam or ScrewAttack) and SpaceJump and WallJump:
pass
if MorphBall and SpeedBooster:
pass
if not MorphBall:
pass
if not MorphBall:
pass
if MorphBall and SpeedBooster:
pass
if (Missiles or ChargeBeam) and MorphBall:
pass
if not Missiles and PowerBombs:
pass
if not Missiles and PowerBombs:
pass
if not Missiles:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and UseBombs and SpaceJump and WallJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and UseBombs and SpaceJump and WallJump:
pass
if not MorphBall and UseBombs and SpaceJump and WallJump:
pass
if not MorphBall and UseBombs and SpaceJump and WallJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and SpaceJump:
pass
if not MorphBall and SpaceJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not SpaceJump:
pass
if not MorphBall and SpaceJump:
pass
if not SpaceJump:
pass
if not MorphBall and SpaceJump:
pass
if not SpaceJump:
pass
if not MorphBall and SpaceJump:
pass
if MorphBall:
pass
if not MorphBall and ScrewAttack and SpaceJump:
pass
if not SpeedBooster:
pass
if not SpeedBooster:
pass
if Missiles and ChargeBeam:
pass
if not Missiles and ChargeBeam and PlasmaBeam and RedDoors and HiJump and WallJump:
pass
if not Missiles and SpeedBooster and PowerBombs:
pass
if not Missiles and SpeedBooster and PowerBombs:
pass
if Missiles and ChargeBeam and PowerBombs and ScrewAttack and SpeedBooster:
pass
if Missiles and ChargeBeam and PowerBombs and ScrewAttack and SpeedBooster:
pass
if not (Missiles or MorphBall) and ChargeBeam and PowerBombs:
pass
if (Missiles or MorphBall) and ChargeBeam and PowerBombs and ScrewAttack and SpeedBooster:
pass
if Missiles:
pass
if Missiles:
pass
if Missiles:
pass
if Missiles:
pass
if not Missiles and ChargeBeam and PowerBombs:
pass
if not Missiles and ChargeBeam and PowerBombs:
pass
if not Missiles and ChargeBeam and PowerBombs:
pass
if not Missiles and ChargeBeam and PowerBombs:
pass
if Missiles and ChargeBeam and PowerBombs and ScrewAttack and SpeedBooster:
pass
if Missiles and ChargeBeam and PowerBombs and ScrewAttack and SpeedBooster:
pass
if Missiles and ChargeBeam and PowerBombs and ScrewAttack and SpeedBooster:
pass
if Missiles and ChargeBeam and PowerBombs and ScrewAttack and SpeedBooster:
pass
if SpaceJump:
pass
if SpaceJump:
pass
if not DamageRuns or Energy >= 199:
pass
if DamageRuns or Energy >= 99 or GravitySuit:
pass
if MorphBall:
pass
if MorphBall:
pass
if DamageRuns or Energy >= 99 or GravitySuit:
pass
if MorphBall:
pass
if DamageRuns or Energy >= 99 or GravitySuit:
pass
if (DamageRuns or Energy >= 99 or GravitySuit) and MorphBall:
pass
if MorphBall and ScrewAttack:
pass
if (DamageRuns or Energy >= 99 or GravitySuit) and MorphBall and ScrewAttack:
pass
if Missiles and MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if Missiles and MorphBall:
pass
if Missiles:
pass
if Missiles:
pass
if Missiles:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not Missiles and MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not Missiles and MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not Missiles and MorphBall and UseBombs and HiJump and WallJump:
pass
if MorphBall and UseBombs:
if not (PowerBombs or WaveBeam) and Missiles and ChargeBeam:
pass
if MorphBall:
pass
if not Missiles:
pass
if not MorphBall and ScrewAttack and SpaceJump:
pass
if not MorphBall and ScrewAttack and SpaceJump:
pass
if MorphBall:
pass
if not Missiles:
pass
if MorphBall and SpaceJump:
pass
if MorphBall and WaveBeam and SpaceJump:
pass
if Missiles or ChargeBeam:
pass
if MorphBall:
pass
if not Missiles:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if (Missiles or ChargeBeam) and MorphBall:
pass
if not (ChargeBeam or WaveBeam or PowerBombs) and Missiles:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and PowerBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if ScrewAttack:
pass
if MorphBall:
pass
if MorphBall and UseBombs and SpringBall:
pass
if not MorphBall or UseBombs:
pass
if not MorphBall and UseBombs or SpringBall:
pass
if not MorphBall and UseBombs and WaveBeam and HiJump and WallJump:
pass
if not MorphBall and HiJump and WallJump:
pass
if not Missiles:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not Missiles:
pass
if not Missiles:
pass
if not SpaceJump:
pass
if not ScrewAttack and SpaceJump and WallJump:
pass
if not ScrewAttack and SpaceJump and WallJump:
pass
if ScrewAttack:
pass
if not ScrewAttack and SpaceJump:
pass
if not MorphBall and UseBombs:
pass
if not MorphBall and UseBombs:
pass
if MorphBall:
if not UseBombs or SpringBall:
if (UseBombs or ScrewAttack) and SpringBall:
pass
if MorphBall:
if not UseBombs or SpringBall:
if (UseBombs or ScrewAttack or SpringBall) and ScrewAttack:
pass
if not MorphBall and UseBombs:
pass
if not MorphBall and UseBombs:
pass
if MorphBall:
if not UseBombs or SpringBall:
if (UseBombs or ScrewAttack) and SpringBall:
pass
if MorphBall:
if not UseBombs or SpringBall:
if (UseBombs or ScrewAttack or SpringBall) and ScrewAttack:
pass
if not SpeedBooster and SpaceJump:
pass
if not MorphBall and SpeedBooster and SpaceJump:
pass
if not SpeedBooster and SpaceJump:
pass
if not SpeedBooster and SpaceJump:
pass
if not SpeedBooster and SpaceJump:
pass
if not SpeedBooster and SpaceJump:
pass
if not MorphBall and SpeedBooster and SpaceJump:
pass
if not SpeedBooster and SpaceJump:
pass
if not SpeedBooster and SpaceJump:
pass
if not SpeedBooster and SpaceJump:
pass
if not MorphBall and SpeedBooster and SpaceJump and WallJump:
pass
if not MorphBall and SpeedBooster and SpaceJump and WallJump:
pass
if not MorphBall and Ice and SpaceJump:
pass
if not MorphBall and UseBombs and WaveBeam:
pass
if not MorphBall and Ice and UseBombs and WaveBeam and GravitySuit and HiJump and WallJump:
pass
if not MorphBall or UseBombs:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and HiJump and WallJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and HiJump and WallJump:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and HiJump and WallJump:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and HiJump and WallJump:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and HiJump and WallJump:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if not MorphBall and HiJump and WallJump:
pass
if MorphBall:
pass
if not SpaceJump and WallJump:
pass
if not SpaceJump and WallJump:
pass
if not SpaceJump and WallJump:
pass
if not SpaceJump and WallJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if Missiles:
pass
if not MorphBall:
pass
if not MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and ScrewAttack and SpeedBooster and Ice:
pass
if not MorphBall and ScrewAttack and SpeedBooster and Ice:
pass
if not MorphBall and ScrewAttack and SpeedBooster and Ice:
pass
if not MorphBall and ScrewAttack and SpeedBooster and Ice:
pass
if SpeedBooster:
pass
if MorphBall and UseBombs and BombJump:
pass
if MorphBall and UseBombs and BombJump:
pass
if MorphBall:
pass
if SuperMissiles and PowerBombs or ScrewAttack:
pass
if not MorphBall and SuperMissiles and PowerBombs:
pass
if not MorphBall and ScrewAttack and UseBombs and SuperMissiles:
pass
if SuperMissiles and PowerBombs or ScrewAttack:
pass
if not MorphBall and UseBombs:
pass
if MorphBall:
if not SpringBall or ScrewAttack:
if BombJump or PowerBombs or UseBombs:
if SuperMissiles and PowerBombs or ScrewAttack:
pass
if MorphBall:
if not UseBombs:
if (SpringBall or ScrewAttack or BombJump) and PowerBombs:
pass
if not MorphBall and UseBombs:
pass
if not MorphBall and UseBombs and HiJump and WallJump:
pass
if MorphBall:
if not UseBombs or SpringBall:
pass
if SpeedBooster and SpaceJump or IBJ:
pass
if SpeedBooster and SpaceJump or IBJ:
pass
if SpeedBooster and SpaceJump or IBJ:
pass
if VariaSuit:
pass
if Missiles and ChargeBeam and Ice or ScrewAttack:
pass
if not Ice and SpaceJump:
if Missiles and ChargeBeam or ScrewAttack:
pass
if Missiles and ChargeBeam or ScrewAttack:
pass
if Missiles and ChargeBeam or ScrewAttack:
pass
if not Missiles:
pass
if VariaSuit:
pass
if GravitySuit and WaveBeam:
pass
if GravitySuit:
pass
if GravitySuit:
pass
if GravitySuit:
pass
if ChargeBeam or Difficulty > 0:
pass
if not ChargeBeam:
pass
if not SpaceJump:
if ChargeBeam or Difficulty > 0:
pass
if not ChargeBeam:
pass
if not SpaceJump:
if ChargeBeam or Difficulty > 0:
pass
if ChargeBeam or Difficulty > 0:
pass
if not MorphBall and SuperMissiles and PowerBombs:
pass
if not MorphBall and UseBombs and SuperMissiles and PowerBombs:
pass
if MorphBall and UseBombs:
if SuperMissiles and PowerBombs or ScrewAttack:
pass
if MorphBall:
pass
if not VariaSuit and DamageRuns and Energy >= 199:
pass
if not VariaSuit and DamageRuns and Energy >= 199 and SpeedBooster and UseBombs:
pass
if MorphBall or UseBombs or ScrewAttack:
pass
if (HiJump or Ice) and SpaceJump and IBJ and MorphBall and UseBombs and Missiles and SpeedBooster:
pass
if not MorphBall or UseBombs:
pass
if MorphBall or UseBombs or ScrewAttack:
if (HiJump or Ice) and SpaceJump and IBJ and Missiles and SpeedBooster:
pass
if MorphBall or UseBombs or ScrewAttack:
pass
if GravitySuit:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam:
pass
if MorphBall:
if WaterLowered or DamageRuns:
if (Diffusion or WaveBeam) and IceBeam:
pass
if not WaterLowered:
pass
if MorphBall and Diffusion and WaveBeam:
pass
if not RedDoors and WaterLowered:
pass
if MorphBall:
if (WaterLowered or DamageRuns) and Diffusion and WaveBeam:
pass
if MorphBall:
if (WaterLowered or DamageRuns) and Diffusion and WaveBeam:
pass
if not RedDoors and WaterLowered:
pass
if MorphBall:
if (WaterLowered or DamageRuns) and Diffusion and WaveBeam:
pass
if not WaterLowered:
pass
if MorphBall:
if WaterLowered or DamageRuns:
if (Diffusion or WaveBeam) and IceBeam:
pass
if MorphBall:
if WaterLowered or DamageRuns:
if (Diffusion or WaveBeam) and IceBeam:
pass
if MorphBall:
pass
if MorphBall and UseBombs and SpeedBooster and WaterLowered and DamageRuns:
pass
if MorphBall:
pass
if SpeedBooster and MorphBall:
if not (UseBombs or PowerBombs) and SpaceJump and WallJump:
pass
if SpeedBooster and WaterLowered and DamageRuns:
pass
if SpeedBooster and WaterLowered and DamageRuns:
pass
if SpeedBooster and WaterLowered and DamageRuns:
pass
if SpeedBooster and WaterLowered and DamageRuns:
pass
if SpeedBooster and MorphBall:
if not (UseBombs or PowerBombs) and SpaceJump and WallJump:
pass
if SpeedBooster and WaterLowered and DamageRuns:
pass
if not Missiles:
pass
if not GravitySuit and SpeedBooster:
pass
if not GravitySuit and SpeedBooster:
pass
if not GravitySuit and SpaceJump:
pass
if not MorphBall and GravitySuit and SpaceJump:
pass
if not GravitySuit and SpaceJump:
pass
if not GravitySuit and SpaceJump:
pass
if not GravitySuit and SpaceJump:
pass
if not MorphBall and GravitySuit and SpaceJump:
pass
if not GravitySuit and SpaceJump:
pass
if not GravitySuit and SpaceJump:
pass
if GravitySuit:
pass
if MorphBall and GravitySuit:
pass
if MorphBall:
if (GravitySuit or ScrewAttack) and Ice:
if not BombJump or GravitySuit:
pass
if MorphBall and GravitySuit:
pass
if GravitySuit:
pass
if GravitySuit:
pass
if MorphBall:
if (GravitySuit or ScrewAttack) and Diffusion:
if not BombJump or GravitySuit:
pass
if not GravitySuit and SpeedBooster:
pass
if MorphBall:
if (GravitySuit or ScrewAttack) and Diffusion:
if not BombJump or GravitySuit:
pass
if GravitySuit:
pass
if MorphBall and Ice:
if (UseBombs or GravitySuit) and SpringBall and GravitySuit:
pass
if not MorphBall and UseBombs:
if (HiJump or SpeedBooster) and WaterLowered and DamageRuns:
pass
if SpeedBooster and WaterLowered and DamageRuns:
pass
if MorphBall and UseBombs and ScrewAttack:
if (HiJump or SpeedBooster) and WaterLowered and DamageRuns:
pass
if not MorphBall and UseBombs and WaterLowered:
pass
if MorphBall and SpeedBooster and WaterLowered and DamageRuns:
pass
if not MorphBall or UseBombs:
pass
if SpeedBooster and WaterLowered and DamageRuns:
pass
if MorphBall and SpeedBooster and WaterLowered and DamageRuns:
pass
if MorphBall:
if (UseBombs or ScrewAttack) and SpeedBooster and WaterLowered and DamageRuns:
pass
if not MorphBall and UseBombs and ScrewAttack and WaterLowered:
pass
if not MorphBall or UseBombs:
pass
if MorphBall:
if (UseBombs or ScrewAttack) and SpeedBooster and WaterLowered and DamageRuns:
pass
if WaterLowered or DamageRuns:
pass
if not WaterLowered:
pass
if not MorphBall and WaterLowered:
pass
if WaterLowered or DamageRuns:
pass
if WaterLowered or DamageRuns:
pass
if WaterLowered or DamageRuns:
pass
if MorphBall:
pass
if SpeedBooster:
pass
if MorphBall and GravitySuit:
pass
if HiJump or GravitySuit:
pass
if SpeedBooster:
pass
if MorphBall and GravitySuit:
pass
if MorphBall and GravitySuit and ScrewAttack:
pass
if MorphBall and SpeedBooster and GravitySuit:
pass
if MorphBall and GravitySuit:
pass
if Missiles and MorphBall:
if (UseBombs or SpringBall) and GravitySuit and GravitySuit:
pass
if Missiles and MorphBall:
if (UseBombs or SpringBall) and GravitySuit and GravitySuit:
pass
if Missiles and MorphBall:
if (UseBombs or GravitySuit) and ScrewAttack:
pass
if Missiles and MorphBall and UseBombs and GravitySuit:
pass
if MorphBall and SpringBall and UseBombs:
pass
if GravitySuit:
pass
if MorphBall and GravitySuit:
pass
if MorphBall and SpringBall and UseBombs:
pass
if MorphBall and GravitySuit:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not HiJumpBoots:
pass
if not HiJumpBoots:
pass
if MorphBall and UseBombs and GravitySuit:
pass
if (MorphBall or UseBombs) and GravitySuit:
pass
if MorphBall and UseBombs and GravitySuit:
pass
if GravitySuit:
pass
if MorphBall:
pass
if MorphBall and Diffusion and GravitySuit:
pass
if MorphBall:
pass
if Missiles and MorphBall and GravitySuit and SpaceJump and HiJump:
pass
if GravitySuit:
pass
if Missiles and MorphBall and GravitySuit and SpaceJump and HiJump:
pass
if not Missiles and MorphBall and GravitySuit and ScrewAttack and SpaceJump:
pass
if not GravitySuit and ScrewAttack and SpaceJump:
pass
if not Missiles and MorphBall and GravitySuit and ScrewAttack and SpaceJump:
pass
if Missiles:
pass
if Missiles:
pass
if Missiles and MorphBall and GravitySuit:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall and GravitySuit:
pass
if MorphBall and GravitySuit:
pass
if MorphBall:
if (PowerBombs and WaveBeam or ChargeBeam) and Difficulty >= 1 and Missiles and ChargeBeam:
pass
if Missiles:
pass
if Missiles:
pass
if Missiles:
pass
if Missiles and MorphBall:
pass
if Missiles and MorphBall:
pass
if Missiles and MorphBall:
pass
if not (HiJump or Ice) and SpaceJump:
pass
if not (HiJump or Ice) and SpaceJump:
pass
if not (HiJump or Ice) and SpaceJump:
pass
if not (HiJump or Ice) and SpaceJump:
pass
if not (HiJump or Ice) and SpaceJump:
pass
if not (HiJump or Ice) and SpaceJump:
pass
if MorphBall and UseBombs and SpeedBooster:
pass
if MorphBall and VariaSuit and PowerBombs and UseBombs:
pass
if SpeedBooster and VariaSuit:
pass
if MorphBall and UseBombs and SpeedBooster:
pass
if MorphBall and VariaSuit and PowerBombs and UseBombs:
pass
if SpeedBooster and VariaSuit:
pass
if MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if MorphBall and VariaSuit and PowerBombs and UseBombs:
pass
if MorphBall and UseBombs and VariaSuit:
pass
if MorphBall and UseBombs and SpeedBooster:
pass
if MorphBall and VariaSuit and PowerBombs and UseBombs:
pass
if SpeedBooster and VariaSuit:
pass
if MorphBall and VariaSuit and PowerBombs and UseBombs:
pass
if MorphBall and VariaSuit and PowerBombs and UseBombs:
pass
if MorphBall and SpeedBooster and VariaSuit and PowerBombs and UseBombs:
pass
if MorphBall and VariaSuit and PowerBombs and UseBombs:
pass
if MorphBall and SpeedBooster and VariaSuit and YellowDoors and PowerBombs and UseBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if MorphBall and VariaSuit and PowerBombs and UseBombs:
pass
if VariaSuit:
pass
if VariaSuit:
pass
if VariaSuit:
pass
if MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if VariaSuit:
pass
if MorphBall and BombJump:
pass
if VariaSuit and SpaceJump:
pass
if not VariaSuit and Ice:
pass
if MorphBall and BombJump:
pass
if VariaSuit and SpaceJump:
pass
if not MorphBall and VariaSuit and Ice:
pass
if MorphBall and VariaSuit:
pass
if MorphBall and VariaSuit and SpaceJump:
pass
if not VariaSuit and Ice:
pass
if VariaSuit:
pass
if MorphBall and BombJump:
pass
if MorphBall and UseBombs and SpeedBooster:
pass
if MorphBall and PowerBombs and UseBombs:
pass
if SpeedBooster and GravitySuit:
pass
if not HiJump:
pass
if MorphBall and UseBombs and SpeedBooster:
pass
if MorphBall:
if not (PowerBombs or UseBombs) and ScrewAttack and HiJump:
pass
if SpeedBooster and GravitySuit:
pass
if not HiJump:
pass
if not HiJump:
pass
if MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
if (PowerBombs or UseBombs) and ScrewAttack:
pass
if MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if MorphBall and PowerBombs and UseBombs:
pass
if MorphBall and PowerBombs and UseBombs:
pass
if MorphBall:
if (PowerBombs or UseBombs) and ScrewAttack and SpeedBooster:
pass
if MorphBall:
if (PowerBombs or UseBombs) and ScrewAttack and SpeedBooster and GravitySuit:
pass
if MorphBall and PowerBombs and UseBombs:
pass
if MorphBall and PowerBombs and UseBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
if (PowerBombs or UseBombs) and ScrewAttack:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and UseBombs and SpeedBooster:
pass
if MorphBall and PowerBombs and UseBombs:
pass
if SpeedBooster and GravitySuit:
pass
if MorphBall and UseBombs and SpeedBooster:
pass
if MorphBall and PowerBombs and UseBombs:
pass
if SpeedBooster and GravitySuit:
pass
if not SpaceJump:
pass
if not SpaceJump:
pass
if MorphBall:
pass
if not HiJump:
pass
if not MorphBall and PowerBombs and HiJump:
pass
if not HiJump:
pass
if not HiJump:
pass
if not HiJump:
pass
if not MorphBall and PowerBombs and HiJump:
pass
if not HiJump:
pass
if not HiJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not Missiles:
pass
if MorphBall and PowerBombs:
pass
if not MorphBall and PowerBombs and VariaSuit and Ice and SpaceJump:
pass
if MorphBall and PowerBombs:
pass
if not MorphBall and PowerBombs and VariaSuit and Ice and SpaceJump:
pass
if MorphBall and PowerBombs:
pass
if MorphBall and PowerBombs:
pass
if not MorphBall and PowerBombs and VariaSuit and Ice and SpaceJump:
pass
if MorphBall and PowerBombs:
pass
if MorphBall and PowerBombs:
pass
if MorphBall and PowerBombs:
pass
if MorphBall:
pass
if not SpaceJump:
pass
if not (HiJump or Ice) and SpaceJump:
pass
if MorphBall:
pass
if not SpaceJump:
pass
if not (HiJump or Ice) and SpaceJump:
pass
if MorphBall:
pass
if not SpaceJump:
pass
if MorphBall:
pass
if SpeedBooster:
pass
if SpeedBooster:
pass
if ScrewAttack:
pass
if SpeedBooster and VariaSuit:
pass
if MorphBall:
pass
if MorphBall:
pass
if VariaSuit:
pass
if MorphBall and BombJump:
pass
if not VariaSuit and Ice:
pass
if MorphBall and BombJump:
pass
if not MorphBall and VariaSuit and Ice:
pass
if MorphBall and VariaSuit:
pass
if Missiles and MorphBall:
pass
if not Missiles and MorphBall and GravitySuit and ScrewAttack and SpaceJump:
pass
if Missiles:
pass
if not GravitySuit and ScrewAttack and SpaceJump:
pass
if Missiles and MorphBall:
pass
if SpeedBooster:
pass
if SpeedBooster:
pass
if SuperMissiles and PowerBombs and ScrewAttack and SpeedBooster:
pass
if MorphBall:
pass
if MorphBall and UseBombs and SuperMissiles and PowerBombs and ScrewAttack and SpeedBooster:
pass
if not SuperMissiles and PowerBombs:
pass
if not MorphBall and UseBombs and SuperMissiles and PowerBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and UseBombs and SuperMissiles and PowerBombs:
pass
if not MorphBall and UseBombs and SuperMissiles and PowerBombs:
pass
if not MorphBall and UseBombs and SuperMissiles and PowerBombs:
pass
if MorphBall:
pass
if not MorphBall and UseBombs and SuperMissiles and PowerBombs:
pass
if SpeedBooster:
pass
if not SpeedBooster and ScrewAttack and VariaSuit:
pass
if not VariaSuit:
pass
if not VariaSuit:
pass
if not MorphBall and PowerBombs and VariaSuit:
pass
if not MorphBall and PowerBombs and RedDoors and VariaSuit:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if Missiles and ChargeBeam:
pass
if SpeedBooster:
pass
if MorphBall:
pass
if HiJump:
pass
if not HiJump and WallJump:
pass
if not HiJump and WallJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not VariaSuit:
pass
if not VariaSuit:
pass
if not VariaSuit:
pass
if not VariaSuit:
pass
if not VariaSuit:
pass
if not VariaSuit:
pass
if not VariaSuit:
pass
if not VariaSuit:
pass
if SpeedBooster and RedDoors:
pass
if SpeedBooster and RedDoors:
pass
if SpeedBooster:
pass
if SpeedBooster and RedDoors:
pass
if SpeedBooster:
pass
if SpeedBooster:
pass
if Missiles and MorphBall:
pass
if MorphBall:
pass
if Missiles and MorphBall:
pass
if Missiles and MorphBall:
pass
if MorphBall:
pass
if Missiles:
pass
if Missiles and MorphBall:
pass
if Missiles:
pass
if not MorphBall and PowerBombs and BombJump:
pass
if MorphBall:
pass
if not MorphBall and PowerBombs and BombJump:
pass
if (Missiles or ChargeBeam) and MorphBall:
pass
if (Missiles or ChargeBeam) and MorphBall:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if Missiles and ChargeBeam:
pass
if not Missiles and ChargeBeam:
pass
if not SpaceJump:
pass
if not SpaceJump:
pass
if not SpaceJump:
pass
if not SpaceJump:
pass
if not Missiles and ChargeBeam:
pass
if not GravitySuit or SpaceJump:
if (SpeedBooster or Difficulty > 0) and DamageRuns:
pass
if GravitySuit and DamageRuns:
pass
if MorphBall and GravitySuit and DamageRuns:
if not Energy >= 299 or VariaSuit:
pass
if GreenDoors and GravitySuit and DamageRuns:
pass
if GravitySuit and SpaceJump and DamageRuns:
pass
if SpaceJump and SpeedBooster:
pass
if MorphBall and GravitySuit and DamageRuns:
if not Energy >= 199 or VariaSuit:
pass
if GreenDoors and GravitySuit and DamageRuns:
pass
if MorphBall and GreenDoors and GravitySuit and DamageRuns:
if not Energy >= 299 or VariaSuit:
pass
if MorphBall and GravitySuit and DamageRuns:
if not Energy >= 199 or VariaSuit:
pass
if not Missiles and Difficulty > 4:
if (Difficulty > 3 or ChargeBeam) and ChargeBeam:
pass
if not SpaceJump and WallJump:
pass
if not Missiles and MorphBall and Diffusion and Ice:
pass
if not Missiles and MorphBall and Diffusion and Ice:
pass
if not Missiles and MorphBall and Diffusion and Ice:
pass
if MorphBall:
pass
if MorphBall:
pass
if not Missiles and MorphBall and Diffusion and Ice:
pass
if MorphBall:
pass
if MorphBall:
pass
if HiJump:
pass
if MorphBall:
if (SpaceJump or HiJump) and WallJump:
pass
if ScrewAttack:
pass
if MorphBall and BombJump and ScrewAttack:
pass
if MorphBall:
pass
if Missiles or ChargeBeam:
pass
if Missiles:
pass
if MorphBall and BombJump and SpeedBooster:
pass
if MorphBall and BombJump and SpeedBooster:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if not Missiles:
pass
if not (Missiles or ChargeBeam) and ScrewAttack and SpaceJump and WallJump:
pass
if not HiJump and WallJump:
pass
if not ScrewAttack and SpaceJump and WallJump:
pass
if not (Missiles or ChargeBeam) and ScrewAttack and HiJump and WallJump:
pass
if Missiles:
pass
if not Missiles and ChargeBeam:
pass
if not Missiles and ChargeBeam:
pass
if MorphBall:
if not (UseBombs or SpringBall) and GravitySuit:
pass
if MorphBall:
if not (UseBombs or SpringBall) and GravitySuit:
pass
if not ScrewAttack and SpaceJump and WallJump:
pass
if not SpaceJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and UseBombs and BombJump:
pass
if MorphBall:
pass
if not MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if not MorphBall and UseBombs:
pass
if MorphBall:
pass
if not MorphBall and UseBombs and BombJump:
pass
if not HiJump and IBJ and Ice and SpeedBooster:
pass
if MorphBall:
if not (UseBombs or WaveBeam or HiJump) and SpaceJump and GravitySuit and Ice and SpaceJump and WallJump:
pass
if not MorphBall and Ice and UseBombs and WaveBeam and GravitySuit and HiJump and IBJ:
pass
if not HiJump and SpaceJump and GravitySuit and Ice and IBJ:
pass
if not SpaceJump and WallJump:
pass
if not SpaceJump and WallJump:
pass
if not SpaceJump and WallJump:
pass
if not SpaceJump and WallJump:
pass
if not SpaceJump and WallJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and UseBombs and BombJump:
pass
if not MorphBall and SuperMissiles:
pass
if MorphBall and UseBombs:
if SuperMissiles or ScrewAttack:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if not MorphBall and UseBombs:
pass
if not MorphBall and UseBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if not MorphBall and UseBombs or SpringBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if SpeedBooster and SpaceJump or IBJ:
pass
if SpeedBooster:
pass
if SpeedBooster:
pass
if MorphBall and PowerBombs and GravitySuit and DamageRuns:
if not Energy >= 399 or VariaSuit:
pass
if MorphBall and PowerBombs and GravitySuit and DamageRuns:
pass
if MorphBall and PowerBombs:
if (Missiles and ChargeBeam and Ice or ScrewAttack) and GravitySuit and DamageRuns:
if not Energy >= 199 or VariaSuit:
pass
if MorphBall and PowerBombs and GravitySuit and DamageRuns:
if not Energy >= 399 or VariaSuit:
pass
if MorphBall and BombJump:
if (Ice or SpaceJump) and VariaSuit:
pass
if MorphBall:
if (Ice or SpaceJump) and VariaSuit:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall and GravitySuit:
pass
if MorphBall:
if UseBombs and SpringBall or SpaceJump:
pass
if MorphBall:
pass
if MorphBall:
if UseBombs and SpringBall or SpaceJump:
pass
if MorphBall and GravitySuit:
pass
if MorphBall and BombJump:
if Ice or SpaceJump:
pass
if MorphBall:
if Ice or SpaceJump:
pass
if MorphBall and BombJump:
if (Ice or SpaceJump) and GravitySuit:
pass
if MorphBall:
if (Ice or SpaceJump) and GravitySuit:
pass
if SpeedBooster:
if not MorphBall or UseBombs:
pass
if not MorphBall or UseBombs:
pass
if not MorphBall or UseBombs:
pass
if SpeedBooster:
if not MorphBall or UseBombs:
pass
if SpeedBooster:
pass
if not MorphBall and PowerBombs and HiJump and Ice:
pass
if not MorphBall and PowerBombs and HiJump and WallJump:
pass
if not MorphBall and PowerBombs and SpeedBooster and HiJump and Ice:
pass
if not MorphBall and PowerBombs and SpeedBooster and HiJump and Ice:
pass
if not SuperMissiles and PowerBombs:
pass
if not SuperMissiles and PowerBombs:
pass
if not MorphBall or UseBombs:
pass
if not MorphBall or UseBombs:
pass
if MorphBall or UseBombs or ScrewAttack:
if not (HiJump or Ice) and SpaceJump:
pass
if not MorphBall or UseBombs:
pass
if SpeedBooster and GravitySuit:
pass
if SpeedBooster:
pass
if SpeedBooster and GravitySuit:
pass
if SpeedBooster:
pass
if not (MorphBall and UseBombs or SpringBall) and IBJ:
pass
if not (MorphBall and UseBombs or SpringBall) and IBJ:
pass
if not (MorphBall and UseBombs or SpringBall) and IBJ:
pass
if not (MorphBall and UseBombs or SpringBall) and IBJ:
pass
if not MorphBall and PowerBombs and WaterLowered:
pass
if not MorphBall and PowerBombs and WaterLowered:
pass
if not MorphBall and PowerBombs and WaterLowered:
pass
if MorphBall and PowerBombs and SpeedBooster and WaterLowered and DamageRuns:
pass
if not MorphBall and PowerBombs and WaterLowered:
pass
if MorphBall and PowerBombs:
if (WaterLowered or DamageRuns) and SpaceJump and WallJump and IBJ and SpeedBooster and WaterLowered and DamageRuns:
pass
if MorphBall and PowerBombs and SpeedBooster and WaterLowered and DamageRuns:
pass
if MorphBall and PowerBombs and SpaceJump and WallJump and IBJ and SpeedBooster and WaterLowered and DamageRuns:
pass
if MorphBall:
pass
if Missiles and MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if Missiles and MorphBall:
pass
if MorphBall:
pass
if Missiles and MorphBall:
pass
if MorphBall:
pass
if not GravitySuit and SpaceJump:
pass
if not GravitySuit and SpaceJump:
pass
if MorphBall:
pass
if GravitySuit:
pass
if GravitySuit and ScrewAttack:
pass
if SpeedBooster and GravitySuit:
pass
if GravitySuit:
pass
if GravitySuit:
pass
if Missiles and MorphBall:
if (UseBombs or SpringBall) and GravitySuit and GravitySuit:
pass
if Missiles and MorphBall:
if (UseBombs or GravitySuit) and ScrewAttack:
pass
if Missiles and MorphBall and UseBombs and GravitySuit:
pass
if Missiles and MorphBall:
if (UseBombs or SpringBall) and GravitySuit and GravitySuit:
pass
if MorphBall and SpeedBooster and HiJump and WaterLowered and GravitySuit:
pass
if SpeedBooster and MorphBall and HiJump and GravitySuit:
pass
if MorphBall and BlueDoors:
if (WaterLowered or BombJump) and DamageRuns and SpringBall and UseBombs:
pass
if MorphBall and DamageRuns and SpringBall and UseBombs:
pass
if MorphBall and BombJump and BlueDoors:
pass
if MorphBall:
pass
if MorphBall:
if (WaterLowered or SuperMissiles) and PowerBombs and WaveBeam and ScrewAttack and DamageRuns and SuperMissiles and PowerBombs and WaveBeam and GravitySuit:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam and WaterLowered and DamageRuns:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam and WaterLowered and DamageRuns:
pass
if MorphBall and WaterLowered and DamageRuns:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam and WaterLowered and DamageRuns:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam and WaterLowered and DamageRuns:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam and WaterLowered and DamageRuns:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam:
if (WaterLowered or SuperMissiles) and PowerBombs and WaveBeam and ScrewAttack and DamageRuns and Energy >= 199 and SuperMissiles and PowerBombs and WaveBeam and GravitySuit:
pass
if not WaterLowered:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam and WaterLowered and DamageRuns:
pass
if MorphBall:
if (Diffusion or WaveBeam) and IceBeam:
if (WaterLowered or SuperMissiles) and PowerBombs and WaveBeam and ScrewAttack and DamageRuns and Energy >= 199 and SuperMissiles and PowerBombs and WaveBeam and GravitySuit:
pass
if not WaterLowered:
pass
if MorphBall and SpeedBooster and GravitySuit:
pass
if MorphBall and GravitySuit:
pass
if MorphBall and SpeedBooster and GravitySuit:
pass
if MorphBall and GravitySuit:
pass
if MorphBall and SpeedBooster:
pass
if MorphBall and GravitySuit:
pass
if MorphBall and SpeedBooster:
pass
if MorphBall and UseBombs and SpringBall and BombJump:
pass
if MorphBall:
pass
if SpeedBooster and GravitySuit and WaveBeam and HiJump:
pass
if MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if MorphBall and BombJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and PowerBombs and HiJump:
pass
if not MorphBall and PowerBombs and HiJump:
pass
if MorphBall:
pass
if MorphBall:
pass
if Missiles:
if not (ChargeBeam or Difficulty > 0) and HiJump:
pass
if Missiles:
if not (ChargeBeam or Difficulty > 0) and HiJump:
pass
if Missiles:
if not (ChargeBeam or Difficulty > 0) and HiJump:
pass
if MorphBall and PowerBombs:
pass
if MorphBall and PowerBombs:
pass
if MorphBall and PowerBombs:
pass
if MorphBall and PowerBombs:
pass
if MorphBall and UseBombs:
pass
if not MorphBall and PowerBombs and VariaSuit and Ice and SpaceJump:
pass
if MorphBall and UseBombs:
pass
if MorphBall and PowerBombs:
pass
if MorphBall and BombJump and Ice:
pass
if MorphBall:
if not UseBombs or SpringBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
if not UseBombs or SpringBall:
pass
if MorphBall and Missiles and ChargeBeam:
pass
if MorphBall:
pass
if not Missiles and MorphBall and PowerBombs:
pass
if not Missiles and MorphBall and UseBombs:
pass
if not Missiles and MorphBall and UseBombs:
pass
if not Missiles and MorphBall and UseBombs:
pass
if not Missiles and MorphBall and PowerBombs:
pass
if not Missiles and MorphBall and PowerBombs:
pass
if MorphBall:
pass
if MorphBall:
pass
if SpeedBooster:
pass
if SpeedBooster:
pass
if SpeedBooster:
pass
if not MorphBall and VariaSuit and Ice:
pass
if MorphBall:
pass
if Missiles:
pass
if Missiles:
pass
if not MorphBall and UseBombs and SpringBall and Ice:
pass
if MorphBall:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if SpringBall or PowerBombs:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if SpringBall or PowerBombs:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if SpringBall or PowerBombs:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if (SpringBall or PowerBombs) and GravitySuit:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if SpringBall or PowerBombs:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if SpringBall or PowerBombs:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if SpringBall or PowerBombs:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if SpringBall or PowerBombs:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if (SpringBall or PowerBombs) and GravitySuit:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if (SpringBall or PowerBombs) and GravitySuit:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if (SpringBall or PowerBombs) and GravitySuit:
pass
if Missiles:
if (ChargeBeam or Difficulty > 0) and MorphBall and UseBombs:
if (SpringBall or PowerBombs) and GravitySuit:
pass
if MorphBall and UseBombs and HiJump and ScrewAttack and Diffusion and WaveBeam:
pass
if MorphBall and UseBombs:
pass
if MorphBall:
pass
if HiJump:
pass
if MorphBall and UseBombs and Diffusion and WaveBeam:
pass
if WaveBeam:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if MorphBall:
pass
if not MorphBall and SpaceJump and IBJ:
pass
if not MorphBall and SpaceJump and IBJ:
pass
if MorphBall:
pass
if MorphBall and UseBombs:
pass
if MorphBall and Bombs:
pass
if MorphBall and Bombs:
pass
if SpeedBooster:
pass
if (SpeedBooster or GravitySuit) and HiJump and WaveBeam:
pass
if (SpeedBooster or GravitySuit) and HiJump and WaveBeam:
pass
if (YellowDoors and SpeedBooster or GravitySuit) and HiJump:
pass
if (SpeedBooster or GravitySuit) and HiJump and WaveBeam:
pass
if (SpeedBooster or GravitySuit) and HiJump and WaveBeam:
pass
if (SpeedBooster or GravitySuit) and HiJump and WaveBeam:
pass
if (SpeedBooster or GravitySuit) and HiJump and WaveBeam:
pass
if (YellowDoors and SpeedBooster or GravitySuit) and HiJump:
pass
if (YellowDoors and SpeedBooster or GravitySuit) and HiJump:
pass
graph.requirements = {
('S0-06', 'S0-0B'): GreenDoors,
('S0-08', 'S0-0A'): Impossible,
('S0-08', 'S0-0C'): Impossible,
('S0-08', 'S0-0D'): PowerBombs,
('S0-08', 'S0-0F'): RedDoors,
('S0-0A', 'S0-08'): Impossible,
('S0-0A', 'S0-0C'): Impossible,
('S0-0A', 'S0-0D'): Impossible,
('S0-0A', 'S0-0F'): Impossible,
('S0-0A', 'S0-11'): Impossible,
('S0-0C', 'S0-08'): Impossible,
('S0-0C', 'S0-0A'): Impossible,
('S0-0C', 'S0-0D'): Impossible,
('S0-0C', 'S0-0F'): Impossible,
('S0-0C', 'S0-11'): Impossible,
('S0-0D', 'S0-08'): PowerBombs,
('S0-0D', 'S0-0A'): Impossible,
('S0-0D', 'S0-0C'): Impossible,
('S0-0D', 'S0-0F'): RedDoors,
('S0-0D', 'S0-11'): PowerBombs,
('S0-0F', 'S0-0A'): Impossible,
('S0-0F', 'S0-0C'): Impossible,
('S0-0F', 'S0-0D'): PowerBombs,
('S0-11', 'S0-0A'): Impossible,
('S0-11', 'S0-0C'): Impossible,
('S0-11', 'S0-0D'): PowerBombs,
('S0-11', 'S0-0F'): RedDoors,
('S0-0E', 'S0-6C'): PowerBombs,
('S0-6C', 'S0-0E'): SpeedBooster,
('S0-6C', 'S0-13'): SpeedBooster,
('S0-13', 'S0-6C'): PowerBombs,
('S0-53', 'S0-56'): ChargeBeam,
('S0-54', 'S0-56'): ChargeBeam,
('S0-55', 'S0-56'): ChargeBeam,
('S0-16', 'S0-1B'): Missiles,
('S0-16', 'S0-41'): Missiles,
('S0-16', 'S0-8D'): Missiles,
('S0-16', 'S0-C1'): IBJ,
('S0-1B', 'S0-16'): Missiles,
('S0-1B', 'S0-C1'): IBJ,
('S0-41', 'S0-16'): Missiles,
('S0-41', 'S0-C1'): IBJ,
('S0-8D', 'S0-16'): Missiles,
('S0-8D', 'S0-C1'): IBJ,
('S0-C1', 'S0-16'): Missiles,
('S0-1C', 'S0-23'): MorphBall,
('S0-23', 'S0-1C'): MorphBall,
('S0-1E', 'S0-1F'): GreenDoors,
('S0-1E', 'S0-9D'): IBJ,
('S0-1E', 'S0-9E'): IBJ,
('S0-1F', 'S0-1E'): GreenDoors,
('S0-1F', 'S0-9D'): IBJ,
('S0-1F', 'S0-9E'): IBJ,
('S0-9D', 'S0-1E'): GreenDoors,
('S0-9D', 'S0-1F'): GreenDoors,
('S0-9D', 'S0-9E'): IBJ,
('S0-9E', 'S0-1E'): GreenDoors,
('S0-9E', 'S0-1F'): GreenDoors,
('S0-9E', 'S0-9D'): IBJ,
('S0-15', 'S0-84'): GreenDoors,
('S0-15', 'S0-CB'): ScrewAttack,
('S0-24', 'S0-15'): GreenDoors,
('S0-24', 'S0-84'): GreenDoors,
('S0-24', 'S0-CB'): ScrewAttack,
('S0-26', 'S0-15'): GreenDoors,
('S0-26', 'S0-84'): GreenDoors,
('S0-26', 'S0-CB'): ScrewAttack,
('S0-27', 'S0-15'): GreenDoors,
('S0-27', 'S0-84'): GreenDoors,
('S0-27', 'S0-CB'): ScrewAttack,
('S0-84', 'S0-15'): GreenDoors,
('S0-84', 'S0-CB'): ScrewAttack,
('S0-CB', 'S0-15'): GreenDoors,
('S0-CB', 'S0-24'): UseBombs,
('S0-CB', 'S0-26'): UseBombs,
('S0-CB', 'S0-27'): UseBombs,
('S0-CB', 'S0-84'): GreenDoors,
('S0-2A', 'S0-A8'): MorphBall,
('S0-2A', 'S0-CA'): IBJ,
('S0-A8', 'S0-2A'): MorphBall,
('S0-A8', 'S0-CA'): IBJ,
('S0-A8', 'S0-2B'): MorphBall,
('S0-A8', 'S0-68'): MorphBall,
('S0-CA', 'S0-2A'): BombJump,
('S0-CA', 'S0-A8'): BombJump,
('S0-CA', 'S0-2B'): BombJump,
('S0-CA', 'S0-68'): BombJump,
('S0-2B', 'S0-A8'): MorphBall,
('S0-2B', 'S0-CA'): IBJ,
('S0-68', 'S0-A8'): MorphBall,
('S0-68', 'S0-CA'): IBJ,
('S0-1D', 'S0-2C'): ScrewAttack,
('S0-1D', 'S0-2D'): ScrewAttack,
('S0-1D', 'S0-5B'): ScrewAttack,
('S0-2C', 'S0-1D'): ScrewAttack,
('S0-2D', 'S0-1D'): ScrewAttack,
('S0-5B', 'S0-1D'): ScrewAttack,
('S0-2F', 'S0-2E'): IBJ,
('S0-30', 'S0-4A'): Difficulty >= 2,
('S0-4A', 'S0-30'): SpeedBooster,
('S0-4A', 'S0-A6'): SpeedBooster,
('S0-A6', 'S0-4A'): Difficulty >= 2,
('S0-34', 'S0-35'): BlueDoors,
('S0-44', 'S0-35'): BlueDoors,
('S0-36', 'S0-37'): GreenDoors,
('S0-37', 'S0-36'): BlueDoors,
('S0-46', 'S0-36'): BlueDoors,
('S0-46', 'S0-37'): GreenDoors,
('S0-48', 'S0-38'): GreenDoors,
('S0-3A', 'S0-3B'): BlueDoors,
('S0-43', 'S0-3B'): BlueDoors,
('S0-3C', 'S0-3D'): GreenDoors,
('S0-3D', 'S0-3C'): BlueDoors,
('S0-45', 'S0-3C'): BlueDoors,
('S0-45', 'S0-3D'): GreenDoors,
('S0-47', 'S0-3E'): GreenDoors,
('S0-40', 'S0-69'): BombJump,
('S0-69', 'S0-40'): Impossible,
('S0-4E', 'S0-4F'): Impossible,
('S0-4F', 'S0-4E'): ScrewAttack,
('S0-4F', 'S0-65'): ScrewAttack,
('S0-65', 'S0-4F'): Impossible,
('S0-51', 'S0-52'): Impossible,
('S0-52', 'S0-51'): Impossible,
('S0-3F', 'S0-62'): Impossible,
('S0-62', 'S0-3F'): Impossible,
('S0-67', 'S0-6A'): Impossible,
('S0-67', 'S0-C3'): Impossible,
('S0-6A', 'S0-67'): Impossible,
('S0-6A', 'S0-C3'): MorphBall,
('S0-C3', 'S0-67'): Impossible,
('S0-C3', 'S0-6A'): Impossible,
('S0-6B', 'S0-C4'): Impossible,
('S0-C4', 'S0-6B'): ChargeBeam,
('S0-6D', 'S0-6F'): RedDoors,
('S0-6E', 'S0-6D'): RedDoors,
('S0-6E', 'S0-6F'): PowerBombs,
('S0-6F', 'S0-6D'): RedDoors,
('S0-6F', 'S0-6E'): PowerBombs,
('S0-70', 'S0-7D'): IBJ,
('S0-7D', 'S0-70'): UseBombs,
('S0-7D', 'S0-71'): UseBombs,
('S0-7D', 'S0-7C'): UseBombs,
('S0-7D', 'S0-82'): UseBombs,
('S0-71', 'S0-7D'): IBJ,
('S0-7C', 'S0-7D'): IBJ,
('S0-82', 'S0-7D'): IBJ,
('S0-77', 'S0-76'): WaveBeam,
('S0-7E', 'S0-7F'): UseBombs,
('S0-7F', 'S0-7E'): UseBombs,
('S0-86', 'S0-87'): IBJ,
('S0-87', 'S0-86'): IBJ,
('S0-87', 'S0-88'): UseBombs,
('S0-87', 'S0-89'): UseBombs,
('S0-87', 'S0-8A'): UseBombs,
('S0-88', 'S0-86'): IBJ,
('S0-88', 'S0-87'): IBJ,
('S0-89', 'S0-86'): IBJ,
('S0-89', 'S0-87'): IBJ,
('S0-8A', 'S0-86'): IBJ,
('S0-8A', 'S0-87'): IBJ,
('S0-8F', 'S0-90'): RedDoors,
('S0-90', 'S0-8F'): WallJump,
('S0-93', 'S0-94'): RedDoors,
('S0-94', 'S0-93'): RedDoors,
('S0-95', 'S0-96'): RedDoors,
('S0-96', 'S0-95'): RedDoors,
('S0-9A', 'S0-99'): RedDoors,
('S0-9B', 'S0-9C'): MorphBall,
('S0-9C', 'S0-9B'): MorphBall,
('S0-9F', 'S0-A0'): Impossible,
('S0-9F', 'S0-A1'): Impossible,
('S0-9F', 'S0-A2'): WaveBeam,
('S0-9F', 'S0-A3'): Impossible,
('S0-A0', 'S0-9F'): GreenDoors,
('S0-A0', 'S0-A1'): Impossible,
('S0-A0', 'S0-A2'): WaveBeam,
('S0-A0', 'S0-A3'): Impossible,
('S0-A1', 'S0-9F'): GreenDoors,
('S0-A1', 'S0-A0'): GreenDoors,
('S0-A1', 'S0-A2'): WaveBeam,
('S0-A1', 'S0-A3'): Impossible,
('S0-A2', 'S0-9F'): GreenDoors,
('S0-A2', 'S0-A0'): Impossible,
('S0-A2', 'S0-A1'): Impossible,
('S0-A2', 'S0-A3'): Impossible,
('S0-A3', 'S0-9F'): GreenDoors,
('S0-A3', 'S0-A0'): GreenDoors,
('S0-A3', 'S0-A1'): GreenDoors,
('S0-A3', 'S0-A2'): WaveBeam,
('S0-AC', 'S0-AF'): Missiles,
('S0-AF', 'S0-AC'): Missiles,
('S0-AF', 'S0-AD'): Missiles,
('S0-AF', 'S0-AE'): Missiles,
('S0-AD', 'S0-AF'): Missiles,
('S0-AE', 'S0-AF'): Missiles,
('S0-B1', 'S0-B0'): GreenDoors,
('S0-64', 'S0-B3'): GreenDoors,
('S0-B2', 'S0-B3'): GreenDoors,
('S0-B4', 'S0-B5'): Impossible,
('S0-B4', 'S0-B6'): Impossible,
('S0-B4', 'S0-B7'): Impossible,
('S0-B5', 'S0-B4'): Impossible,
('S0-B5', 'S0-B6'): Impossible,
('S0-B5', 'S0-B7'): Impossible,
('S0-B6', 'S0-B4'): Impossible,
('S0-B6', 'S0-B5'): Impossible,
('S0-B6', 'S0-B7'): RedDoors,
('S0-B7', 'S0-B4'): Impossible,
('S0-B7', 'S0-B5'): Impossible,
('S0-B7', 'S0-B6'): RedDoors,
('S0-B8', 'S0-B9'): RedDoors,
('S0-B8', 'S0-BA'): Impossible,
('S0-B9', 'S0-B8'): RedDoors,
('S0-B9', 'S0-BA'): Impossible,
('S0-BA', 'S0-B8'): Impossible,
('S0-BA', 'S0-B9'): Impossible,
('S0-BD', 'S0-BE'): Impossible,
('S0-BE', 'S0-BD'): SpaceJump,
('S0-BB', 'S0-BC'): RedDoors,
('S0-BC', 'S0-BB'): RedDoors,
('S0-C5', 'S0-C6'): Impossible,
('S0-C6', 'S0-C5'): Impossible,
('S0-C6', 'S0-C7'): Impossible,
('S0-C7', 'S0-C5'): RedDoors,
('S0-C7', 'S0-C6'): Impossible,
('S0-92', 'S0-CC'): PlasmaBeam,
('S0-CC', 'S0-92'): IBJ,
('S1-01', 'S1-4C'): GreenDoors,
('S1-4C', 'S1-01'): BlueDoors,
('S1-4C', 'S1-02'): GreenDoors,
('S1-4C', 'S1-03'): GreenDoors,
('S1-02', 'S1-01'): BlueDoors,
('S1-02', 'S1-4C'): GreenDoors,
('S1-03', 'S1-01'): BlueDoors,
('S1-03', 'S1-4C'): GreenDoors,
('S1-09', 'S1-0A'): ScrewAttack,
('S1-0A', 'S1-09'): ScrewAttack,
('S1-0B', 'S1-0C'): Difficulty >= 3,
('S1-0C', 'S1-0B'): Difficulty >= 3,
('S1-17', 'S1-58'): ScrewAttack,
('S1-58', 'S1-17'): Difficulty >= 3,
('S1-18', 'S1-5C'): MorphBall,
('S1-5C', 'S1-18'): MorphBall,
('S1-5C', 'S1-54'): MorphBall,
('S1-54', 'S1-5C'): MorphBall,
('S1-1D', 'S1-1E'): ScrewAttack,
('S1-1E', 'S1-1D'): ScrewAttack,
('S1-16', 'S1-59'): WaveBeam,
('S1-20', 'S1-21'): ScrewAttack,
('S1-20', 'S1-4B'): ScrewAttack,
('S1-21', 'S1-20'): Difficulty >= 4,
('S1-21', 'S1-4B'): Difficulty >= 4,
('S1-4B', 'S1-20'): Difficulty >= 4,
('S1-4B', 'S1-21'): Difficulty >= 4,
('S1-22', 'S1-23'): ScrewAttack,
('S1-23', 'S1-22'): ScrewAttack,
('S1-23', 'S1-5E'): ScrewAttack,
('S1-5E', 'S1-23'): ScrewAttack,
('S1-24', 'S1-25'): GravitySuit,
('S1-25', 'S1-24'): GreenDoors,
('S1-26', 'S1-27'): ScrewAttack,
('S1-27', 'S1-26'): ScrewAttack,
('S1-2A', 'S1-2B'): GreenDoors,
('S1-2A', 'S1-6A'): ScrewAttack,
('S1-2B', 'S1-2A'): BlueDoors,
('S1-2B', 'S1-6A'): ScrewAttack,
('S1-6A', 'S1-2A'): BlueDoors,
('S1-6A', 'S1-2B'): GreenDoors,
('S1-2D', 'S1-2E'): UseBombs,
('S1-2D', 'S1-2F'): UseBombs,
('S1-2D', 'S1-5F'): UseBombs,
('S1-2D', 'S1-6E'): UseBombs,
('S1-2E', 'S1-2D'): UseBombs,
('S1-2E', 'S1-2F'): MorphBall,
('S1-2E', 'S1-5F'): MorphBall,
('S1-2E', 'S1-6E'): MorphBall,
('S1-2F', 'S1-2D'): IBJ,
('S1-2F', 'S1-2E'): IBJ,
('S1-5F', 'S1-2D'): IBJ,
('S1-5F', 'S1-2E'): IBJ,
('S1-6E', 'S1-2D'): IBJ,
('S1-6E', 'S1-2E'): IBJ,
('S1-30', 'S1-31'): ScrewAttack,
('S1-31', 'S1-30'): UseBombs,
('S1-38', 'S1-39'): ChargeBeam,
('S1-3B', 'S1-29'): WaveBeam,
('S1-3E', 'S1-3F'): WallJump,
('S1-3F', 'S1-3E'): WallJump,
('S1-43', 'S1-46'): Impossible,
('S1-43', 'S1-47'): Impossible,
('S1-46', 'S1-43'): Impossible,
('S1-46', 'S1-47'): WaveBeam,
('S1-46', 'S1-44'): Impossible,
('S1-46', 'S1-45'): Impossible,
('S1-47', 'S1-43'): Impossible,
('S1-47', 'S1-44'): Impossible,
('S1-47', 'S1-45'): Impossible,
('S1-44', 'S1-46'): Impossible,
('S1-44', 'S1-47'): Impossible,
('S1-45', 'S1-46'): Impossible,
('S1-45', 'S1-47'): Impossible,
('S1-4A', 'S1-6C'): MorphBall,
('S1-6C', 'S1-4A'): UseBombs,
('S1-49', 'S1-48'): ChargeBeam,
('S1-07', 'S1-08'): ScrewAttack,
('S1-08', 'S1-07'): ScrewAttack,
('S1-19', 'S1-4D'): MorphBall,
('S1-19', 'S1-53'): MorphBall,
('S1-19', 'S1-64'): UseBombs,
('S1-4D', 'S1-19'): Impossible,
('S1-4D', 'S1-53'): ChargeBeam,
('S1-4D', 'S1-64'): UseBombs,
('S1-53', 'S1-19'): Impossible,
('S1-53', 'S1-64'): UseBombs,
('S1-64', 'S1-19'): Impossible,
('S1-64', 'S1-4D'): UseBombs,
('S1-64', 'S1-53'): UseBombs,
('S1-4F', 'S1-50'): MorphBall,
('S1-50', 'S1-4F'): MorphBall,
('S1-6F', 'S1-70'): ScrewAttack,
('S1-70', 'S1-6F'): HiJump,
('S2-01', 'S2-03'): PowerBombs,
('S2-01', 'S2-04'): BlueDoors,
('S2-01', 'S2-20'): UseBombs,
('S2-03', 'S2-01'): PowerBombs,
('S2-03', 'S2-04'): BlueDoors,
('S2-03', 'S2-20'): PowerBombs,
('S2-03', 'S2-02'): PowerBombs,
('S2-03', 'S2-05'): PowerBombs,
('S2-03', 'S2-0F'): PowerBombs,
('S2-04', 'S2-03'): PowerBombs,
('S2-04', 'S2-20'): UseBombs,
('S2-20', 'S2-01'): UseBombs,
('S2-20', 'S2-03'): PowerBombs,
('S2-20', 'S2-04'): BlueDoors,
('S2-20', 'S2-02'): UseBombs,
('S2-20', 'S2-05'): UseBombs,
('S2-20', 'S2-0F'): UseBombs,
('S2-02', 'S2-03'): PowerBombs,
('S2-02', 'S2-04'): BlueDoors,
('S2-02', 'S2-20'): UseBombs,
('S2-05', 'S2-03'): PowerBombs,
('S2-05', 'S2-04'): BlueDoors,
('S2-05', 'S2-20'): UseBombs,
('S2-0F', 'S2-03'): PowerBombs,
('S2-0F', 'S2-04'): BlueDoors,
('S2-0F', 'S2-20'): UseBombs,
('S2-0D', 'S2-3A'): BlueDoors,
('S2-0D', 'S2-80'): ScrewAttack,
('S2-3A', 'S2-80'): ScrewAttack,
('S2-80', 'S2-0D'): ScrewAttack,
('S2-80', 'S2-3A'): BlueDoors,
('S2-80', 'S2-3C'): ScrewAttack,
('S2-3C', 'S2-3A'): BlueDoors,
('S2-3C', 'S2-80'): ScrewAttack,
('S2-14', 'S2-15'): UseBombs,
('S2-15', 'S2-14'): ScrewAttack,
('S2-16', 'S2-17'): ScrewAttack,
('S2-17', 'S2-16'): ScrewAttack,
('S2-18', 'S2-1B'): IBJ,
('S2-1B', 'S2-18'): IBJ,
('S2-26', 'S2-27'): Impossible,
('S2-26', 'S2-5D'): Impossible,
('S2-27', 'S2-26'): Impossible,
('S2-5D', 'S2-26'): Impossible,
('S2-5D', 'S2-27'): ChargeBeam,
('S2-29', 'S2-46'): PowerBombs,
('S2-29', 'S2-6C'): PowerBombs,
('S2-46', 'S2-29'): PowerBombs,
('S2-46', 'S2-2A'): PowerBombs,
('S2-46', 'S2-58'): PowerBombs,
('S2-6C', 'S2-29'): PowerBombs,
('S2-6C', 'S2-2A'): PowerBombs,
('S2-6C', 'S2-58'): PowerBombs,
('S2-2A', 'S2-46'): PowerBombs,
('S2-2A', 'S2-6C'): PowerBombs,
('S2-58', 'S2-46'): PowerBombs,
('S2-58', 'S2-6C'): PowerBombs,
('S2-2E', 'S2-30'): ChargeBeam,
('S2-2F', 'S2-30'): ChargeBeam,
('S2-34', 'S2-35'): MorphBall,
('S2-35', 'S2-34'): MorphBall,
('S2-37', 'S2-87'): MorphBall,
('S2-87', 'S2-37'): Impossible,
('S2-3B', 'S2-3D'): IBJ,
('S2-3B', 'S2-83'): IBJ,
('S2-3D', 'S2-3B'): BlueDoors,
('S2-3D', 'S2-83'): IBJ,
('S2-83', 'S2-3B'): BlueDoors,
('S2-83', 'S2-3D'): IBJ,
('S2-3E', 'S2-3F'): MorphBall,
('S2-3F', 'S2-3E'): MorphBall,
('S2-10', 'S2-12'): ScrewAttack,
('S2-10', 'S2-45'): BlueDoors,
('S2-10', 'S2-54'): ScrewAttack,
('S2-12', 'S2-10'): ScrewAttack,
('S2-12', 'S2-45'): BlueDoors,
('S2-45', 'S2-12'): ScrewAttack,
('S2-45', 'S2-54'): ScrewAttack,
('S2-54', 'S2-10'): ScrewAttack,
('S2-54', 'S2-45'): BlueDoors,
('S2-2B', 'S2-47'): Impossible,
('S2-2B', 'S2-48'): Impossible,
('S2-2B', 'S2-75'): MorphBall,
('S2-47', 'S2-2B'): Impossible,
('S2-47', 'S2-75'): Impossible,
('S2-47', 'S2-2C'): Impossible,
('S2-47', 'S2-2D'): Impossible,
('S2-47', 'S2-78'): Impossible,
('S2-48', 'S2-2B'): Impossible,
('S2-48', 'S2-75'): Impossible,
('S2-48', 'S2-2C'): Impossible,
('S2-48', 'S2-2D'): Impossible,
('S2-48', 'S2-78'): Impossible,
('S2-75', 'S2-2B'): MorphBall,
('S2-75', 'S2-47'): Impossible,
('S2-75', 'S2-48'): Impossible,
('S2-75', 'S2-2C'): MorphBall,
('S2-75', 'S2-2D'): MorphBall,
('S2-75', 'S2-78'): MorphBall,
('S2-2C', 'S2-47'): Impossible,
('S2-2C', 'S2-48'): Impossible,
('S2-2C', 'S2-75'): MorphBall,
('S2-2D', 'S2-47'): Impossible,
('S2-2D', 'S2-48'): Impossible,
('S2-2D', 'S2-75'): MorphBall,
('S2-78', 'S2-47'): Impossible,
('S2-78', 'S2-48'): Impossible,
('S2-78', 'S2-75'): MorphBall,
('S2-49', 'S2-7D'): ScrewAttack,
('S2-7D', 'S2-49'): ScrewAttack,
('S2-4D', 'S2-7A'): MorphBall,
('S2-50', 'S2-4D'): IBJ,
('S2-50', 'S2-7A'): IBJ,
('S2-50', 'S2-4E'): IBJ,
('S2-50', 'S2-4F'): IBJ,
('S2-50', 'S2-79'): IBJ,
('S2-51', 'S2-4D'): IBJ,
('S2-51', 'S2-7A'): IBJ,
('S2-51', 'S2-4E'): IBJ,
('S2-51', 'S2-4F'): IBJ,
('S2-51', 'S2-79'): IBJ,
('S2-7A', 'S2-4D'): MorphBall,
('S2-7A', 'S2-50'): MorphBall,
('S2-7A', 'S2-51'): MorphBall,
('S2-7A', 'S2-4E'): MorphBall,
('S2-7A', 'S2-4F'): MorphBall,
('S2-7A', 'S2-79'): IBJ,
('S2-4E', 'S2-7A'): MorphBall,
('S2-4F', 'S2-7A'): MorphBall,
('S2-79', 'S2-7A'): IBJ,
('S2-53', 'S2-91'): MorphBall,
('S2-91', 'S2-53'): IBJ,
('S2-38', 'S2-5F'): GravitySuit,
('S2-5F', 'S2-38'): IBJ,
('S2-64', 'S2-65'): ScrewAttack,
('S2-65', 'S2-64'): Impossible,
('S2-67', 'S2-66'): Impossible,
('S2-1E', 'S2-1F'): IBJ,
('S2-1E', 'S2-71'): IBJ,
('S2-1F', 'S2-1E'): UseBombs,
('S2-1F', 'S2-68'): UseBombs,
('S2-1F', 'S2-69'): UseBombs,
('S2-1F', 'S2-6A'): UseBombs,
('S2-1F', 'S2-6B'): UseBombs,
('S2-1F', 'S2-70'): UseBombs,
('S2-1F', 'S2-71'): IBJ,
('S2-68', 'S2-1F'): IBJ,
('S2-68', 'S2-71'): IBJ,
('S2-69', 'S2-1F'): IBJ,
('S2-69', 'S2-71'): IBJ,
('S2-6A', 'S2-1F'): IBJ,
('S2-6A', 'S2-71'): IBJ,
('S2-6B', 'S2-1F'): IBJ,
('S2-6B', 'S2-71'): IBJ,
('S2-70', 'S2-1F'): IBJ,
('S2-70', 'S2-71'): IBJ,
('S2-71', 'S2-1E'): MorphBall,
('S2-71', 'S2-1F'): UseBombs,
('S2-71', 'S2-68'): MorphBall,
('S2-71', 'S2-69'): MorphBall,
('S2-71', 'S2-6A'): MorphBall,
('S2-71', 'S2-6B'): MorphBall,
('S2-71', 'S2-70'): MorphBall,
('S2-6D', 'S2-73'): IBJ,
('S2-6E', 'S2-6D'): IBJ,
('S2-6E', 'S2-73'): IBJ,
('S2-73', 'S2-6D'): IBJ,
('S2-7B', 'S2-7C'): Impossible,
('S2-88', 'S2-89'): UseBombs,
('S2-89', 'S2-88'): UseBombs,
('S2-36', 'S2-8A'): WaveBeam,
('S2-36', 'S2-8B'): Missiles,
('S2-8A', 'S2-36'): Missiles,
('S2-8B', 'S2-36'): Missiles,
('S2-8B', 'S2-8A'): WaveBeam,
('S2-52', 'S2-8E'): WaveBeam,
('S2-8D', 'S2-8E'): WaveBeam,
('S2-8F', 'S2-90'): UseBombs,
('S2-90', 'S2-8F'): UseBombs,
('S3-01', 'S3-04'): SpaceJump,
('S3-04', 'S3-01'): MorphBall,
('S3-04', 'S3-02'): MorphBall,
('S3-04', 'S3-03'): MorphBall,
('S3-04', 'S3-35'): MorphBall,
('S3-02', 'S3-04'): SpaceJump,
('S3-03', 'S3-04'): SpaceJump,
('S3-35', 'S3-04'): SpaceJump,
('S3-08', 'S3-09'): GreenDoors,
('S3-08', 'S3-4C'): SpeedBooster,
('S3-09', 'S3-08'): SpeedBooster,
('S3-09', 'S3-4C'): SpeedBooster,
('S3-4C', 'S3-08'): Impossible,
('S3-4C', 'S3-09'): Impossible,
('S3-0A', 'S3-4D'): Impossible,
('S3-4D', 'S3-0A'): GreenDoors,
('S3-0B', 'S3-0C'): GreenDoors,
('S3-3D', 'S3-0C'): GreenDoors,
('S3-0D', 'S3-0E'): GreenDoors,
('S3-0D', 'S3-0F'): ScrewAttack,
('S3-0D', 'S3-3C'): PowerBombs,
('S3-0E', 'S3-0D'): GreenDoors,
('S3-0E', 'S3-0F'): MorphBall,
('S3-0E', 'S3-3C'): ScrewAttack,
('S3-0F', 'S3-0D'): GreenDoors,
('S3-0F', 'S3-0E'): GreenDoors,
('S3-0F', 'S3-3C'): ScrewAttack,
('S3-3C', 'S3-0D'): Impossible,
('S3-3C', 'S3-0E'): Impossible,
('S3-3C', 'S3-0F'): Impossible,
('S3-11', 'S3-12'): IBJ,
('S3-12', 'S3-11'): ScrewAttack,
('S3-13', 'S3-53'): ScrewAttack,
('S3-13', 'S3-54'): ScrewAttack,
('S3-53', 'S3-13'): ScrewAttack,
('S3-53', 'S3-54'): ScrewAttack,
('S3-53', 'S3-26'): ScrewAttack,
('S3-54', 'S3-13'): ScrewAttack,
('S3-54', 'S3-53'): ScrewAttack,
('S3-54', 'S3-26'): ScrewAttack,
('S3-26', 'S3-53'): ScrewAttack,
('S3-26', 'S3-54'): ScrewAttack,
('S3-14', 'S3-15'): GreenDoors,
('S3-14', 'S3-46'): GreenDoors,
('S3-15', 'S3-46'): GreenDoors,
('S3-46', 'S3-15'): GreenDoors,
('S3-39', 'S3-15'): GreenDoors,
('S3-39', 'S3-46'): GreenDoors,
('S3-16', 'S3-17'): VariaSuit,
('S3-17', 'S3-16'): GreenDoors,
('S3-18', 'S3-19'): VariaSuit,
('S3-19', 'S3-18'): VariaSuit,
('S3-1A', 'S3-1B'): VariaSuit,
('S3-1B', 'S3-1A'): VariaSuit,
('S3-1C', 'S3-1D'): IBJ,
('S3-1E', 'S3-1F'): VariaSuit,
('S3-1F', 'S3-1E'): VariaSuit,
('S3-20', 'S3-21'): VariaSuit,
('S3-21', 'S3-20'): VariaSuit,
('S3-22', 'S3-31'): ChargeBeam,
('S3-24', 'S3-2B'): GreenDoors,
('S3-28', 'S3-4B'): WaveBeam,
('S3-28', 'S3-4E'): ScrewAttack,
('S3-4B', 'S3-28'): VariaSuit,
('S3-4B', 'S3-4E'): ScrewAttack,
('S3-4E', 'S3-28'): ScrewAttack,
('S3-4E', 'S3-4B'): ScrewAttack,
('S3-2D', 'S3-10'): GreenDoors,
('S3-40', 'S3-10'): GreenDoors,
('S3-25', 'S3-2B'): GreenDoors,
('S3-25', 'S3-2E'): Difficulty > 0,
('S3-2B', 'S3-25'): GreenDoors,
('S3-2B', 'S3-2E'): Difficulty > 0,
('S3-2E', 'S3-25'): GreenDoors,
('S3-2E', 'S3-2B'): GreenDoors,
('S3-2F', 'S3-30'): ScrewAttack,
('S3-2F', 'S3-3F'): ScrewAttack,
('S3-30', 'S3-2F'): GreenDoors,
('S3-30', 'S3-3F'): UseBombs,
('S3-3F', 'S3-2F'): Impossible,
('S3-3F', 'S3-30'): Impossible,
('S3-36', 'S3-37'): SpeedBooster,
('S3-37', 'S3-36'): ScrewAttack,
('S3-3A', 'S3-3B'): Impossible,
('S3-3A', 'S3-3E'): Impossible,
('S3-3B', 'S3-3A'): SpeedBooster,
('S3-3E', 'S3-3A'): SpeedBooster,
('S3-3E', 'S3-3B'): Impossible,
('S3-27', 'S3-47'): GreenDoors,
('S3-27', 'S3-4A'): Difficulty >= 4,
('S3-47', 'S3-27'): ScrewAttack,
('S3-47', 'S3-4A'): Difficulty >= 4,
('S3-4A', 'S3-47'): GreenDoors,
('S3-4F', 'S3-50'): SpeedBooster,
('S3-50', 'S3-4F'): Impossible,
('S4-08', 'S4-09'): RedDoors,
('S4-08', 'S4-1B'): RedDoors,
('S4-08', 'S4-54'): DamageRuns,
('S4-09', 'S4-08'): IceBeam,
('S4-09', 'S4-1B'): DamageRuns,
('S4-09', 'S4-54'): IceBeam,
('S4-1B', 'S4-08'): IceBeam,
('S4-1B', 'S4-09'): DamageRuns,
('S4-1B', 'S4-54'): IceBeam,
('S4-54', 'S4-08'): DamageRuns,
('S4-54', 'S4-09'): RedDoors,
('S4-54', 'S4-1B'): RedDoors,
('S4-0D', 'S4-0E'): UseBombs,
('S4-0D', 'S4-12'): GravitySuit,
('S4-0D', 'S4-41'): UseBombs,
('S4-0E', 'S4-0D'): IBJ,
('S4-0E', 'S4-12'): GravitySuit,
('S4-12', 'S4-0D'): GravitySuit,
('S4-12', 'S4-0E'): GravitySuit,
('S4-12', 'S4-41'): GravitySuit,
('S4-41', 'S4-0D'): IBJ,
('S4-41', 'S4-12'): GravitySuit,
('S4-14', 'S4-15'): MorphBall,
('S4-15', 'S4-14'): MorphBall,
('S4-15', 'S4-4A'): MorphBall,
('S4-4A', 'S4-15'): MorphBall,
('S4-17', 'S4-18'): SpeedBooster,
('S4-18', 'S4-17'): Impossible,
('S4-16', 'S4-3F'): Impossible,
('S4-16', 'S4-40'): Impossible,
('S4-3F', 'S4-16'): Impossible,
('S4-3F', 'S4-40'): ChargeBeam,
('S4-40', 'S4-16'): Impossible,
('S4-40', 'S4-3F'): GravitySuit,
('S4-58', 'S4-5F'): SpaceJump,
('S4-59', 'S4-5F'): SpaceJump,
('S4-1E', 'S4-1D'): Impossible,
('S4-75', 'S4-1D'): Impossible,
('S4-1F', 'S4-4F'): MorphBall,
('S4-21', 'S4-1F'): IBJ,
('S4-21', 'S4-4F'): IBJ,
('S4-21', 'S4-20'): IBJ,
('S4-21', 'S4-60'): IBJ,
('S4-22', 'S4-1F'): IBJ,
('S4-22', 'S4-4F'): IBJ,
('S4-22', 'S4-20'): IBJ,
('S4-22', 'S4-60'): IBJ,
('S4-4F', 'S4-1F'): MorphBall,
('S4-4F', 'S4-21'): MorphBall,
('S4-4F', 'S4-22'): MorphBall,
('S4-4F', 'S4-20'): MorphBall,
('S4-4F', 'S4-60'): MorphBall,
('S4-20', 'S4-4F'): MorphBall,
('S4-60', 'S4-4F'): MorphBall,
('S4-24', 'S4-25'): RedDoors,
('S4-29', 'S4-28'): RedDoors,
('S4-2A', 'S4-37'): ScrewAttack,
('S4-2A', 'S4-5A'): SpringBall,
('S4-2A', 'S4-74'): MorphBall,
('S4-37', 'S4-2A'): ScrewAttack,
('S4-37', 'S4-5A'): ScrewAttack,
('S4-37', 'S4-74'): ScrewAttack,
('S4-5A', 'S4-2A'): SpringBall,
('S4-5A', 'S4-37'): ScrewAttack,
('S4-5A', 'S4-74'): SpringBall,
('S4-74', 'S4-2A'): MorphBall,
('S4-74', 'S4-37'): ScrewAttack,
('S4-74', 'S4-5A'): ScrewAttack,
('S4-11', 'S4-2B'): GravitySuit,
('S4-11', 'S4-3B'): GravitySuit,
('S4-11', 'S4-47'): GravitySuit,
('S4-2B', 'S4-11'): DamageRuns,
('S4-2B', 'S4-3B'): GravitySuit,
('S4-2B', 'S4-47'): ScrewAttack,
('S4-3B', 'S4-11'): GravitySuit,
('S4-3B', 'S4-2B'): GravitySuit,
('S4-3B', 'S4-47'): GravitySuit,
('S4-47', 'S4-11'): DamageRuns,
('S4-47', 'S4-2B'): ScrewAttack,
('S4-47', 'S4-3B'): GravitySuit,
('S4-2C', 'S4-2D'): RedDoors,
('S4-2C', 'S4-2E'): MorphBall,
('S4-2C', 'S4-4B'): BlueDoors,
('S4-2D', 'S4-2C'): DamageRuns,
('S4-2D', 'S4-2E'): DamageRuns,
('S4-2D', 'S4-4B'): BlueDoors,
('S4-2E', 'S4-2D'): RedDoors,
('S4-2E', 'S4-4B'): BlueDoors,
('S4-4B', 'S4-2D'): RedDoors,
('S4-4B', 'S4-2E'): MorphBall,
('S4-2F', 'S4-45'): MorphBall,
('S4-45', 'S4-2F'): UseBombs,
('S4-30', 'S4-35'): GravitySuit,
('S4-30', 'S4-4E'): ScrewAttack,
('S4-35', 'S4-30'): Impossible,
('S4-35', 'S4-4D'): Impossible,
('S4-35', 'S4-4E'): Impossible,
('S4-4D', 'S4-30'): RedDoors,
('S4-4D', 'S4-35'): GravitySuit,
('S4-4D', 'S4-4E'): ScrewAttack,
('S4-4E', 'S4-30'): RedDoors,
('S4-4E', 'S4-35'): ScrewAttack,
('S4-4E', 'S4-4D'): ScrewAttack,
('S4-31', 'S4-50'): ScrewAttack,
('S4-36', 'S4-31'): RedDoors,
('S4-36', 'S4-50'): ScrewAttack,
('S4-50', 'S4-31'): RedDoors,
('S4-50', 'S4-36'): ScrewAttack,
('S4-32', 'S4-33'): RedDoors,
('S4-32', 'S4-64'): GravitySuit,
('S4-33', 'S4-32'): RedDoors,
('S4-33', 'S4-53'): GravitySuit,
('S4-33', 'S4-64'): BombJump,
('S4-53', 'S4-32'): RedDoors,
('S4-53', 'S4-33'): RedDoors,
('S4-53', 'S4-64'): GravitySuit,
('S4-64', 'S4-32'): RedDoors,
('S4-64', 'S4-33'): RedDoors,
('S4-64', 'S4-53'): GravitySuit,
('S4-34', 'S4-62'): Impossible,
('S4-62', 'S4-34'): RedDoors,
('S4-42', 'S4-43'): UseBombs,
('S4-42', 'S4-44'): Impossible,
('S4-42', 'S4-71'): Impossible,
('S4-43', 'S4-42'): UseBombs,
('S4-43', 'S4-44'): Impossible,
('S4-43', 'S4-71'): Impossible,
('S4-44', 'S4-42'): Impossible,
('S4-44', 'S4-43'): Impossible,
('S4-44', 'S4-71'): MorphBall,
('S4-71', 'S4-42'): Impossible,
('S4-71', 'S4-43'): Impossible,
('S4-71', 'S4-44'): MorphBall,
('S4-46', 'S4-49'): GravitySuit,
('S4-49', 'S4-46'): GravitySuit,
('S4-48', 'S4-51'): Impossible,
('S4-48', 'S4-52'): Impossible,
('S4-51', 'S4-48'): ScrewAttack,
('S4-51', 'S4-52'): ScrewAttack,
('S4-52', 'S4-48'): ScrewAttack,
('S4-52', 'S4-51'): ScrewAttack,
('S4-1C', 'S4-38'): Diffusion,
('S4-1C', 'S4-6D'): ScrewAttack,
('S4-1C', 'S4-70'): Diffusion,
('S4-38', 'S4-1C'): Ice,
('S4-38', 'S4-6D'): ScrewAttack,
('S4-38', 'S4-70'): Ice,
('S4-6D', 'S4-1C'): WallJump,
('S4-6D', 'S4-38'): WallJump,
('S4-6D', 'S4-70'): WallJump,
('S4-70', 'S4-1C'): MorphBall,
('S4-70', 'S4-38'): MorphBall,
('S4-70', 'S4-6D'): ScrewAttack,
('S4-56', 'S4-57'): UseBombs,
('S4-57', 'S4-56'): RedDoors,
('S4-5D', 'S4-5E'): ScrewAttack,
('S4-5E', 'S4-5D'): ScrewAttack,
('S4-65', 'S4-66'): WaveBeam,
('S4-66', 'S4-65'): MorphBall,
('S4-6E', 'S4-6F'): MorphBall,
('S4-6F', 'S4-6E'): MorphBall,
('S5-01', 'S5-42'): YellowDoors,
('S5-01', 'S5-4D'): MorphBall,
('S5-01', 'S5-51'): YellowDoors,
('S5-42', 'S5-4D'): MorphBall,
('S5-42', 'S5-51'): YellowDoors,
('S5-4D', 'S5-01'): MorphBall,
('S5-4D', 'S5-42'): YellowDoors,
('S5-4D', 'S5-51'): YellowDoors,
('S5-51', 'S5-42'): YellowDoors,
('S5-51', 'S5-4D'): YellowDoors,
('S5-07', 'S5-08'): IBJ,
('S5-08', 'S5-07'): YellowDoors,
('S5-09', 'S5-07'): YellowDoors,
('S5-09', 'S5-08'): IBJ,
('S5-4E', 'S5-07'): YellowDoors,
('S5-4E', 'S5-08'): IBJ,
('S5-34', 'S5-59'): YellowDoors,
('S5-59', 'S5-34'): YellowDoors,
('S5-0B', 'S5-0C'): IBJ,
('S5-0C', 'S5-0B'): YellowDoors,
('S5-0D', 'S5-0B'): YellowDoors,
('S5-0D', 'S5-0C'): IBJ,
('S5-50', 'S5-0B'): YellowDoors,
('S5-50', 'S5-0C'): IBJ,
('S5-0E', 'S5-0F'): VariaSuit,
('S5-0E', 'S5-10'): VariaSuit,
('S5-0E', 'S5-1E'): VariaSuit,
('S5-0E', 'S5-38'): ScrewAttack,
('S5-0E', 'S5-63'): YellowDoors,
('S5-0F', 'S5-0E'): VariaSuit,
('S5-0F', 'S5-10'): VariaSuit,
('S5-0F', 'S5-1E'): VariaSuit,
('S5-0F', 'S5-38'): ScrewAttack,
('S5-0F', 'S5-63'): YellowDoors,
('S5-10', 'S5-0E'): VariaSuit,
('S5-10', 'S5-0F'): VariaSuit,
('S5-10', 'S5-1E'): VariaSuit,
('S5-10', 'S5-38'): ScrewAttack,
('S5-10', 'S5-63'): YellowDoors,
('S5-1E', 'S5-0E'): VariaSuit,
('S5-1E', 'S5-0F'): VariaSuit,
('S5-1E', 'S5-10'): VariaSuit,
('S5-1E', 'S5-38'): ScrewAttack,
('S5-1E', 'S5-63'): YellowDoors,
('S5-38', 'S5-0E'): ScrewAttack,
('S5-38', 'S5-0F'): ScrewAttack,
('S5-38', 'S5-10'): ScrewAttack,
('S5-38', 'S5-1E'): ScrewAttack,
('S5-38', 'S5-63'): ScrewAttack,
('S5-63', 'S5-0E'): VariaSuit,
('S5-63', 'S5-0F'): VariaSuit,
('S5-63', 'S5-10'): VariaSuit,
('S5-63', 'S5-1E'): VariaSuit,
('S5-63', 'S5-38'): ScrewAttack,
('S5-24', 'S5-40'): WaveBeam,
('S5-40', 'S5-24'): VariaSuit,
('S5-12', 'S5-14'): YellowDoors,
('S5-14', 'S5-12'): YellowDoors,
('S5-28', 'S5-13'): YellowDoors,
('S5-15', 'S5-16'): VariaSuit,
('S5-16', 'S5-15'): VariaSuit,
('S5-18', 'S5-31'): YellowDoors,
('S5-18', 'S5-4F'): VariaSuit,
('S5-18', 'S5-5A'): YellowDoors,
('S5-31', 'S5-18'): SpaceJump,
('S5-31', 'S5-4F'): VariaSuit,
('S5-31', 'S5-5A'): YellowDoors,
('S5-4F', 'S5-18'): SpaceJump,
('S5-4F', 'S5-31'): YellowDoors,
('S5-4F', 'S5-5A'): YellowDoors,
('S5-5A', 'S5-18'): SpaceJump,
('S5-5A', 'S5-31'): YellowDoors,
('S5-5A', 'S5-4F'): VariaSuit,
('S5-1B', 'S5-1D'): GravitySuit,
('S5-1B', 'S5-39'): ScrewAttack,
('S5-1B', 'S5-46'): YellowDoors,
('S5-1C', 'S5-1B'): GravitySuit,
('S5-1C', 'S5-1D'): GravitySuit,
('S5-1C', 'S5-39'): GravitySuit,
('S5-1C', 'S5-46'): YellowDoors,
('S5-1C', 'S5-1F'): GravitySuit,
('S5-1C', 'S5-35'): GravitySuit,
('S5-1D', 'S5-1B'): GravitySuit,
('S5-1D', 'S5-1C'): GravitySuit,
('S5-1D', 'S5-39'): GravitySuit,
('S5-1D', 'S5-46'): YellowDoors,
('S5-1D', 'S5-1F'): GravitySuit,
('S5-1D', 'S5-35'): GravitySuit,
('S5-39', 'S5-1B'): ScrewAttack,
('S5-39', 'S5-1C'): ScrewAttack,
('S5-39', 'S5-1D'): GravitySuit,
('S5-39', 'S5-46'): YellowDoors,
('S5-39', 'S5-1F'): ScrewAttack,
('S5-39', 'S5-35'): ScrewAttack,
('S5-46', 'S5-1B'): GravitySuit,
('S5-46', 'S5-1C'): GravitySuit,
('S5-46', 'S5-1D'): UseBombs,
('S5-46', 'S5-39'): GravitySuit,
('S5-46', 'S5-1F'): GravitySuit,
('S5-46', 'S5-35'): GravitySuit,
('S5-1F', 'S5-1D'): GravitySuit,
('S5-1F', 'S5-39'): ScrewAttack,
('S5-1F', 'S5-46'): YellowDoors,
('S5-35', 'S5-1D'): GravitySuit,
('S5-35', 'S5-39'): ScrewAttack,
('S5-35', 'S5-46'): YellowDoors,
('S5-5B', 'S5-5C'): YellowDoors,
('S5-5C', 'S5-5B'): IBJ,
('S5-5C', 'S5-5D'): IBJ,
('S5-5D', 'S5-5C'): YellowDoors,
('S5-22', 'S5-78'): PowerBombs,
('S5-3D', 'S5-22'): IBJ,
('S5-3D', 'S5-78'): IBJ,
('S5-3D', 'S5-23'): IBJ,
('S5-3D', 'S5-77'): IBJ,
('S5-3E', 'S5-22'): IBJ,
('S5-3E', 'S5-78'): IBJ,
('S5-3E', 'S5-23'): IBJ,
('S5-3E', 'S5-77'): IBJ,
('S5-78', 'S5-22'): UseBombs,
('S5-78', 'S5-3D'): UseBombs,
('S5-78', 'S5-3E'): UseBombs,
('S5-78', 'S5-23'): UseBombs,
('S5-78', 'S5-77'): UseBombs,
('S5-23', 'S5-78'): PowerBombs,
('S5-77', 'S5-78'): PowerBombs,
('S5-25', 'S5-26'): ChargeBeam,
('S5-2A', 'S5-6C'): VariaSuit,
('S5-2A', 'S5-6D'): VariaSuit,
('S5-2A', 'S5-6E'): WallJump,
('S5-6C', 'S5-2A'): VariaSuit,
('S5-6C', 'S5-6D'): VariaSuit,
('S5-6C', 'S5-6E'): WallJump,
('S5-6D', 'S5-2A'): VariaSuit,
('S5-6D', 'S5-6C'): VariaSuit,
('S5-6D', 'S5-6E'): WallJump,
('S5-6E', 'S5-2A'): VariaSuit,
('S5-6E', 'S5-6C'): VariaSuit,
('S5-6E', 'S5-6D'): VariaSuit,
('S5-19', 'S5-30'): YellowDoors,
('S5-19', 'S5-69'): PowerBombs,
('S5-30', 'S5-19'): IBJ,
('S5-30', 'S5-68'): IBJ,
('S5-30', 'S5-69'): PowerBombs,
('S5-61', 'S5-19'): IBJ,
('S5-61', 'S5-30'): YellowDoors,
('S5-61', 'S5-68'): IBJ,
('S5-61', 'S5-69'): PowerBombs,
('S5-68', 'S5-19'): IBJ,
('S5-68', 'S5-30'): YellowDoors,
('S5-68', 'S5-69'): PowerBombs,
('S5-69', 'S5-19'): Impossible,
('S5-69', 'S5-30'): Impossible,
('S5-69', 'S5-61'): Impossible,
('S5-69', 'S5-68'): Impossible,
('S5-3B', 'S5-3C'): GravitySuit,
('S5-3C', 'S5-3B'): GravitySuit,
('S5-41', 'S5-11'): YellowDoors,
('S5-43', 'S5-49'): ScrewAttack,
('S5-49', 'S5-43'): YellowDoors,
('S5-03', 'S5-52'): YellowDoors,
('S5-52', 'S5-03'): YellowDoors,
('S5-1A', 'S5-27'): Impossible,
('S5-27', 'S5-1A'): MorphBall,
('S5-55', 'S5-56'): YellowDoors,
('S5-56', 'S5-55'): WaveBeam,
('S5-67', 'S5-66'): Ice,
('S5-64', 'S5-65'): Impossible,
('S5-65', 'S5-64'): YellowDoors,
('S5-6A', 'S5-6B'): UseBombs,
('S5-6B', 'S5-6A'): UseBombs,
('S5-5E', 'S5-5F'): YellowDoors,
('S5-5E', 'S5-60'): VariaSuit,
('S5-5F', 'S5-5E'): SpaceJump,
('S5-5F', 'S5-60'): VariaSuit,
('S5-60', 'S5-5E'): SpaceJump,
('S5-60', 'S5-5F'): YellowDoors,
('S5-36', 'S5-44'): Ice,
('S5-44', 'S5-36'): WallJump,
('S5-44', 'S5-70'): MorphBall,
('S5-70', 'S5-36'): WallJump,
('S5-70', 'S5-44'): Ice,
('S5-73', 'S5-7B'): GravitySuit,
('S5-7B', 'S5-73'): GravitySuit,
('S6-01', 'S6-33'): Impossible,
('S6-01', 'S6-4F'): ScrewAttack,
('S6-33', 'S6-01'): Impossible,
('S6-33', 'S6-4F'): Impossible,
('S6-33', 'S6-02'): Impossible,
('S6-4F', 'S6-01'): ScrewAttack,
('S6-4F', 'S6-33'): Impossible,
('S6-4F', 'S6-02'): ScrewAttack,
('S6-02', 'S6-33'): Impossible,
('S6-02', 'S6-4F'): ScrewAttack,
('S6-07', 'S6-08'): Difficulty >= 1,
('S6-07', 'S6-32'): UseBombs,
('S6-07', 'S6-4B'): Difficulty >= 1,
('S6-08', 'S6-07'): ScrewAttack,
('S6-08', 'S6-32'): ScrewAttack,
('S6-08', 'S6-4B'): UseBombs,
('S6-32', 'S6-07'): UseBombs,
('S6-32', 'S6-08'): ScrewAttack,
('S6-32', 'S6-4B'): ScrewAttack,
('S6-4B', 'S6-07'): ScrewAttack,
('S6-4B', 'S6-08'): UseBombs,
('S6-4B', 'S6-32'): ScrewAttack,
('S6-0B', 'S6-52'): ScrewAttack,
('S6-0B', 'S6-55'): Impossible,
('S6-52', 'S6-0B'): ScrewAttack,
('S6-52', 'S6-55'): Impossible,
('S6-52', 'S6-0C'): ScrewAttack,
('S6-52', 'S6-0D'): ScrewAttack,
('S6-52', 'S6-0E'): ScrewAttack,
('S6-55', 'S6-0B'): SpeedBooster,
('S6-55', 'S6-52'): ScrewAttack,
('S6-55', 'S6-0C'): SpeedBooster,
('S6-55', 'S6-0D'): SpeedBooster,
('S6-55', 'S6-0E'): SpeedBooster,
('S6-0C', 'S6-52'): ScrewAttack,
('S6-0C', 'S6-55'): Impossible,
('S6-0D', 'S6-52'): ScrewAttack,
('S6-0D', 'S6-55'): Energy > 499,
('S6-0E', 'S6-52'): ScrewAttack,
('S6-0E', 'S6-55'): Impossible,
('S6-20', 'S6-30'): Energy > 499,
('S6-30', 'S6-20'): Energy > 499,
('S6-03', 'S6-21'): Energy > 499,
('S6-21', 'S6-03'): Energy > 499,
('S6-0F', 'S6-47'): ScrewAttack,
('S6-47', 'S6-0F'): MorphBall,
('S6-47', 'S6-10'): MorphBall,
('S6-10', 'S6-47'): ScrewAttack,
('S6-11', 'S6-12'): SpeedBooster,
('S6-11', 'S6-2E'): SpeedBooster,
('S6-12', 'S6-11'): SpeedBooster,
('S6-2E', 'S6-11'): Impossible,
('S6-14', 'S6-1B'): MorphBall,
('S6-1B', 'S6-14'): UseBombs,
('S6-1B', 'S6-15'): UseBombs,
('S6-1B', 'S6-3D'): UseBombs,
('S6-15', 'S6-1B'): MorphBall,
('S6-3D', 'S6-1B'): MorphBall,
('S6-17', 'S6-18'): GreenDoors,
('S6-1A', 'S6-59'): ScrewAttack,
('S6-1C', 'S6-1A'): RedDoors,
('S6-1C', 'S6-59'): Impossible,
('S6-59', 'S6-1A'): RedDoors,
('S6-59', 'S6-1C'): MorphBall,
('S6-25', 'S6-58'): ScrewAttack,
('S6-58', 'S6-25'): ScrewAttack,
('S6-28', 'S6-2A'): RedDoors,
('S6-29', 'S6-28'): IBJ,
('S6-29', 'S6-2A'): RedDoors,
('S6-2A', 'S6-28'): IBJ,
('S6-2C', 'S6-2D'): WaveBeam,
('S6-2D', 'S6-2C'): RedDoors,
('S6-35', 'S6-3E'): GreenDoors,
('S6-3E', 'S6-35'): GreenDoors,
('S6-13', 'S6-36'): UseBombs,
('S6-36', 'S6-13'): PowerBombs,
('S6-37', 'S6-38'): PowerBombs,
('S6-38', 'S6-37'): PowerBombs,
('S6-39', 'S6-3A'): MorphBall,
('S6-3A', 'S6-39'): MorphBall,
('S6-3F', 'S6-42'): Impossible,
('S6-40', 'S6-42'): Impossible,
('S6-41', 'S6-43'): Energy >= 599,
('S6-41', 'S6-44'): Energy >= 599,
('S6-43', 'S6-41'): Energy > 599,
('S6-43', 'S6-4D'): Energy > 599,
('S6-44', 'S6-41'): Energy > 599,
('S6-44', 'S6-4D'): Energy > 599,
('S6-4D', 'S6-43'): Energy > 599,
('S6-4D', 'S6-44'): Energy > 599,
('S0-0E', 'Item S0-0E-0B'): PowerBombs,
('Item S0-0E-0B', 'S0-0E'): PowerBombs,
('Item S0-0E-0B', 'S0-13'): PowerBombs,
('Item S0-0E-0B', 'S0-6C'): PowerBombs,
('S0-13', 'Item S0-0E-0B'): PowerBombs,
('S0-6C', 'Item S0-0E-0B'): PowerBombs,
('S0-20', 'Item S0-05-16'): BackwardsLabs,
('S0-20', 'S0-22'): BackwardsLabs,
('Item S0-05-16', 'S0-20'): RedDoors,
('Item S0-05-16', 'S0-22'): BackwardsLabs,
('S0-22', 'S0-20'): RedDoors,
('S0-22', 'Item S0-05-16'): RedDoors,
('Item S0-14-07', 'S0-4F'): Impossible,
('S0-4F', 'Item S0-14-07'): Missiles,
('S0-58', 'Arachnus'): Missiles,
('S0-58', 'S0-59'): MorphBall,
('S0-58', 'S0-C8'): Missiles,
('Item S0-18-06', 'S0-58'): Missiles,
('Item S0-18-06', 'Arachnus'): Missiles,
('Item S0-18-06', 'S0-59'): MorphBall,
('Item S0-18-06', 'S0-C8'): Missiles,
('Arachnus', 'S0-58'): ScrewAttack,
('Arachnus', 'Item S0-18-06'): ScrewAttack,
('Arachnus', 'S0-59'): MorphBall,
('Arachnus', 'S0-C8'): ScrewAttack,
('S0-59', 'S0-58'): ScrewAttack,
('S0-59', 'Item S0-18-06'): ScrewAttack,
('S0-59', 'Arachnus'): MorphBall,
('S0-59', 'S0-C8'): ScrewAttack,
('S0-C8', 'S0-58'): Missiles,
('S0-C8', 'Item S0-18-06'): Missiles,
('S0-C8', 'Arachnus'): Missiles,
('S0-C8', 'S0-59'): MorphBall,
('S0-6B', 'Item S0-08-0B'): SpringBall,
('Item S0-08-0B', 'S0-6B'): PowerBombs,
('Item S0-08-0B', 'S0-C4'): Impossible,
('S0-C4', 'Item S0-08-0B'): SpringBall,
('S0-74', 'Item S0-16-12'): MorphBall,
('S0-74', 'S0-75'): UseBombs,
('Item S0-16-12', 'S0-74'): MorphBall,
('Item S0-16-12', 'S0-75'): UseBombs,
('S0-75', 'S0-74'): Impossible,
('S0-75', 'Item S0-16-12'): Impossible,
('S0-83', 'Item S0-0E-07'): BombJump,
('Item S0-0E-07', 'S0-83'): GreenDoors,
('S0-9F', 'Item S0-09-04'): WaveBeam,
('Item S0-09-04', 'S0-9F'): GreenDoors,
('Item S0-09-04', 'S0-A0'): Impossible,
('Item S0-09-04', 'S0-A1'): Impossible,
('Item S0-09-04', 'S0-A2'): WaveBeam,
('Item S0-09-04', 'S0-A3'): Impossible,
('S0-A0', 'Item S0-09-04'): WaveBeam,
('S0-A9', 'Item S0-0C-09'): MorphBall,
('Item S0-0C-09', 'S0-A9'): MorphBall,
('S0-AA', 'Item S0-05-08'): SpeedBooster,
('Item S0-05-08', 'S0-AA'): SpeedBooster,
('S0-C2', 'End-of-Game'): PlasmaBeam,
('End-of-Game', 'S0-C2'): RedDoors,
('S0-03', 'Yakuza'): Difficulty > 0,
('S0-03', 'S0-79'): IBJ,
('Yakuza', 'S0-03'): IBJ,
('Yakuza', 'S0-79'): IBJ,
('S0-79', 'S0-03'): IBJ,
('S0-79', 'Yakuza'): Difficulty > 0,
('S1-0D', 'Item S1-0D-02'): MorphBall,
('Item S1-0D-02', 'S1-0D'): MorphBall,
('Item S1-0D-02', 'S1-0E'): MorphBall,
('S1-0E', 'Item S1-0D-02'): MorphBall,
('S1-24', 'Item S1-05-03'): Energy >= 199,
('S1-24', 'Item S1-06-03'): Energy >= 199,
('S1-24', 'Item S1-07-04'): Energy >= 399,
('Item S1-05-03', 'S1-24'): Energy >= 199,
('Item S1-05-03', 'S1-25'): Energy >= 199,
('Item S1-05-03', 'Item S1-06-03'): Impossible,
('Item S1-05-03', 'Item S1-07-04'): Impossible,
('S1-25', 'Item S1-05-03'): Difficulty > 0,
('S1-25', 'Item S1-07-04'): Energy >= 299,
('Item S1-06-03', 'S1-24'): Energy >= 199,
('Item S1-06-03', 'Item S1-05-03'): Impossible,
('Item S1-06-03', 'Item S1-07-04'): Impossible,
('Item S1-07-04', 'S1-24'): Energy >= 399,
('Item S1-07-04', 'Item S1-05-03'): Impossible,
('Item S1-07-04', 'S1-25'): Energy >= 299,
('Item S1-07-04', 'Item S1-06-03'): Impossible,
('S1-3A', 'Ridley'): PlasmaBeam,
('Ridley', 'S1-3A'): IBJ,
('S1-3E', 'Item S1-03-0A'): ScrewAttack,
('Item S1-03-0A', 'S1-3E'): ScrewAttack,
('Item S1-03-0A', 'S1-3F'): ScrewAttack,
('Item S1-03-0A', '3E'): BombJump,
('Item S1-03-0A', '3F'): BombJump,
('S1-3F', 'Item S1-03-0A'): ScrewAttack,
('3E', 'Item S1-03-0A'): BombJump,
('3F', 'Item S1-03-0A'): BombJump,
('S1-51', 'Item S1-07-00'): ScrewAttack,
('S1-51', 'S1-66'): ScrewAttack,
('Item S1-07-00', 'S1-51'): GreenDoors,
('Item S1-07-00', 'S1-66'): MorphBall,
('S1-66', 'S1-51'): GreenDoors,
('S1-66', 'Item S1-07-00'): BombJump,
('S1-52', 'Item S1-09-04'): SpeedBooster,
('S1-52', 'Charge Core-X'): Missiles,
('S1-52', 'S1-55'): Missiles,
('Item S1-09-04', 'S1-52'): Missiles,
('Item S1-09-04', 'Charge Core-X'): Missiles,
('Item S1-09-04', 'S1-55'): Missiles,
('Charge Core-X', 'Item S1-09-04'): Impossible,
('S1-55', 'S1-52'): Missiles,
('S1-55', 'Item S1-09-04'): SpeedBooster,
('S1-55', 'Charge Core-X'): Missiles,
('S1-5D', 'Item S1-0A-04'): MorphBall,
('Item S1-0A-04', 'S1-5D'): MorphBall,
('S1-65', 'Item S1-0C-07'): GravitySuit,
('Item S1-0C-07', 'S1-65'): GravitySuit,
('S1-6D', 'Item S1-11-02'): MorphBall,
('Item S1-11-02', 'S1-6D'): MorphBall,
('S2-0E', 'Item S2-09-03'): UseBombs,
('Item S2-09-03', 'S2-0E'): BlueDoors,
('Data S2', 'S2-13'): BlueDoors,
('S2-14', 'Item S2-00-05'): UseBombs,
('Item S2-00-05', 'S2-14'): MorphBall,
('Item S2-00-05', 'S2-15'): UseBombs,
('S2-15', 'Item S2-00-05'): HiJump,
('S2-16', 'Item S2-02-0E'): UseBombs,
('Item S2-02-0E', 'S2-16'): SpringBall,
('Item S2-02-0E', 'S2-17'): UseBombs,
('S2-17', 'Item S2-02-0E'): UseBombs,
('S2-26', 'Item S2-0C-0B'): Impossible,
('Item S2-0C-0B', 'S2-26'): Impossible,
('Item S2-0C-0B', 'S2-27'): ChargeBeam,
('S2-28', 'Zazabi'): Missiles,
('S2-28', 'S2-85'): IBJ,
('Zazabi', 'S2-28'): IBJ,
('Zazabi', 'S2-85'): IBJ,
('S2-85', 'S2-28'): IBJ,
('S2-85', 'Zazabi'): ScrewAttack,
('S2-31', 'Item S2-0C-04'): MorphBall,
('Item S2-0C-04', 'S2-31'): MorphBall,
('S2-32', 'Nettori'): Impossible,
('S2-32', 'S2-33'): Impossible,
('Nettori', 'S2-33'): Impossible,
('S2-33', 'S2-32'): Difficulty > 0,
('S2-33', 'Nettori'): Difficulty > 0,
('S2-39', 'Item S2-03-0C'): PowerBombs,
('Item S2-03-0C', 'S2-39'): PowerBombs,
('S2-83', 'Security-Level-1'): ScrewAttack,
('Security-Level-1', 'S2-83'): IBJ,
('Security-Level-1', 'S2-3B'): BlueDoors,
('Security-Level-1', 'S2-3D'): IBJ,
('S2-3E', 'Item S2-09-05'): UseBombs,
('Item S2-09-05', 'S2-3E'): UseBombs,
('Item S2-09-05', 'S2-3F'): UseBombs,
('S2-3F', 'Item S2-09-05'): UseBombs,
('S2-10', 'Item S2-04-04'): UseBombs,
('S2-12', 'Item S2-04-04'): ScrewAttack,
('Item S2-04-04', 'S2-10'): UseBombs,
('Item S2-04-04', 'S2-12'): ScrewAttack,
('Item S2-04-04', 'S2-45'): BlueDoors,
('Item S2-04-04', 'S2-54'): ScrewAttack,
('S2-45', 'Item S2-04-04'): UseBombs,
('S2-54', 'Item S2-04-04'): ScrewAttack,
('S2-49', 'Item S2-04-03'): ScrewAttack,
('Item S2-04-03', 'S2-7D'): ScrewAttack,
('S2-7D', 'Item S2-04-03'): ScrewAttack,
('S2-38', 'Item S2-04-0B'): IBJ,
('Item S2-04-0B', 'S2-38'): WallJump,
('S2-5F', 'Item S2-04-0B'): WallJump,
('S2-6D', 'Item S2-08-08'): IBJ,
('Item S2-08-08', 'S2-6D'): IBJ,
('Item S2-08-08', 'S2-73'): IBJ,
('S2-6E', 'Item S2-08-08'): IBJ,
('S2-73', 'Item S2-08-08'): IBJ,
('S2-72', 'Item S2-05-08'): Ice,
('S2-72', 'Item S2-05-0A'): Ice,
('Item S2-05-08', 'S2-72'): UseBombs,
('Item S2-05-0A', 'S2-72'): UseBombs,
('S2-84', 'Item S2-05-00'): SpaceJump,
('S2-84', 'Item S2-05-01'): SpaceJump,
('Item S2-05-00', 'S2-84'): UseBombs,
('S2-86', 'Item S2-10-0C'): SpeedBooster,
('S2-86', 'Item S2-10-0E'): SpeedBooster,
('S3-08', 'Item S3-06-06'): SpeedBooster,
('Item S3-06-06', 'S3-08'): SpeedBooster,
('Item S3-06-06', 'S3-09'): GreenDoors,
('Item S3-06-06', 'S3-4C'): SpeedBooster,
('S3-4C', 'Item S3-06-06'): Impossible,
('Security-Level-2', 'S3-0A'): GreenDoors,
('Security-Level-2', 'S3-4D'): Impossible,
('S3-4D', 'Security-Level-2'): MorphBall,
('S3-0D', 'Item S3-0B-04'): ScrewAttack,
('Item S3-0B-04', 'S3-0D'): GreenDoors,
('Item S3-0B-04', 'S3-0E'): GreenDoors,
('Item S3-0B-04', 'S3-0F'): UseBombs,
('Item S3-0B-04', 'S3-3C'): ScrewAttack,
('S3-0E', 'Item S3-0B-04'): MorphBall,
('S3-0F', 'Item S3-0B-04'): ScrewAttack,
('S3-3C', 'Item S3-0B-04'): Impossible,
('S3-11', 'Item S3-0A-01'): PowerBombs,
('S3-11', 'Item S3-0B-02'): UseBombs,
('Item S3-0A-01', 'S3-11'): MorphBall,
('Item S3-0A-01', 'S3-12'): HiJump,
('Item S3-0B-02', 'S3-11'): ScrewAttack,
('Item S3-0B-02', 'S3-12'): HiJump,
('S3-12', 'Item S3-0A-01'): PowerBombs,
('S3-12', 'Item S3-0B-02'): UseBombs,
('S3-13', 'Item S3-0F-00'): SpeedBooster,
('Item S3-0F-00', 'S3-53'): ScrewAttack,
('Item S3-0F-00', 'S3-54'): ScrewAttack,
('S3-26', 'Item S3-0F-00'): SpeedBooster,
('S3-53', 'Item S3-0F-00'): ScrewAttack,
('S3-54', 'Item S3-0F-00'): ScrewAttack,
('S3-18', 'Item S3-07-0B'): Energy >= 599,
('Item S3-07-0B', 'S3-18'): Energy >= 199,
('Item S3-07-0B', 'S3-19'): Energy >= 299,
('S3-19', 'Item S3-07-0B'): Energy >= 599,
('S3-28', 'Item S3-11-0A'): WaveBeam,
('S3-28', 'Item S3-12-09'): WaveBeam,
('Item S3-11-0A', 'S3-28'): VariaSuit,
('Item S3-11-0A', 'Item S3-12-09'): VariaSuit,
('Item S3-11-0A', 'S3-4B'): VariaSuit,
('Item S3-11-0A', 'S3-4E'): ScrewAttack,
('Item S3-12-09', 'S3-28'): VariaSuit,
('Item S3-12-09', 'Item S3-11-0A'): VariaSuit,
('Item S3-12-09', 'S3-4B'): VariaSuit,
('Item S3-12-09', 'S3-4E'): ScrewAttack,
('S3-4B', 'Item S3-11-0A'): VariaSuit,
('S3-4B', 'Item S3-12-09'): VariaSuit,
('S3-4E', 'Item S3-11-0A'): ScrewAttack,
('S3-4E', 'Item S3-12-09'): ScrewAttack,
('Data S3', 'S3-2C'): GreenDoors,
('S3-32', 'Wide Core-X'): Missiles,
('S3-38', 'Item S3-01-02'): ScrewAttack,
('S3-38', 'S3-57'): ScrewAttack,
('Item S3-01-02', 'S3-38'): ScrewAttack,
('Item S3-01-02', 'Item S3-03-04'): ScrewAttack,
('Item S3-01-02', 'S3-57'): ScrewAttack,
('Item S3-03-04', 'Item S3-01-02'): ScrewAttack,
('Item S3-03-04', 'S3-57'): ScrewAttack,
('S3-57', 'S3-38'): ScrewAttack,
('S3-57', 'Item S3-01-02'): ScrewAttack,
('S3-57', 'Item S3-03-04'): ScrewAttack,
('S3-3A', 'Item S3-0B-06'): IBJ,
('Item S3-0B-06', 'S3-3A'): IBJ,
('Item S3-0B-06', 'S3-3B'): Impossible,
('Item S3-0B-06', 'S3-3E'): Impossible,
('S3-3B', 'Item S3-0B-06'): IBJ,
('S3-3E', 'Item S3-0B-06'): IBJ,
('S3-45', 'Item S3-11-04'): ScrewAttack,
('Item S3-11-04', 'S3-45'): ScrewAttack,
('S3-27', 'Item S3-0E-0A'): ScrewAttack,
('Item S3-0E-0A', 'S3-27'): ScrewAttack,
('Item S3-0E-0A', 'S3-47'): GreenDoors,
('Item S3-0E-0A', 'S3-4A'): IBJ,
('S3-4A', 'Item S3-0E-0A'): ScrewAttack,
('S3-4F', 'Item S3-14-03'): ScrewAttack,
('S3-4F', 'Item S3-14-09'): GravitySuit,
('Item S3-14-03', 'S3-4F'): Impossible,
('Item S3-14-03', 'S3-50'): ScrewAttack,
('Item S3-14-09', 'S3-4F'): Impossible,
('Item S3-14-09', 'S3-50'): GravitySuit,
('S3-50', 'Item S3-14-03'): Impossible,
('S3-50', 'Item S3-14-09'): Impossible,
('S3-58', 'Item S3-00-05'): ScrewAttack,
('Item S3-00-05', 'S3-58'): ScrewAttack,
('Item S3-00-05', 'S3-59'): ScrewAttack,
('S3-59', 'Item S3-00-05'): ScrewAttack,
('Data S4', 'S4-0A'): RedDoors,
('S4-0D', 'Item S4-0C-06'): DamageRuns,
('Item S4-0C-06', 'S4-0D'): DamageRuns,
('Item S4-0C-06', 'S4-0E'): DamageRuns,
('Item S4-0C-06', 'S4-12'): GravitySuit,
('Item S4-0C-06', 'S4-41'): DamageRuns,
('S4-0E', 'Item S4-0C-06'): GravitySuit,
('S4-12', 'Item S4-0C-06'): GravitySuit,
('S4-41', 'Item S4-0C-06'): GravitySuit,
('Item S4-09-02', 'S4-3F'): Impossible,
('Item S4-09-02', 'S4-40'): Impossible,
('S4-3F', 'Item S4-09-02'): Impossible,
('S4-40', 'Item S4-09-02'): Impossible,
('S4-1D', 'Item S4-0D-01'): UseBombs,
('S4-1D', 'Item S4-0E-02'): UseBombs,
('Item S4-0D-01', 'S4-1D'): Impossible,
('Item S4-0D-01', 'S4-1E'): UseBombs,
('Item S4-0D-01', 'S4-75'): UseBombs,
('Item S4-0E-02', 'S4-1D'): Impossible,
('S4-1E', 'Item S4-0D-01'): UseBombs,
('S4-1E', 'Item S4-0E-02'): UseBombs,
('S4-75', 'Item S4-0D-01'): UseBombs,
('S4-75', 'Item S4-0E-02'): UseBombs,
('S4-23', 'Item S4-0B-08'): None,
('Item S4-0B-08', 'S4-23'): None,
('S4-26', 'Item S4-0A-0C'): PowerBombs,
('Item S4-0A-0C', 'S4-26'): IBJ,
('Item S4-0A-0C', 'S4-27'): IBJ,
('S4-27', 'Item S4-0A-0C'): PowerBombs,
('S4-30', 'Item S4-07-08'): ScrewAttack,
('Item S4-07-08', 'S4-30'): RedDoors,
('Item S4-07-08', 'S4-35'): ScrewAttack,
('Item S4-07-08', 'S4-4D'): ScrewAttack,
('Item S4-07-08', 'S4-4E'): MorphBall,
('S4-35', 'Item S4-07-08'): Impossible,
('S4-4D', 'Item S4-07-08'): ScrewAttack,
('S4-4E', 'Item S4-07-08'): MorphBall,
('S4-31', 'Item S4-07-0A'): ScrewAttack,
('Item S4-07-0A', 'S4-31'): RedDoors,
('Item S4-07-0A', 'S4-36'): ScrewAttack,
('Item S4-07-0A', 'S4-50'): MorphBall,
('S4-36', 'Item S4-07-0A'): ScrewAttack,
('S4-50', 'Item S4-07-0A'): MorphBall,
('Security-Level-4', 'S4-34'): RedDoors,
('Security-Level-4', 'S4-62'): Impossible,
('S4-04', 'Item S4-09-06'): MorphBall,
('Item S4-09-06', 'S4-04'): MorphBall,
('Item S4-09-06', 'S4-3C'): MorphBall,
('S4-3C', 'Item S4-09-06'): MorphBall,
('S4-4C', 'Item S4-00-06'): DamageRuns,
('S4-4C', 'Water Pump'): DamageRuns,
('Item S4-00-06', 'S4-4C'): GravitySuit,
('Item S4-00-06', 'Water Pump'): GravitySuit,
('Water Pump', 'S4-4C'): WaterLowered,
('Water Pump', 'Item S4-00-06'): WaterLowered,
('S4-55', 'Item S4-0F-06'): ScrewAttack,
('S4-55', 'S4-5B'): Energy >= 199,
('S4-55', 'S4-5C'): Energy >= 199,
('Item S4-0F-06', 'S4-55'): Energy >= 199,
('Item S4-0F-06', 'S4-5B'): Energy >= 199,
('Item S4-0F-06', 'S4-5C'): Energy >= 199,
('S4-5B', 'S4-55'): Energy >= 199,
('S4-5B', 'Item S4-0F-06'): ScrewAttack,
('S4-5B', 'S4-5C'): DamageRuns,
('S4-5C', 'S4-55'): Energy >= 199,
('S4-5C', 'Item S4-0F-06'): ScrewAttack,
('S4-5C', 'S4-5B'): DamageRuns,
('S4-5D', 'Item S4-13-07'): ScrewAttack,
('Item S4-12-07', 'Item S4-13-07'): Impossible,
('Item S4-12-07', 'S4-5E'): ScrewAttack,
('Item S4-13-07', 'S4-5D'): ScrewAttack,
('Item S4-13-07', 'Item S4-12-07'): ScrewAttack,
('Item S4-13-07', 'S4-5E'): GravitySuit,
('S4-5E', 'Item S4-12-07'): ScrewAttack,
('S4-5E', 'Item S4-13-07'): GravitySuit,
('S4-67', 'Item S4-06-0E'): GravitySuit,
('Item S4-06-0E', 'S4-67'): UseBombs,
('S4-1A', 'Serris'): Missiles,
('S4-1A', 'S4-68'): Missiles,
('S4-68', 'S4-1A'): Missiles,
('S4-68', 'Serris'): Missiles,
('S4-72', 'Item S4-05-03'): MorphBall,
('Item S4-05-03', 'S4-72'): MorphBall,
('S5-0A', 'Item S5-04-01'): YellowDoors,
('Item S5-05-01', 'Item S5-04-01'): Impossible,
('Data S5', 'S5-34'): YellowDoors,
('Data S5', 'S5-59'): YellowDoors,
('Security-Level-3', 'S5-13'): YellowDoors,
('S5-28', 'S5-13'): YellowDoors,
('S5-17', 'Item S5-0C-07'): BombJump,
('Item S5-0C-07', 'S5-17'): BombJump,
('S5-45', 'Item S5-0F-07'): VariaSuit,
('Item S5-0F-07', 'S5-45'): MorphBall,
('S5-22', 'Item S5-12-04'): PowerBombs,
('Item S5-12-04', 'S5-22'): UseBombs,
('Item S5-12-04', 'S5-23'): UseBombs,
('Item S5-12-04', 'S5-3D'): UseBombs,
('Item S5-12-04', 'S5-3E'): UseBombs,
('Item S5-12-04', 'S5-77'): UseBombs,
('Item S5-12-04', 'S5-78'): UseBombs,
('S5-23', 'Item S5-12-04'): PowerBombs,
('S5-3D', 'Item S5-12-04'): IBJ,
('S5-3E', 'Item S5-12-04'): IBJ,
('S5-77', 'Item S5-12-04'): PowerBombs,
('S5-78', 'Item S5-12-04'): UseBombs,
('S5-3A', 'Nightmare'): SpaceJump,
('S5-3A', 'S5-54'): Impossible,
('Nightmare', 'S5-54'): Impossible,
('S5-54', 'S5-3A'): SpaceJump,
('S5-54', 'Nightmare'): SpaceJump,
('S5-2A', 'Item S5-07-0B'): VariaSuit,
('S5-6C', 'Item S5-07-0B'): VariaSuit,
('Item S5-07-0B', 'S5-2A'): VariaSuit,
('Item S5-07-0B', 'S5-6C'): VariaSuit,
('Item S5-07-0B', 'S5-6D'): VariaSuit,
('Item S5-07-0B', 'S5-6E'): WallJump,
('S5-6D', 'Item S5-07-0B'): VariaSuit,
('S5-6E', 'Item S5-07-0B'): VariaSuit,
('S5-37', 'Item S5-06-05'): VariaSuit,
('Item S5-06-05', 'S5-37'): VariaSuit,
('Item S5-03-04', 'S5-43'): YellowDoors,
('Item S5-03-04', 'S5-49'): ScrewAttack,
('S5-49', 'Item S5-03-04'): ScrewAttack,
('S5-03', 'Item S5-05-04'): ScrewAttack,
('Item S5-05-04', 'S5-03'): YellowDoors,
('Item S5-05-04', 'S5-52'): YellowDoors,
('S5-52', 'Item S5-05-04'): ScrewAttack,
('S5-1A', 'Item S5-16-04'): Impossible,
('Item S5-16-04', 'S5-1A'): SpaceJump,
('Item S5-16-04', 'S5-27'): Impossible,
('S5-27', 'Item S5-16-04'): UseBombs,
('S5-4B', 'Item S5-0B-01'): ScrewAttack,
('Item S5-0B-01', 'S5-4B'): ScrewAttack,
('Item S5-0B-01', 'S5-57'): ScrewAttack,
('Item S5-0B-01', 'S5-58'): ScrewAttack,
('S5-57', 'Item S5-0B-01'): ScrewAttack,
('S5-58', 'Item S5-0B-01'): ScrewAttack,
('S5-76', 'Item S5-11-05'): PowerBombs,
('Item S5-11-05', 'S5-76'): PowerBombs,
('S5-73', 'Item S5-14-07'): GravitySuit,
('Item S5-14-07', 'S5-7B'): GravitySuit,
('S5-7B', 'Item S5-14-07'): GravitySuit,
('S5-2F', 'Item S5-0E-08'): SpaceJump,
('Item S5-0E-08', 'S5-2F'): VariaSuit,
('S6-01', 'Item S6-05-03'): Impossible,
('Item S6-05-03', 'S6-01'): Impossible,
('Item S6-05-03', 'S6-02'): Impossible,
('Item S6-05-03', 'S6-33'): MorphBall,
('Item S6-05-03', 'S6-4F'): Impossible,
('S6-02', 'Item S6-05-03'): Impossible,
('S6-33', 'Item S6-05-03'): MorphBall,
('S6-4F', 'Item S6-05-03'): Impossible,
('S6-19', 'Mega Core-X'): ChargeBeam,
('Mega Core-X', 'S6-19'): GreenDoors,
('S6-34', 'S6-19'): GreenDoors,
('S6-34', 'Mega Core-X'): ChargeBeam,
('S6-1D', 'Item S6-05-0B'): IBJ,
('Item S6-05-0B', 'S6-1D'): UseBombs,
('S6-1E', 'Wave Core-X'): GravitySuit,
('S6-1E', 'S6-1F'): GravitySuit,
('S6-1E', 'S6-24'): GravitySuit,
('S6-1E', 'S6-57'): ScrewAttack,
('Wave Core-X', 'S6-1E'): Impossible,
('Wave Core-X', 'S6-57'): Impossible,
('S6-1F', 'S6-1E'): Impossible,
('S6-1F', 'Wave Core-X'): GravitySuit,
('S6-1F', 'S6-24'): GravitySuit,
('S6-1F', 'S6-57'): Impossible,
('S6-24', 'S6-1E'): Impossible,
('S6-24', 'Wave Core-X'): GravitySuit,
('S6-24', 'S6-1F'): GravitySuit,
('S6-24', 'S6-57'): Impossible,
('S6-57', 'S6-1E'): ScrewAttack,
('S6-57', 'Wave Core-X'): ScrewAttack,
('S6-57', 'S6-1F'): ScrewAttack,
('S6-57', 'S6-24'): ScrewAttack,
('S6-25', 'Item S6-09-05'): IceBeam,
('S6-25', 'Item S6-0A-06'): WaveBeam,
('Item S6-09-05', 'S6-25'): ScrewAttack,
('Item S6-09-05', 'S6-58'): UseBombs,
('Item S6-0A-06', 'S6-25'): WaveBeam,
('Item S6-0A-06', 'S6-58'): ScrewAttack,
('S6-58', 'Item S6-09-05'): IceBeam,
('S6-58', 'Item S6-0A-06'): ScrewAttack,
('S6-31', 'Item S6-0E-03'): UseBombs,
('Item S6-0E-03', 'S6-31'): UseBombs,
('Data S6', 'S6-35'): GreenDoors,
('Data S6', 'S6-3E'): GreenDoors,
('Item S6-06-08', 'S6-36'): UseBombs,
('S6-36', 'Item S6-06-08'): PowerBombs,
('S6-3F', 'Item S6-0C-08'): Impossible,
('S6-3F', 'Item S6-0B-09'): WallJump,
('Item S6-0C-08', 'S6-42'): Impossible,
('Item S6-0B-09', 'S6-3F'): MorphBall,
('Item S6-0B-09', 'S6-40'): MorphBall,
('Item S6-0B-09', 'S6-42'): Impossible,
('S6-40', 'Item S6-0C-08'): Impossible,
('S6-40', 'Item S6-0B-09'): WallJump,
('S6-42', 'Item S6-0B-09'): MorphBall,
('S6-4C', 'Item S6-08-03'): UseBombs,
('Item S6-08-03', 'S6-4C'): SpringBall,
('S6-56', 'Item S6-0E-04'): SpeedBooster,
('Item S6-0E-04', 'S6-56'): SpeedBooster,
('S6-5A', 'Item S6-03-04'): SpeedBooster,
('S6-5A', 'Item S6-01-06'): SpaceJump,
('Item S6-03-04', 'S6-5A'): SpeedBooster,
('Item S6-01-06', 'S6-5A'): SpeedBooster,
('S5-4D', 'S5-50'): YellowDoors,
('S5-0A', 'S5-0C'): YellowDoors,
('S5-03', 'S5-0B'): WaveBeam,
('S5-55', 'S5-1F'): YellowDoors,
('S5-37', 'S5-39'): YellowDoors,
('S5-24', 'S5-1C'): YellowDoors,
('S5-15', 'S5-1D'): YellowDoors,
('S5-64', 'S5-46'): WaveBeam,
('S5-56', 'S5-5C'): WaveBeam }
def find_available_areas(graph):
check = int(StartLocation[1:2])
AreaOpen[check] = StartLocation
if AreaOpen[0] == None:
check = 'S0-32'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[0] = check
if AreaOpen[1] == None:
check = 'S1-00'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[1] = check
if ScrewAttack:
if AreaOpen[1] == None:
check = 'S1-6B'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[1] = check
if AreaOpen[1] == None:
check = 'S1-68'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[1] = check
if AreaOpen[2] == None:
check = 'S2-00'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[2] = check
if ScrewAttack:
if AreaOpen[2] == None:
check = 'S2-7F'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[2] = check
if AreaOpen[2] == None:
check = 'S2-82'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[2] = check
if AreaOpen[3] == None:
check = 'S3-00'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[3] = check
if ScrewAttack:
if AreaOpen[3] == None:
check = 'S3-56'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[3] = check
if AreaOpen[3] == None:
check = 'S3-59'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[3] = check
if AreaOpen[4] == None:
check = 'S4-00'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[4] = check
if ScrewAttack:
if AreaOpen[4] == None:
check = 'S4-6A'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[4] = check
if AreaOpen[4] == None:
check = 'S4-6C'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[4] = check
if AreaOpen[5] == None:
check = 'S5-00'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[5] = check
if ScrewAttack:
if AreaOpen[5] == None:
check = 'S5-53'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[5] = check
if AreaOpen[6] == None:
check = 'S6-00'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[6] = check
if ScrewAttack:
if AreaOpen[6] == None:
check = 'S6-51'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[6] = check
if AreaOpen[6] == None:
check = 'S6-54'
path = graph.get_path(StartLocation, check)
if path != None:
path = graph.get_path(check, StartLocation)
if path != None:
AreaOpen[6] = check
if BlueDoors == False:
path = graph.get_path(StartLocation, 'Security-Level-1', depth=250)
if path != None:
enable_item(graph, 'BlueDoors')
path = graph.get_path('Security-Level-1', StartLocation, depth=250)
if path == None:
disable_item(graph, 'BlueDoors')
if GreenDoors == False:
path = graph.get_path(StartLocation, 'Security-Level-2', depth=250)
if path != None:
enable_item(graph, 'GreenDoors')
path = graph.get_path('Security-Level-2', StartLocation, depth=250)
if path == None:
disable_item(graph, 'GreenDoors')
elif SeedSettings['SplitSecurity'] == False:
enable_item(graph, 'BlueDoors')
if YellowDoors == False:
path = graph.get_path(StartLocation, 'Security-Level-3', depth=250)
if path != None:
enable_item(graph, 'YellowDoors')
path = graph.get_path('Security-Level-3', StartLocation, depth=250)
if path == None:
disable_item(graph, 'YellowDoors')
elif SeedSettings['SplitSecurity'] == False:
enable_item(graph, 'GreenDoors')
enable_item(graph, 'BlueDoors')
if RedDoors == False:
path = graph.get_path(StartLocation, 'Security-Level-4', depth=250)
if path != None:
enable_item(graph, 'RedDoors')
path = graph.get_path('Security-Level-4', StartLocation, depth=250)
if path == None:
disable_item(graph, 'RedDoors')
elif SeedSettings['SplitSecurity'] == False:
enable_item(graph, 'YellowDoors')
enable_item(graph, 'GreenDoors')
enable_item(graph, 'BlueDoors')
if WaterLowered == False:
path = graph.get_path(StartLocation, 'S4-00')
if path != None:
path = graph.get_path('S4-00', 'Water Pump', True)
if path != None:
enable_item(graph, 'WaterLowered')
path = graph.get_path('Water Pump', 'S4-00', True)
if path == None:
disable_item(graph, 'WaterLowered')
def randomize_game(graph):
global MaxETanks
global MissileCount
global NettoriOpen
global PlacedETanks
global PlacedMissiles
global PlacedPowerBombs
global areaLayout
update_requirements(graph)
PlacedETanks = PlacedMissiles = PlacedPowerBombs = 0
gameBeatable = False
init = False
weightInit = False
startingWeights = list()
availableItems = list()
areaWeights = list()
MajorLocations = list()
MinorLocations = list()
PossibleMissileTanks = list()
AllItemLocations = list()
locationWeights = list()
locationsPerArea = list()
weightValue = list()
newLocations = list()
invalidItems = list()
invalidWeights = list()
oldLocations = list()
oldWeights = list()
FirstItem = None
AddETank = False
attemptedLayouts = [[5,3,1,2,4,6]]
WeightedMajors = { 'MainMissiles': 16,
'MorphBall': 16,
'ChargeBeam': 8,
'Bombs': 14,
'HiJumpBoots': 14,
'SpeedBooster': 8,
'SuperMissileItem': 8,
'VariaSuit': 12,
'IceMissileItem': 6,
'WideBeam': 4,
'MainPowerBombs': 6,
'SpaceJump': 4,
'PlasmaBeam': 2,
'GravitySuit': 4,
'DiffusionItem': 6,
'WaveBeam': 4,
'ScrewAttack': 2,
'IceBeam': 2}
BossHealths = {
'Arachnus': 0,
'Yakuza': 1000,
'Ridley': 4500,
'Charge Core-X': 0,
'Zazabi': 100,
'Nettori': 2000,
'Data S3': 300,
'Wide Core-X': 0,
'Serris': 50,
'Nightmare': 1800,
'Mega Core-X': 0,
'Box-2': 500}
print('Generating, please wait...')
while True:
if not gameBeatable == False:
if not init == False:
if not SeedSettings['SectorShuffle'] == True:
areaDoors = {1:[
'S1-6B', 'S1-68'],
2:[
'S2-7F', 'S2-82'],
3:[
'S3-59', 'S3-56'],
4:[
'S4-6C', 'S4-6A'],
5:[
'S5-02', 'S5-53'],
6:[
'S6-51', 'S6-54']}
areaLayout = random.sample(range(1, 7), 6)
if SeedSettings['MajorMinor'] == True:
if areaLayout[2] != 1:
if areaLayout[2] != 2:
if areaLayout[3] != 1:
if areaLayout[3] != 2:
attemptedLayouts.append(areaLayout)
while True:
if areaLayout in attemptedLayouts:
areaLayout = random.sample(range(1, 7), 6)
while True:
pass
while areaLayout in attemptedLayouts:
areaLayout = random.sample(range(1, 7), 6)
attemptedLayouts.append(areaLayout)
for area in areaLayout:
elevator = areaLayout.index(area)
if elevator == 0:
leftArea = areaLayout[5]
else:
leftArea = areaLayout[areaLayout.index(area) - 1]
if elevator == 5:
rightArea = areaLayout[0]
else:
rightArea = areaLayout[areaLayout.index(area) + 1]
if area == 1:
topTile = 19
bottomTile = 35
leftTile = 179
rightTile = 180
tileset = 17
if leftArea > 2:
leftTube = 226 + leftArea
else:
leftTube = 235 + leftArea
if rightArea > 2:
rightTube = 9 + rightArea
elif rightArea == 2:
rightTube = 4
else:
rightTube = 1
graph.patcher.update({4857211: leftTube})
graph.patcher.update({4857224: (leftTube + 16)})
graph.patcher.update({4856958: rightTube})
graph.patcher.update({4856975: (rightTube + 16)})
elif area == 2:
topTile = 20
bottomTile = 36
leftTile = 181
rightTile = 182
tileset = 35
if leftArea > 2:
leftTube = 9 + leftArea
elif leftArea == 2:
leftTube = 4
else:
leftTube = 1
if rightArea > 2:
rightTube = 226 + rightArea
else:
rightTube = 235 + rightArea
graph.patcher.update({5091931: leftTube})
graph.patcher.update({5091944: (leftTube + 16)})
graph.patcher.update({5092202: rightTube})
graph.patcher.update({5092219: (rightTube + 16)})
elif area == 3:
topTile = 21
bottomTile = 37
leftTile = 183
rightTile = 184
tileset = 36
if leftArea > 2:
leftTube = 226 + leftArea
else:
leftTube = 235 + leftArea
if rightArea > 2:
rightTube = 9 + rightArea
elif rightArea == 2:
rightTube = 4
else:
rightTube = 1
graph.patcher.update({5254431: leftTube})
graph.patcher.update({5254447: (leftTube + 16)})
graph.patcher.update({5254714: rightTube})
graph.patcher.update({5254731: (rightTube + 16)})
elif area == 4:
topTile = 51
bottomTile = 67
leftTile = 195
rightTile = 196
tileset = 37
if leftArea > 2:
leftTube = 9 + leftArea
elif leftArea == 2:
leftTube = 4
else:
leftTube = 1
if rightArea > 2:
rightTube = 226 + rightArea
else:
rightTube = 235 + rightArea
graph.patcher.update({5512395: leftTube})
graph.patcher.update({5512408: (leftTube + 16)})
graph.patcher.update({5512134: rightTube})
graph.patcher.update({5512151: (rightTube + 16)})
elif area == 5:
topTile = 52
bottomTile = 68
leftTile = 197
rightTile = 198
tileset = 38
if leftArea > 2:
leftTube = 226 + leftArea
else:
leftTube = 235 + leftArea
if rightArea > 2:
rightTube = 226 + rightArea
else:
rightTube = 235 + rightArea
graph.patcher.update({5358711: leftTube})
graph.patcher.update({5358724: (leftTube + 16)})
graph.patcher.update({5361542: rightTube})
graph.patcher.update({5361559: (rightTube + 16)})
elif area == 6:
topTile = 24
bottomTile = 40
leftTile = 199
rightTile = 200
tileset = 39
if leftArea > 2:
leftTube = 226 + leftArea
else:
leftTube = 235 + leftArea
if rightArea > 2:
rightTube = 226 + rightArea
else:
rightTube = 235 + rightArea
graph.patcher.update({5598427: leftTube})
graph.patcher.update({5598440: (leftTube + 16)})
graph.patcher.update({5598706: rightTube})
graph.patcher.update({5598723: (rightTube + 16)})
if elevator == 0:
graph.patcher.update({4669078: leftTile})
graph.patcher.update({4669079: rightTile})
graph.patcher.update({4669026: leftTile})
graph.patcher.update({4669027: rightTile})
graph.patcher.update({4670120: leftTile})
graph.patcher.update({4670121: rightTile})
graph.patcher.update({4670922: leftTile})
graph.patcher.update({4670923: rightTile})
graph.patcher.update({4671720: leftTile})
graph.patcher.update({4671721: rightTile})
graph.patcher.update({4672508: leftTile})
graph.patcher.update({4672509: rightTile})
graph.patcher.update({4673296: leftTile})
graph.patcher.update({4673297: rightTile})
graph.patcher.update({4674087: topTile})
graph.patcher.update({4674099: bottomTile})
graph.patcher.update({3945300: tileset})
graph.patcher.update({5713644: (171 + area)})
source = 'S0-47'
elif elevator == 1:
graph.patcher.update({4669038: leftTile})
graph.patcher.update({4669039: rightTile})
graph.patcher.update({4669028: leftTile})
graph.patcher.update({4669029: rightTile})
graph.patcher.update({4670106: leftTile})
graph.patcher.update({4670107: rightTile})
graph.patcher.update({4670908: leftTile})
graph.patcher.update({4670909: rightTile})
graph.patcher.update({4671708: leftTile})
graph.patcher.update({4671709: rightTile})
graph.patcher.update({4672494: leftTile})
graph.patcher.update({4672495: rightTile})
graph.patcher.update({4674067: leftTile})
graph.patcher.update({4674068: rightTile})
graph.patcher.update({4673301: topTile})
graph.patcher.update({4673315: bottomTile})
graph.patcher.update({3945240: tileset})
graph.patcher.update({5713617: (171 + area)})
source = 'S0-45'
elif elevator == 2:
graph.patcher.update({4669001: leftTile})
graph.patcher.update({4669002: rightTile})
graph.patcher.update({4669030: leftTile})
graph.patcher.update({4669031: rightTile})
graph.patcher.update({4670094: leftTile})
graph.patcher.update({4670095: rightTile})
graph.patcher.update({4670896: leftTile})
graph.patcher.update({4670897: rightTile})
graph.patcher.update({4671696: leftTile})
graph.patcher.update({4671697: rightTile})
graph.patcher.update({4673279: leftTile})
graph.patcher.update({4673280: rightTile})
graph.patcher.update({4674079: leftTile})
graph.patcher.update({4674080: rightTile})
graph.patcher.update({4672499: topTile})
graph.patcher.update({4672513: bottomTile})
graph.patcher.update({3945180: tileset})
graph.patcher.update({5713597: (171 + area)})
source = 'S0-43'
elif elevator == 3:
graph.patcher.update({4669012: leftTile})
graph.patcher.update({4669013: rightTile})
graph.patcher.update({4669057: leftTile})
graph.patcher.update({4669058: rightTile})
graph.patcher.update({4670884: leftTile})
graph.patcher.update({4670885: rightTile})
graph.patcher.update({4671684: leftTile})
graph.patcher.update({4671685: rightTile})
graph.patcher.update({4672489: leftTile})
graph.patcher.update({4672490: rightTile})
graph.patcher.update({4673291: leftTile})
graph.patcher.update({4673292: rightTile})
graph.patcher.update({4674091: leftTile})
graph.patcher.update({4674092: rightTile})
graph.patcher.update({4670111: topTile})
graph.patcher.update({4670125: bottomTile})
graph.patcher.update({3945000: tileset})
graph.patcher.update({5713600: (171 + area)})
source = 'S0-44'
elif elevator == 4:
graph.patcher.update({4669049: leftTile})
graph.patcher.update({4669050: rightTile})
graph.patcher.update({4669059: leftTile})
graph.patcher.update({4669060: rightTile})
graph.patcher.update({4670115: leftTile})
graph.patcher.update({4670116: rightTile})
graph.patcher.update({4671672: leftTile})
graph.patcher.update({4671673: rightTile})
graph.patcher.update({4672503: leftTile})
graph.patcher.update({4672504: rightTile})
graph.patcher.update({4673305: leftTile})
graph.patcher.update({4673306: rightTile})
graph.patcher.update({4674103: leftTile})
graph.patcher.update({4674104: rightTile})
graph.patcher.update({4670913: topTile})
graph.patcher.update({4670927: bottomTile})
graph.patcher.update({3945060: tileset})
graph.patcher.update({5713621: (171 + area)})
source = 'S0-46'
elif elevator == 5:
graph.patcher.update({4669089: leftTile})
graph.patcher.update({4669090: rightTile})
graph.patcher.update({4669061: leftTile})
graph.patcher.update({4669062: rightTile})
graph.patcher.update({4670129: leftTile})
graph.patcher.update({4670130: rightTile})
graph.patcher.update({4670917: leftTile})
graph.patcher.update({4670918: rightTile})
graph.patcher.update({4672517: leftTile})
graph.patcher.update({4672518: rightTile})
graph.patcher.update({4673319: leftTile})
graph.patcher.update({4673320: rightTile})
graph.patcher.update({4674115: leftTile})
graph.patcher.update({4674116: rightTile})
graph.patcher.update({4671701: topTile})
graph.patcher.update({4671713: bottomTile})
graph.patcher.update({3945120: tileset})
graph.patcher.update({5713647: (171 + area)})
source = 'S0-48'
destination = 'S{}-00'.format(area)
graph.UpdateDoorConnection(source, destination)
graph.UpdateDoorConnection(destination, source)
source = areaDoors.get(area)[0]
destination = areaDoors.get(leftArea)[1]
graph.UpdateDoorConnection(source, destination)
source = areaDoors.get(area)[1]
destination = areaDoors.get(rightArea)[0]
graph.UpdateDoorConnection(source, destination)
graph.ConnectAllNodes()
PlacedETanks = PlacedMissiles = PlacedPowerBombs = 0
if SeedSettings['DamageRuns']:
Energy = PlacedETanks * 100 + 99
MissileCount = 10
locationWeights.clear()
locationsPerArea.clear()
areaWeights.clear()
weightValue.clear()
MajorLocations.clear()
MinorLocations.clear()
AllItemLocations.clear()
newLocations.clear()
AccessibleLocations.clear()
UsedLocations.clear()
PlacedItems.clear()
NettoriOpen = False
invalidItems.clear()
invalidWeights.clear()
oldLocations.clear()
oldWeights.clear()
MajorLocations.extend(graph.majorItemLocations)
if SeedSettings['MajorMinor'] == False:
MajorLocations.extend(graph.minorItemLocations)
MinorLocations.extend(graph.minorItemLocations)
AllItemLocations.extend(graph.majorItemLocations)
AllItemLocations.extend(graph.minorItemLocations)
random.shuffle(MajorLocations)
random.shuffle(MinorLocations)
random.shuffle(AllItemLocations)
for item in MajorItems:
disable_item(graph, item)
disable_item(graph, 'BlueDoors')
disable_item(graph, 'GreenDoors')
disable_item(graph, 'YellowDoors')
disable_item(graph, 'RedDoors')
disable_item(graph, 'WaterLowered')
for area in range(0, 7):
AreaOpen[area] = None
locationsPerArea.append(list())
areaWeights.append(1)
weightValue.append(1)
MajorList = list(WeightedMajors.keys())
if SeedSettings['MissilesWithoutMainData']:
WeightedMajors.update({'MainMissiles': 8})
WeightedMajors.update({'SuperMissileItem': 8})
WeightedMajors.update({'IceMissileItem': 8})
WeightedMajors.update({'DiffusionItem': 8})
if SeedSettings['PowerBombsWithoutBombs']:
WeightedMajors.update({'Bombs': 10})
WeightedMajors.update({'MainPowerBombs': 10})
if SeedSettings['DamageRuns']:
WeightedMajors.update({'VariaSuit': 4})
MajorWeights = list(WeightedMajors.values())
MajorWeights.pop(MajorList.index('Bombs'))
MajorList.remove('Bombs')
MajorWeights.pop(MajorList.index('MainPowerBombs'))
MajorList.remove('MainPowerBombs')
if SeedSettings['MissilesWithoutMainData'] == False:
MajorWeights.pop(MajorList.index('IceMissileItem'))
MajorList.remove('IceMissileItem')
MajorWeights.pop(MajorList.index('SuperMissileItem'))
MajorList.remove('SuperMissileItem')
MajorWeights.pop(MajorList.index('DiffusionItem'))
MajorList.remove('DiffusionItem')
if weightInit == False:
availableItems.clear()
path = None
for location in MajorLocations:
path = graph.get_path(StartLocation, location)
if path != None:
break
if path == None:
print('Path: No accessible locations found with this start, try changing your game settings.')
else:
for item in MajorItems:
enable_item(graph, item)
currentItemWeight = 0
find_available_areas(graph)
for location in MajorLocations:
path = graph.get_path(StartLocation, location)
if path != None:
currentItemWeight += 1
if currentItemWeight > 1:
availableItems.append(item)
break
for area in range(0, 7):
AreaOpen[area] = None
disable_item(graph, item)
disable_item(graph, 'WaterLowered')
disable_item(graph, 'BlueDoors')
disable_item(graph, 'GreenDoors')
disable_item(graph, 'YellowDoors')
disable_item(graph, 'RedDoors')
weightInit = True
if len(availableItems) < 1:
print('Items: No accessible locations found with this start, try changing your game settings.')
find_available_areas(graph)
for location in MajorLocations:
path = graph.get_path(StartLocation, location)
if path != None:
AccessibleLocations.append(location)
for area in range(0, 7):
if location in AreaItemLocations[area]:
if location not in locationsPerArea[area]:
locationsPerArea[area].append(location)
for area in range(0, 7):
if len(locationsPerArea[area]) > 0:
areaWeights[area] = weightValue[area] / len(locationsPerArea[area])
for location in AccessibleLocations:
for area in range(0, 7):
if location in AreaItemLocations[area]:
locationWeights.append(areaWeights[area])
if FirstItem == None:
FirstItem = random.choice(availableItems)
MajorWeights.pop(MajorList.index(FirstItem))
MajorList.remove(FirstItem)
enable_item(graph, FirstItem)
path = None
if SeedSettings['DamageRuns']:
Energy = Energy / 2
while True:
if not path == None:
location = random.choice(AccessibleLocations)
path = graph.get_path(location, StartLocation)
if path != None:
locationWeights.pop(AccessibleLocations.index(location))
AccessibleLocations.remove(location)
UsedLocations.append(location)
PlacedItems.append(FirstItem)
for area in range(0, 7):
if location not in AreaItemLocations[area]:
weightValue[area] += 1
if FirstItem == 'MainMissiles':
if SeedSettings['MissilesWithoutMainData'] == False:
MajorList.append('IceMissileItem')
MajorWeights.append(WeightedMajors.get('IceMissileItem'))
MajorList.append('SuperMissileItem')
MajorWeights.append(WeightedMajors.get('SuperMissileItem'))
MajorList.append('DiffusionItem')
MajorWeights.append(WeightedMajors.get('DiffusionItem'))
elif FirstItem == 'MorphBall':
MajorList.append('Bombs')
MajorWeights.append(WeightedMajors.get('Bombs'))
if SeedSettings['PowerBombsWithoutBombs'] == True:
MajorList.append('MainPowerBombs')
MajorWeights.append(WeightedMajors.get('MainPowerBombs'))
elif FirstItem == 'Bombs':
if SeedSettings['PowerBombsWithoutBombs'] == False:
MajorList.append('MainPowerBombs')
MajorWeights.append(WeightedMajors.get('MainPowerBombs'))
init = True
if SeedSettings['DamageRuns']:
Energy = PlacedETanks * 100 + 99
find_available_areas(graph)
path = graph.get_path(StartLocation, 'End-of-Game')
if path != None:
path = graph.get_path('End-of-Game', 'S0-00')
if path != None:
gameBeatable = True
if not gameBeatable == False:
newLocations.clear()
locationWeights.clear()
for location in MajorLocations:
path = None
if location not in UsedLocations:
if location not in AccessibleLocations:
if not location == 'Data S0' or location == 'Item S0-05-16':
path = graph.get_path(location, StartLocation, depth=250)
for area in range(0, 7):
if location in AreaItemLocations[area]:
if AreaOpen[area]:
path = graph.get_path(AreaOpen[area], location, True)
break
if path != None:
AccessibleLocations.append(location)
MajorLocations.remove(location)
newLocations.append(location)
for area in range(0, 7):
if location in AreaItemLocations[area]:
if location not in locationsPerArea[area]:
locationsPerArea[area].append(location)
for area in range(0, 7):
if len(locationsPerArea[area]) > 0:
if SeedSettings['MajorMinor']:
areaWeights[area] = weightValue[area] / len(locationsPerArea[area])
else:
areaWeights[area] = weightValue[area] / len(locationsPerArea[area]) + area
for location in AccessibleLocations:
for area in range(0, 7):
if location in AreaItemLocations[area]:
if location in newLocations:
locationWeights.append(areaWeights[area] * 1.8)
else:
if location in BossLocations:
if SeedSettings['MajorMinor'] == False:
locationWeights.append(areaWeights[area] * 1.5)
locationWeights.append(areaWeights[area])
if not len(MajorList) > 0:
itemLocation = None
path = None
item = random.choices(MajorList, weights=MajorWeights, k=1)[0]
currentItemWeight = MajorWeights.pop(MajorList.index(item))
MajorList.remove(item)
enable_item(graph, item)
if SeedSettings['DamageRuns']:
Energy = Energy / 2
while True:
if not path == None:
if not len(AccessibleLocations) > 0:
itemLocation = random.choices(AccessibleLocations, weights=locationWeights, k=1)[0]
oldLocationWeight = locationWeights.pop(AccessibleLocations.index(itemLocation))
AccessibleLocations.remove(itemLocation)
if itemLocation == 'Data S0' or itemLocation == 'Item S0-05-16':
path = graph.get_path(itemLocation, StartLocation, depth=250)
else:
for area in range(0, 7):
if itemLocation in AreaItemLocations[area]:
if AreaOpen[area]:
path = graph.get_path(itemLocation, AreaOpen[area], True)
break
if not itemLocation in BossLocations:
if not path != None:
disable_item(graph, item)
if ChargeBeam == False:
if SeedSettings['Difficulty'] > 0:
healthCheck = BossHealths.get(itemLocation)
if SeedSettings['Difficulty'] > 4:
healthCheck = healthCheck * 1.02
elif SeedSettings['Difficulty'] > 2:
healthCheck = healthCheck * 1.05
else:
healthCheck = healthCheck * 1.1
healthCheck = healthCheck - MissileDamage * MissileCount
if healthCheck > 0:
if MissileDamage > 0:
tankCheck = math.ceil(healthCheck / MissileDamage / 5)
PossibleMissileTanks.clear()
if SeedSettings['MajorMinor']:
for missileLocation in MinorLocations:
if missileLocation not in UsedLocations:
missilePath = None
if missileLocation == 'Item S0-05-16':
missilePath = graph.get_path(StartLocation, missileLocation, depth=250)
if missilePath != None:
missilePath = graph.get_path(missileLocation, StartLocation, depth=250)
else:
for area in range(0, 7):
if missileLocation in AreaItemLocations[area]:
if AreaOpen[area]:
missilePath = graph.get_path(AreaOpen[area], missileLocation, True)
if missilePath != None:
missilePath = graph.get_path(missileLocation, AreaOpen[area], True)
break
if missilePath != None:
PossibleMissileTanks.append(missileLocation)
else:
for missileLocation in AccessibleLocations:
missilePath = None
if not missileLocation == 'Data S0' or missileLocation == 'Item S0-05-16':
missilePath = graph.get_path(missileLocation, StartLocation, depth=250)
for area in range(0, 7):
if missileLocation in AreaItemLocations[area]:
if AreaOpen[area]:
missilePath = graph.get_path(missileLocation, AreaOpen[area], True)
break
if missilePath != None:
if missileLocation not in BossLocations:
PossibleMissileTanks.append(missileLocation)
if len(PossibleMissileTanks) > int(tankCheck):
for x in range(0, int(tankCheck)):
missileLocation = random.choice(PossibleMissileTanks)
PossibleMissileTanks.remove(missileLocation)
if SeedSettings['MajorMinor'] == False:
locationWeights.pop(AccessibleLocations.index(missileLocation))
AccessibleLocations.remove(missileLocation)
UsedLocations.append(missileLocation)
PlacedItems.append('Missile Tank')
PlacedMissiles += 1
MissileCount = 10 + PlacedMissiles * 5
update_items(graph)
else:
path = None
else:
path = None
enable_item(graph, item)
if path == None:
oldLocations.append(itemLocation)
oldWeights.append(oldLocationWeight)
if path == None:
if len(MajorList) > 0 and len(PlacedItems) > 4:
invalidItems.append(item)
invalidWeights.append(currentItemWeight)
AccessibleLocations.extend(oldLocations)
oldLocations.clear()
locationWeights.extend(oldWeights)
oldWeights.clear()
disable_item(graph, item)
else:
for item in MajorItems:
disable_item(graph, item)
print("Couldn't find a path forward, trying again")
init = False
else:
UsedLocations.append(itemLocation)
PlacedItems.append(item)
MajorList.extend(invalidItems)
invalidItems.clear()
MajorWeights.extend(invalidWeights)
invalidWeights.clear()
AccessibleLocations.extend(oldLocations)
oldLocations.clear()
locationWeights.extend(oldWeights)
oldWeights.clear()
for area in range(0, 7):
if itemLocation in locationsPerArea[area]:
locationsPerArea[area].remove(itemLocation)
if itemLocation not in AreaItemLocations[area]:
weightValue[area] += 1
elif item == 'MainMissiles':
if SeedSettings['MissilesWithoutMainData'] == False:
MajorList.append('IceMissileItem')
MajorWeights.append(WeightedMajors.get('IceMissileItem'))
MajorList.append('SuperMissileItem')
MajorWeights.append(WeightedMajors.get('SuperMissileItem'))
MajorList.append('DiffusionItem')
MajorWeights.append(WeightedMajors.get('DiffusionItem'))
elif item == 'MorphBall':
MajorList.append('Bombs')
MajorWeights.append(WeightedMajors.get('Bombs'))
if SeedSettings['PowerBombsWithoutBombs'] == True:
MajorList.append('MainPowerBombs')
MajorWeights.append(WeightedMajors.get('MainPowerBombs'))
elif item == 'Bombs':
if SeedSettings['PowerBombsWithoutBombs'] == False:
MajorList.append('MainPowerBombs')
MajorWeights.append(WeightedMajors.get('MainPowerBombs'))
if SeedSettings['MajorMinor'] == False:
if not len(AccessibleLocations) > 3:
if PlacedETanks < MaxETanks:
itemLocation = random.choice(AccessibleLocations)
locationWeights.pop(AccessibleLocations.index(itemLocation))
AccessibleLocations.remove(itemLocation)
UsedLocations.append(itemLocation)
PlacedItems.append('Energy Tank')
PlacedETanks += 1
for item in MajorItems:
disable_item(graph, item)
print("Couldn't find a path forward, trying again")
init = False
print('Game is beatable, placing remaining items (no logic)')
for item in MajorItems:
if item not in PlacedItems:
if item not in MajorList:
MajorList.append(item)
MajorWeights.append(WeightedMajors.get(item))
MajorLocations.extend(AccessibleLocations)
for item in MajorList:
if item not in PlacedItems:
location = random.choice(MajorLocations)
while location in UsedLocations:
MajorLocations.remove(location)
location = random.choice(MajorLocations)
UsedLocations.append(location)
PlacedItems.append(item)
if SeedSettings['MajorMinor']:
for location in MajorLocations:
if PlacedETanks < MaxETanks:
if location not in UsedLocations:
UsedLocations.append(location)
PlacedItems.append(MinorItems[0])
PlacedETanks += 1
MaxETanks = PlacedETanks
if PlacedETanks >= MaxETanks:
MinorItems.remove('Energy Tank')
if PlacedMissiles >= MaxMissiles:
MinorItems.remove('Missile Tank')
if PlacedPowerBombs >= MaxPowerBombs:
MinorItems.remove('Power Bomb Tank')
for location in AllItemLocations:
if len(MinorItems) > 0:
if location not in UsedLocations:
item = random.choice(MinorItems)
UsedLocations.append(location)
PlacedItems.append(item)
if item == 'Energy Tank':
PlacedETanks += 1
if PlacedETanks >= MaxETanks:
MinorItems.remove('Energy Tank')
else:
if item == 'Missile Tank':
PlacedMissiles += 1
if not PlacedMissiles >= MaxMissiles:
MinorItems.remove('Missile Tank')
if item == 'Power Bomb Tank':
PlacedPowerBombs += 1
if PlacedPowerBombs >= MaxPowerBombs:
MinorItems.remove('Power Bomb Tank')
patch_game()
def patch_game():
global FileName, BaseName
CreditsOffsets = {
'ChargeBeam': 7655617,
'WideBeam': 7655725,
'PlasmaBeam': 7655833,
'WaveBeam': 7655941,
'IceBeam': 7656049,
'MainMissiles': 7656157,
'SuperMissileItem': 7656265,
'IceMissileItem': 7656373,
'DiffusionItem': 7656481,
'Bombs': 7656589,
'MainPowerBombs': 7656697,
'MorphBall': 7656805,
'HiJumpBoots': 7656913,
'SpeedBooster': 7657021,
'SpaceJump': 7657129,
'ScrewAttack': 7657237,
'VariaSuit': 7657345,
'GravitySuit': 7657453,
'GreenDoors': 7657561,
'BlueDoors': 7657669,
'YellowDoors': 7657777,
'RedDoors': 7657885 }
print('Patching game, please wait')
HashValue = random.sample(HashList, 4)
FileName = 'MFOR -'
if Debug:
FileName = 'Debug -'
for x in HashValue:
FileName = FileName + ' {}'.format(x)
if Debug:
# FIXME: whenever Kazuto decides to drop the original ASM reintroduce debug mode
# armips is FOSS and further documentation should be provided on how to build it
os.system('.\\armips\\armips.exe "Metroid Fusion Open Randomizer.asm" -root ".\\data\\asm" -sym ".\\temp.sym"')
os.replace('.\\data\\MFOR.gba', '.\\seeds\\{}.gba'.format(FileName))
else:
source = open(BaseName, 'rb')
target = open(os.path.join('.', 'seeds', '{}.gba'.format(FileName)), 'wb')
patch = open(os.path.join('.', 'data', 'MFOR.bps'), 'rb')
try:
apply_to_files(patch, source, target)
except:
target.close()
os.unlink(os.path.join('.', 'seeds', '{}.gba'.format(FileName)))
print('Error: failed to patch game with base patch!')
sys.exit(1)
checksum = fileHash(os.path.join('.', 'seeds', '{}.gba'.format(FileName)))
if checksum != 2455114263:
os.unlink(os.path.join('.', 'seeds', '{}.gba'.format(FileName)))
print('Error: Base patch file has been modified. Please go to https://metroidconstruction.com/ and re-download MFOR.')
sys.exit(1)
with open(os.path.join('.', 'seeds', '{}.gba'.format(FileName)), 'rb+') as patchedGame:
if Debug:
sym = dict()
sym.clear()
with open(os.path.join('.', 'data', 'asm', 'temp.sym'), 'r') as symFile:
for line in symFile:
x = line.split()
if len(x) > 1 and re.search('^[a-zA-Z]', x[1]):
sym.update({
x[1]: x[0][2:] })
os.remove(os.path.join('.', 'data', 'asm', 'temp.sym'))
roomEventOffset = int(sym.get('t_bossanddownloadevents'), 16)
itemEventOffset = int(sym.get('t_obtainitemevents'), 16)
securityOffset = int(sym.get('b_unlocklowerlevels'), 16)
print('roomEventOffset: 0x{:06X}'.format(roomEventOffset))
print('itemEventOffset: 0x{:06X}'.format(itemEventOffset))
print('securityOffset: 0x{:06X}'.format(securityOffset))
roomEventOffset = 8326320
itemEventOffset = 5726112
securityOffset = 479192
for area in RoomNodes:
areaIndex = list(RoomNodes.keys()).index(area)
for node in RoomNodes[area]:
name = node.get('Name')
nodeType = node.get('Type')
if nodeType != None:
itemName = ''
if 'Tank' in nodeType:
itemName = PlacedItems[UsedLocations.index(name)]
bg1 = int(node.get('BG1'), 16)
clipdata = int(node.get('Clipdata'), 16)
tileset = int(node.get('Tileset'), 16)
if SeedSettings['HideItems']:
if tileset == 33:
blockValue = 7
elif tileset == 34:
blockValue = 7
elif tileset == 40:
blockValue = 7
elif tileset == 42:
blockValue = 7
else:
blockValue = 3
else:
blockValue = ItemList.index(itemName)
if blockValue < 2:
blockValue = blockValue ^ 1
elif blockValue > 2:
if tileset == 33:
blockValue = 7
elif tileset == 34:
blockValue = 7
elif tileset == 40:
blockValue = 7
elif tileset == 42:
blockValue = 7
else:
blockValue = 3
blockValue += 70
if tileset == 9:
blockValue += 1
elif tileset == 11:
blockValue += 1
elif tileset == 25:
blockValue += 1
elif tileset >= 30 and tileset <= 34:
blockValue += 1
elif tileset == 40:
blockValue += 1
elif tileset == 42:
blockValue += 1
elif tileset == 48:
blockValue += 1
elif tileset == 49:
blockValue += 1
elif tileset == 52:
blockValue += 1
elif tileset == 56:
blockValue += 1
elif tileset == 61:
blockValue += 1
elif tileset == 62:
blockValue += 1
elif tileset == 64:
blockValue += 1
elif tileset == 67:
blockValue += 1
elif tileset == 72:
blockValue += 1
clipValue = ItemList.index(itemName)
if clipValue < 2:
clipValue = clipValue ^ 99
if 'Hidden' in nodeType:
clipValue += 2
elif 'Underwater' in nodeType:
clipValue += 4
elif clipValue == 2:
clipValue = 104
if 'Hidden' in nodeType:
clipValue += 1
elif 'Underwater' in nodeType:
clipValue += 2
elif clipValue >= 3:
clipValue = (clipValue - 3) * 3 + 120
if 'Hidden' in nodeType:
clipValue += 1
elif 'Underwater' in nodeType:
clipValue += 2
if 'Hidden' not in nodeType:
patchedGame.seek(bg1)
patchedGame.write(blockValue.to_bytes(1, 'little'))
patchedGame.seek(clipdata)
patchedGame.write(clipValue.to_bytes(1, 'little'))
elif 'Boss' in nodeType or 'Data' in nodeType:
itemName = PlacedItems[UsedLocations.index(name)]
itemValue = ItemList.index(itemName)
slot = BossDataList.index(name)
roomEvent = roomEventOffset
if roomEvent != None:
roomEvent = roomEvent + 3 + slot * 4
if itemValue < 3:
itemValue += 1
else:
itemValue -= 3
itemEvent = itemEventOffset
if itemEvent != None:
itemEvent = itemEvent + 1 + itemValue
patchedGame.seek(itemEvent)
itemValue = int.from_bytes(patchedGame.read(1), 'little')
patchedGame.seek(roomEvent)
patchedGame.write(itemValue.to_bytes(1, 'little'))
if name == 'Data S5':
roomEvent = roomEventOffset
roomEvent = roomEvent + 3 + (slot + 1) * 4
patchedGame.seek(roomEvent)
patchedGame.write(itemValue.to_bytes(1, 'little'))
if itemName in MajorItems:
offset = CreditsOffsets.get(itemName)
if 'Boss' in nodeType:
location = name
elif 'S0' in name:
location = 'Main Deck : '
else:
location = 'Sector {} : '.format(name[6:7])
if 'Tank' in nodeType:
location = location + name[8:]
else:
location = location + nodeType + ' Room'
spaces = ceiling(30 - len(location), 2)
location = ' ' * spaces + location
patchedGame.seek(offset)
patchedGame.write(location.encode('ascii'))
for x in range(len(location), 35):
patchedGame.write((0).to_bytes(1, 'little'))
if SeedSettings['HideItems']:
patchedGame.seek(3926048)
patchedGame.write((76).to_bytes(2, 'little'))
patchedGame.write((77).to_bytes(2, 'little'))
patchedGame.write((78).to_bytes(2, 'little'))
patchedGame.write((79).to_bytes(2, 'little'))
patchedGame.write((76).to_bytes(2, 'little'))
patchedGame.write((77).to_bytes(2, 'little'))
patchedGame.write((78).to_bytes(2, 'little'))
patchedGame.write((79).to_bytes(2, 'little'))
patchedGame.write((76).to_bytes(2, 'little'))
patchedGame.write((77).to_bytes(2, 'little'))
patchedGame.write((78).to_bytes(2, 'little'))
patchedGame.write((79).to_bytes(2, 'little'))
if SeedSettings['SplitSecurity'] == True:
security = securityOffset
patchedGame.seek(security)
patchedGame.write((0).to_bytes(2, 'little'))
if SeedSettings['MissilesWithoutMainData']:
patchedGame.seek(24828)
patchedGame.write((15).to_bytes(1, 'little'))
patchedGame.seek(395742)
patchedGame.write((15).to_bytes(1, 'little'))
patchedGame.seek(465582)
patchedGame.write((15).to_bytes(1, 'little'))
if SeedSettings['PowerBombsWithoutBombs']:
patchedGame.seek(24756)
patchedGame.write((32).to_bytes(1, 'little'))
patchedGame.seek(465672)
patchedGame.write((32).to_bytes(1, 'little'))
if SeedSettings['SectorShuffle'] == True:
for currentArea in range(7):
patchedGame.seek(7977108 + currentArea * 4, 0)
data = patchedGame.read(4)
unpacked = struct.unpack('<L', data)
doorData = unpacked[0] - 134217728
patchedGame.seek(doorData, 0)
doorNumber = 0
connectionType = int.from_bytes(patchedGame.read(1), 'little')
patchedGame.seek(5, 1)
offset = patchedGame.tell()
connectedDoor = int.from_bytes(patchedGame.read(1), 'little')
patchedGame.seek(5, 1)
resume = patchedGame.tell()
if connectionType == 0 and connectedDoor == 0:
continue
sourceDoor = 'S{}-{:02X}'.format(currentArea, doorNumber)
targetDoorStr = World.doorConnections.get(sourceDoor)
connectedArea = World.areaConnections.get(sourceDoor, currentArea)
connectedDoorStr = 'S{}-{:02X}'.format(connectedArea, connectedDoor)
if connectedDoorStr != targetDoorStr:
targetDoor = int(targetDoorStr[-2:], 16)
patchedGame.seek(offset)
patchedGame.write(targetDoor.to_bytes(1, 'little'))
patchedGame.seek(resume)
doorNumber += 1
for door, targetArea in World.areaConnections.items():
offset = World.areaConnectionOffsets.get(door)
patchedGame.seek(offset)
areaByte = int.from_bytes(patchedGame.read(1), 'little')
if areaByte != targetArea:
patchedGame.seek(offset)
patchedGame.write(targetArea.to_bytes(1, 'little'))
continue
for target in World.patcher:
value = World.patcher.get(target)
patchedGame.seek(target)
patchedGame.write(value.to_bytes(1, 'little'))
if Patch:
with open(BaseGame, 'rb') as source:
sourcedata = source.read()
with open(os.path.join('.', 'seeds', '{}.gba'.format(FileName)), 'rb') as target:
targetdata = target.read()
patch = open(os.path.join('.', 'seeds', '{}.bps'.format(FileName)), 'wb')
blocksize = (len(sourcedata) + len(targetdata)) // 1000000 + 1
print("Using blocks of {0} bytes".format(blocksize))
iterable = diff_bytearrays(blocksize, sourcedata, targetdata)
write_bps(bps_progress(iterable), patch)
print('')
ItemNames = [
'Missile Data',
'Morph Ball',
'Charge Beam',
'Bombs',
'Hi-Jump Boots',
'Speed Booster',
'Super Missile Data',
'Varia Suit',
'Ice Missile Data',
'Wide Beam',
'Power Bomb Data',
'Space Jump',
'Plasma Beam',
'Gravity Suit',
'Diffusion Data',
'Wave Beam',
'Screw Attack',
'Ice Beam']
if SeedSettings['RaceSeed'] == False:
spoilerLog = dict()
spoilerLog.update({
'MFOR Version': version })
spoilerLog.update({
'Seed': SeedValue })
settingsDict = dict()
settingsDict.update({
'Difficulty': SeedSettings['Difficulty'] })
if SeedSettings['MajorMinor'] == False:
settingsDict.update({
'Item pool': 'Major items anywhere' })
else:
settingsDict.update({
'Item pool': 'Limited major item locations' })
settingsDict.update({
'Missile upgrades enable Missiles': SeedSettings['MissilesWithoutMainData'] })
settingsDict.update({
'Power Bombs without normal Bombs': SeedSettings['PowerBombsWithoutBombs'] })
settingsDict.update({
'Allow logical damage runs': SeedSettings['DamageRuns'] })
settingsDict.update({
'Separated security levels': SeedSettings['SplitSecurity'] })
settingsDict.update({
'Sector shuffle': SeedSettings['SectorShuffle'] })
if SeedSettings['SectorShuffle'] == True:
sectorLayout = str()
for x in areaLayout:
sectorLayout = sectorLayout.strip() + ' {}'.format(x)
settingsDict.update({
'Sector layout:': sectorLayout })
settingsDict.update({
'Hide item graphics': SeedSettings['HideItems'] })
settingsDict.update({
'E-Tanks': PlacedETanks })
settingsDict.update({
'Missile Tanks': PlacedMissiles })
settingsDict.update({
'Power Bomb Tanks': PlacedPowerBombs })
spoilerLog.update({
'Settings': settingsDict })
itemProgression = dict()
for x in range(len(PlacedItems)):
if PlacedItems[x] in MajorItems:
namedItem = ItemNames[MajorItems.index(PlacedItems[x])]
PlacedItems[x] = namedItem
itemProgression.update({
UsedLocations[x]: PlacedItems[x] })
continue
spoilerLog.update({
'Item order': itemProgression })
itemDict = dict()
World.itemLocations.sort()
for x in range(0, len(World.itemLocations)):
itemDict.update({
World.itemLocations[x]: 0 })
for x in range(0, len(PlacedItems)):
itemDict.update({
UsedLocations[x]: PlacedItems[x] })
spoilerLog.update({
'Items': itemDict })
with open(os.path.join('.', 'spoilers', '{}.json'.format(FileName)), 'w') as spoiler:
json.dump(spoilerLog, spoiler, indent=4)
def initialize():
global AccessibleLocations
global AreaOpen
global BackwardsLabs
global BossDataList
global BossLocations
global Energy
global HashList
global InfiniteBombJump
global ItemList
global MajorItems
global MaxETanks
global MaxMissiles
global MaxPowerBombs
global MinorItems
global MissileCount
global MissileDamage
global PlacedETanks
global PlacedItems
global PlacedMissiles
global PlacedPowerBombs
global UsedLocations
global WallJumpSetting
HashList = list()
with open(os.path.join('.', 'data', 'SeedHash.json')) as jsonFile:
HashList = json.load(jsonFile)
HashList.sort()
AreaOpen = list()
for area in range(0, 7):
AreaOpen.append(None)
Energy = 0
WallJumpSetting = False
InfiniteBombJump = False
BackwardsLabs = False
MaxETanks = 20
MaxMissiles = 48
MaxPowerBombs = 32
PlacedETanks = PlacedMissiles = PlacedPowerBombs = 0
MissileDamage = 0
MissileCount = 10
MajorItems = [
'MainMissiles',
'MorphBall',
'ChargeBeam',
'Bombs',
'HiJumpBoots',
'SpeedBooster',
'SuperMissileItem',
'VariaSuit',
'IceMissileItem',
'WideBeam',
'MainPowerBombs',
'SpaceJump',
'PlasmaBeam',
'GravitySuit',
'DiffusionItem',
'WaveBeam',
'ScrewAttack',
'IceBeam']
MinorItems = [
'Energy Tank', 'Missile Tank', 'Power Bomb Tank']
BossDataList = ['Data S0',
'Arachnus',
'Charge Core-X',
'Data S2',
'Zazabi',
'Serris',
'Data S3',
'Mega Core-X',
'Data S5',
'Data S5',
'Wide Core-X',
'Data S6',
'Yakuza',
'Nettori',
'Nightmare',
'Data S4',
'Box-2',
'Ridley',
'Omega Metroid']
ItemList = MinorItems + MajorItems
PlacedItems = list()
BossLocations = list()
AccessibleLocations = list()
UsedLocations = list()
def start_randomizer(rom, settings):
global AreaItemLocations
global BaseGame
global DamageRuns
global Debug
global Difficulty
global Patch
global RoomNodes
global SeedSettings
global SeedValue
global StartLocation
global World
BaseGame = rom
if BaseGame == None or BaseGame == '':
print('Error: no base game provided.')
sys.exit(1)
checksum = fileHash(BaseGame)
if checksum != 1819625372:
print('Only Metroid Fusion (U) is supported. Check the CRC32 value: it should be 6C75479C')
sys.exit(1)
Debug = settings['Debug']
settings.pop('Debug')
if Debug == False:
checksum = fileHash(os.path.join('.', 'data', 'MFOR.bps'))
if checksum != 558161692:
print('Error: Base patch file has been modified. Please go to https://metroidconstruction.com/ and re-download MFOR.')
sys.exit(1)
totalRandoTime = time.time()
if settings['Seed']:
SeedValue = str(settings['Seed']).strip(' \n')
else:
SeedValue = str(random.randrange(sys.maxsize))
settings.pop('Seed')
repeat = 1
if settings['Num']:
if settings['Num'] > repeat:
repeat = settings['Num']
settings.pop('Num')
if settings['Patch']:
Patch = True
else:
Patch = False
settings.pop('Patch')
for loop in range(repeat):
initialize()
SeedSettings = settings.copy()
if Debug:
print('Debug generation enabled')
if loop > 0:
SeedValue = str(random.randrange(sys.maxsize))
Difficulty = SeedSettings['Difficulty']
DamageRuns = SeedSettings['DamageRuns']
random.seed(SeedValue + str(SeedSettings))
World = Graph.Game(BaseGame)
World.RemoveNodeFromRoom('Room-S2-07', 'S2-10')
World.RemoveNodeFromRoom('Room-S2-0D', 'S2-1E')
World.RemoveNodeFromRoom('Room-S3-07', 'S3-10')
World.RemoveNodeFromRoom('Room-S3-12', 'S3-2B')
World.RemoveNodeFromRoom('Room-S5-15', 'S5-2A')
World.AddNodeToRoom('Room-S2-1F', 'S2-10')
World.AddNodeToRoom('Room-S2-2E', 'S2-1E')
World.AddNodeToRoom('Room-S3-16', 'S3-10')
World.AddNodeToRoom('Room-S3-17', 'S3-2B')
World.AddNodeToRoom('Room-S5-16', 'S5-2A')
World.UpdateDoorConnection('S0-4A', 'S0-61')
World.UpdateDoorConnection('S0-96', 'S0-22')
World.UpdateDoorConnection('S0-98', 'S0-20')
World.UpdateDoorConnection('S2-13', 'S2-45')
World.UpdateDoorConnection('S2-19', 'S2-2F')
World.UpdateDoorConnection('S2-1B', 'S2-68')
World.UpdateDoorConnection('S2-23', 'S2-69')
World.UpdateDoorConnection('S2-5F', 'S2-6A')
World.UpdateDoorConnection('S2-6E', 'S2-70')
World.UpdateDoorConnection('S3-2D', 'S3-2E')
World.UpdateDoorConnection('S5-28', 'S5-6C')
AreaItemLocations = list()
for area in range(7):
AreaItemLocations.append(list())
with open(os.path.join('.', 'data', 'NodeData.json')) as jsonFile:
RoomNodes = json.load(jsonFile)
for area in RoomNodes:
areaIndex = list(RoomNodes.keys()).index(area)
for node in RoomNodes[area]:
name = node.get('Name')
room = node.get('Room')
item = node.get('Item')
nodeType = node.get('Type')
World.AddNodeToRoom('Room-S{}-{:02X}'.format(areaIndex, int(room, 16)), name)
if item == 'Missile' or item == 'Power Bomb':
World.add_to_minors(name)
elif nodeType == 'Boss':
World.add_to_majors(name)
BossLocations.append(name)
else:
if nodeType == 'Data' or item == 'E-Tank':
World.add_to_majors(name)
if name == 'Data S3':
BossLocations.append(name)
if not 'Item' in name:
if not nodeType == 'Boss':
if nodeType == 'Data':
pass
AreaItemLocations[areaIndex].append(name)
World.ConnectAllNodes()
StartLocation = 'S0-00'
startTime = time.time()
randomize_game(World)
seedTime = time.time() - startTime
print(str(FileName))
print('Randomized in:', seedTime)
totalRandoTime = time.time() - totalRandoTime
print('All seeds took:', totalRandoTime)
return FileName