OpenMFOR/Randomizer.py

5187 lines
196 KiB
Python

# 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 Missiles, Missiles, SuperMissiles, IceMissiles, Diffusion, Ice, HiJump, SpringBall, WallJump, PowerBombs, PowerBombs, UseBombs, BombJump, IBJ, MissileDamage, MissileDamage, MissileDamage, MissileDamage, MissileDamage
if SeedSettings['MissilesWithoutMainData'] == True:
if not MainMissiles and SuperMissileItem and IceMissileItem:
pass
Missiles = DiffusionItem
else:
Missiles = MainMissiles
if Missiles:
pass
SuperMissiles = SuperMissileItem
if Missiles:
pass
IceMissiles = IceMissileItem
if Missiles:
pass
Diffusion = DiffusionItem
if not IceMissiles:
pass
Ice = IceBeam
if not HiJumpBoots:
pass
HiJump = SpaceJump
SpringBall = HiJumpBoots
if not SpaceJump:
pass
WallJump = WallJumpSetting
if SeedSettings['PowerBombsWithoutBombs'] == True:
if MorphBall:
pass
PowerBombs = MainPowerBombs
elif MorphBall and Bombs:
pass
PowerBombs = MainPowerBombs
if not MorphBall and Bombs:
pass
UseBombs = PowerBombs
if not MorphBall and Bombs:
pass
BombJump = SpringBall
if MorphBall and Bombs:
pass
IBJ = 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 and 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', 250, **('depth',))
if path != None:
enable_item(graph, 'BlueDoors')
path = graph.get_path('Security-Level-1', StartLocation, 250, **('depth',))
if path == None:
disable_item(graph, 'BlueDoors')
if GreenDoors == False:
path = graph.get_path(StartLocation, 'Security-Level-2', 250, **('depth',))
if path != None:
enable_item(graph, 'GreenDoors')
path = graph.get_path('Security-Level-2', StartLocation, 250, **('depth',))
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', 250, **('depth',))
if path != None:
enable_item(graph, 'YellowDoors')
path = graph.get_path('Security-Level-3', StartLocation, 250, **('depth',))
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', 250, **('depth',))
if path != None:
enable_item(graph, 'RedDoors')
path = graph.get_path('Security-Level-4', StartLocation, 250, **('depth',))
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 PlacedETanks, PlacedMissiles, PlacedPowerBombs, areaLayout, areaLayout, areaLayout, PlacedETanks, PlacedMissiles, PlacedPowerBombs, MissileCount, NettoriOpen, PlacedMissiles, MissileCount, PlacedETanks, PlacedETanks, MaxETanks, PlacedETanks, PlacedMissiles, PlacedPowerBombs
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...')
if gameBeatable == False:
if init == False:
if 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 or areaLayout[2] != 1) and areaLayout[2] != 2 and areaLayout[3] != 1 and areaLayout[3] != 2:
attemptedLayouts.append(areaLayout)
if areaLayout in attemptedLayouts:
areaLayout = random.sample(range(1, 7), 6)
# continue
# continue
elif areaLayout in attemptedLayouts:
areaLayout = random.sample(range(1, 7), 6)
# continue
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:
pass
if path == None:
print('No accessible locations found with this start, try changing your game settings.')
sys.exit(1)
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)
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')
continue
weightInit = True
if len(availableItems) < 1:
print('No accessible locations found with this start, try changing your game settings.')
sys.exit(1)
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] and location not in locationsPerArea[area]:
locationsPerArea[area].append(location)
continue
continue
for area in range(0, 7):
if len(locationsPerArea[area]) > 0:
areaWeights[area] = weightValue[area] / len(locationsPerArea[area])
continue
for location in AccessibleLocations:
for area in range(0, 7):
if location in AreaItemLocations[area]:
locationWeights.append(areaWeights[area])
continue
continue
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
if 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
continue
continue
if FirstItem == 'MainMissiles' or 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' and 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 gameBeatable == False:
newLocations.clear()
locationWeights.clear()
for location in MajorLocations:
path = None
if location not in UsedLocations and location not in AccessibleLocations or location == 'Data S0' or location == 'Item S0-05-16':
path = graph.get_path(location, StartLocation, 250, **('depth',))
else:
for area in range(0, 7):
if location in AreaItemLocations[area] and AreaOpen[area]:
path = graph.get_path(AreaOpen[area], location, True)
if path != None:
AccessibleLocations.append(location)
MajorLocations.remove(location)
newLocations.append(location)
for area in range(0, 7):
if location in AreaItemLocations[area] and location not in locationsPerArea[area]:
locationsPerArea[area].append(location)
continue
continue
for area in range(0, 7):
if len(locationsPerArea[area]) > 0 or 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] or location in newLocations:
locationWeights.append(areaWeights[area] * 1.8)
elif location in BossLocations and SeedSettings['MajorMinor'] == False:
locationWeights.append(areaWeights[area] * 1.5)
else:
locationWeights.append(areaWeights[area])
if len(MajorList) > 0:
itemLocation = None
path = None
item = random.choices(MajorList, MajorWeights, 1, **('weights', 'k'))[0]
currentItemWeight = MajorWeights.pop(MajorList.index(item))
MajorList.remove(item)
enable_item(graph, item)
if SeedSettings['DamageRuns']:
Energy = Energy / 2
if path == None and len(AccessibleLocations) > 0:
itemLocation = random.choices(AccessibleLocations, locationWeights, 1, **('weights', 'k'))[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, 250, **('depth',))
else:
for area in range(0, 7):
if itemLocation in AreaItemLocations[area] and AreaOpen[area]:
path = graph.get_path(itemLocation, AreaOpen[area], True)
if itemLocation in BossLocations and path != None:
disable_item(graph, item)
if ChargeBeam == False and 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, 250, **('depth',))
if missilePath != None:
missilePath = graph.get_path(missileLocation, StartLocation, 250, **('depth',))
else:
for area in range(0, 7):
if missileLocation in AreaItemLocations[area] and AreaOpen[area]:
missilePath = graph.get_path(AreaOpen[area], missileLocation, True)
if missilePath != None:
missilePath = graph.get_path(missileLocation, AreaOpen[area], True)
if missilePath != None:
PossibleMissileTanks.append(missileLocation)
continue
else:
for missileLocation in AccessibleLocations:
missilePath = None
if missileLocation == 'Data S0' or missileLocation == 'Item S0-05-16':
missilePath = graph.get_path(missileLocation, StartLocation, 250, **('depth',))
else:
for area in range(0, 7):
if missileLocation in AreaItemLocations[area] and AreaOpen[area]:
missilePath = graph.get_path(missileLocation, AreaOpen[area], True)
if missilePath != None and missileLocation not in BossLocations:
PossibleMissileTanks.append(missileLocation)
continue
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)
continue
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
continue
if item == 'MainMissiles' or 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' and SeedSettings['PowerBombsWithoutBombs'] == False:
MajorList.append('MainPowerBombs')
MajorWeights.append(WeightedMajors.get('MainPowerBombs'))
if SeedSettings['MajorMinor'] == False and len(AccessibleLocations) > 3 and PlacedETanks < MaxETanks:
itemLocation = random.choice(AccessibleLocations)
locationWeights.pop(AccessibleLocations.index(itemLocation))
AccessibleLocations.remove(itemLocation)
UsedLocations.append(itemLocation)
PlacedItems.append('Energy Tank')
PlacedETanks += 1
else:
for item in MajorItems:
disable_item(graph, item)
print("Couldn't find a path forward, trying again")
init = False
# continue
print('Game is beatable, placing remaining items (no logic)')
for item in MajorItems:
if item not in PlacedItems and item not in MajorList:
MajorList.append(item)
MajorWeights.append(WeightedMajors.get(item))
continue
MajorLocations.extend(AccessibleLocations)
for item in MajorList:
if item not in PlacedItems:
location = random.choice(MajorLocations)
if location in UsedLocations:
MajorLocations.remove(location)
location = random.choice(MajorLocations)
continue
UsedLocations.append(location)
PlacedItems.append(item)
if SeedSettings['MajorMinor']:
for location in MajorLocations:
if PlacedETanks < MaxETanks and location not in UsedLocations:
UsedLocations.append(location)
PlacedItems.append(MinorItems[0])
PlacedETanks += 1
continue
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 and 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')
elif item == 'Missile Tank':
PlacedMissiles += 1
if PlacedMissiles >= MaxMissiles:
MinorItems.remove('Missile Tank')
elif item == 'Power Bomb Tank':
PlacedPowerBombs += 1
if PlacedPowerBombs >= MaxPowerBombs:
MinorItems.remove('Power Bomb Tank')
continue
patch_game()
continue
return None
def patch_game():
global FileName, FileName, FileName
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)
return None
def initialize():
global HashList, HashList, AreaOpen, Energy, WallJumpSetting, InfiniteBombJump, BackwardsLabs, MaxETanks, MaxMissiles, MaxPowerBombs, PlacedETanks, PlacedMissiles, PlacedPowerBombs, MissileDamage, MissileCount, MajorItems, MinorItems, BossDataList, ItemList, PlacedItems, BossLocations, AccessibleLocations, UsedLocations
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()
return None
def start_randomizer(rom, settings):
global BaseGame, Debug, SeedValue, SeedValue, Patch, Patch, SeedSettings, SeedValue, Difficulty, DamageRuns, World, AreaItemLocations, RoomNodes, StartLocation
BaseGame = rom
if BaseGame == None or BaseGame == '':
sys.exit('Error: no base game provided.')
checksum = fileHash(BaseGame)
if checksum != 1819625372:
sys.exit('Only Metroid Fusion (U) is supported. Check the CRC32 value: it should be 6C75479C')
Debug = settings['Debug']
settings.pop('Debug')
if Debug == False:
checksum = fileHash(os.path.join('.', 'data', 'MFOR.bps'))
if checksum != 558161692:
sys.exit('Error: Base patch file has been modified. Please go to https://metroidconstruction.com/ and re-download MFOR.')
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'] and 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))
print('DEBUG: Calling Graph creation')
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)
elif nodeType == 'Data' or item == 'E-Tank':
World.add_to_majors(name)
if name == 'Data S3':
BossLocations.append(name)
if not 'Item' in name and nodeType == 'Boss':
if nodeType == 'Data':
AreaItemLocations[areaIndex].append(name)
continue
continue
World.ConnectAllNodes()
StartLocation = 'S0-00'
startTime = time.time()
randomize_game(World)
seedTime = time.time() - startTime
print(str(FileName))
print('Randomized in:', seedTime)
continue
totalRandoTime = time.time() - totalRandoTime
print('All seeds took:', totalRandoTime)
return FileName