def canPassRedTowerToMaridiaNode(self): sm = self.smbm return sm.wand(sm.haveItem('Morph'), RomPatches.has(RomPatches.AreaRandoGatesBase))
def canPassMoatReverse(self): sm = self.smbm return sm.wor(RomPatches.has(RomPatches.MoatShotBlock), sm.haveItem('Grapple'), sm.haveItem('SpaceJump'), sm.haveItem('Gravity'), sm.canPassBombPassages())
def canPassMaridiaToRedTowerNode(self): sm = self.smbm return sm.wand( sm.haveItem('Morph'), sm.wor(RomPatches.has(RomPatches.AreaRandoGatesBase), sm.haveItem('Super')))
def canAccessBillyMays(self): sm = self.smbm return sm.wand(sm.wor(RomPatches.has(RomPatches.BlueBrinstarBlueDoor), sm.traverse('ConstructionZoneRight')), sm.canUsePowerBombs(), sm.canGravLessLevel1())
'Landing Site': lambda sm: SMBool(True) } locationsDict["Bomb"].Available = ( lambda sm: sm.wand(sm.haveItem('Morph'), sm.traverse('FlywayRight')) ) locationsDict["Energy Tank, Terminator"].AccessFrom = { 'Landing Site': lambda sm: sm.canPassTerminatorBombWall(), 'Lower Mushrooms Left': lambda sm: sm.canPassCrateriaGreenPirates(), # 'Gauntlet Top': lambda sm: sm.haveItem('Morph') } locationsDict["Energy Tank, Terminator"].Available = ( lambda sm: SMBool(True) ) locationsDict["Reserve Tank, Brinstar"].AccessFrom = { 'Green Brinstar Elevator': lambda sm: sm.wor(RomPatches.has(RomPatches.BrinReserveBlueDoors), sm.traverse('MainShaftRight')) } locationsDict["Reserve Tank, Brinstar"].Available = ( lambda sm: sm.wor(RomPatches.has(RomPatches.BrinReserveBlueDoors), sm.traverse('EarlySupersRight')) ) locationsDict["Charge Beam"].AccessFrom = { 'Big Pink': lambda sm: sm.haveItem('Morph') } locationsDict["Charge Beam"].Available = ( lambda sm: sm.canPassBombPassages() ) locationsDict["Morphing Ball"].AccessFrom = { 'Blue Brinstar Elevator Bottom': lambda sm: SMBool(True) } locationsDict["Morphing Ball"].Available = ( lambda sm: SMBool(True)
def loadRom(self, rom, interactive=False, magic=None, startLocation=None): self.scavengerOrder = [] self.plandoScavengerOrder = [] # startLocation param is only use for seedless if rom == None: # TODO::add a --logic parameter for seedless Logic.factory('vanilla') self.romFileName = 'seedless' self.majorsSplit = 'Full' self.masterMajorsSplit = 'Full' self.areaRando = True self.bossRando = True self.escapeRando = False self.escapeTimer = "03:00" self.startLocation = startLocation RomPatches.setDefaultPatches(startLocation) self.startArea = getAccessPoint(startLocation).Start['solveArea'] # in seedless load all the vanilla transitions self.areaTransitions = vanillaTransitions[:] self.bossTransitions = vanillaBossesTransitions[:] self.escapeTransition = [vanillaEscapeTransitions[0]] # in seedless we allow mixing of area and boss transitions self.hasMixedTransitions = True self.curGraphTransitions = self.bossTransitions + self.areaTransitions + self.escapeTransition self.locations = Logic.locations for loc in self.locations: loc.itemName = 'Nothing' # set doors related to default patches DoorsManager.setDoorsColor() self.doorsRando = False self.hasNothing = False self.objectives.setVanilla() self.tourian = 'Vanilla' else: self.romFileName = rom self.romLoader = RomLoader.factory(rom, magic) Logic.factory(self.romLoader.readLogic()) self.locations = Logic.locations (self.majorsSplit, self.masterMajorsSplit) = self.romLoader.assignItems( self.locations) (self.startLocation, self.startArea, startPatches) = self.romLoader.getStartAP() if not GraphUtils.isStandardStart( self.startLocation) and self.majorsSplit != 'Full': # update major/chozo locs in non standard start self.romLoader.updateSplitLocs(self.majorsSplit, self.locations) (self.areaRando, self.bossRando, self.escapeRando, hasObjectives, self.tourian) = self.romLoader.loadPatches() RomPatches.ActivePatches += startPatches self.escapeTimer = self.romLoader.getEscapeTimer() self.doorsRando = self.romLoader.loadDoorsColor() self.hasNothing = self.checkLocsForNothing() if self.majorsSplit == 'Scavenger': self.scavengerOrder = self.romLoader.loadScavengerOrder( self.locations) if hasObjectives: self.romLoader.loadObjectives(self.objectives) else: if self.majorsSplit == "Scavenger": self.objectives.setScavengerHunt() self.objectives.tourianRequired = not self.romLoader.hasPatch( 'Escape_Trigger') else: self.objectives.setVanilla() self.majorUpgrades = self.romLoader.loadMajorUpgrades() self.splitLocsByArea = self.romLoader.getSplitLocsByArea( self.locations) self.objectives.setSolverMode(self) if interactive == False: print( "ROM {} majors: {} area: {} boss: {} escape: {} patches: {} activePatches: {}" .format(rom, self.majorsSplit, self.areaRando, self.bossRando, self.escapeRando, sorted(self.romLoader.getPatches()), sorted(RomPatches.ActivePatches))) else: print( "majors: {} area: {} boss: {} escape: {} activepatches: {}" .format(self.majorsSplit, self.areaRando, self.bossRando, self.escapeRando, sorted(RomPatches.ActivePatches))) (self.areaTransitions, self.bossTransitions, self.escapeTransition, self.hasMixedTransitions) = self.romLoader.getTransitions( self.tourian) if interactive == True and self.debug == False: # in interactive area mode we build the graph as we play along if self.areaRando == True and self.bossRando == True: self.curGraphTransitions = [] elif self.areaRando == True: self.curGraphTransitions = self.bossTransitions[:] elif self.bossRando == True: self.curGraphTransitions = self.areaTransitions[:] else: self.curGraphTransitions = self.bossTransitions + self.areaTransitions if self.escapeRando == False: self.curGraphTransitions += self.escapeTransition else: self.curGraphTransitions = self.bossTransitions + self.areaTransitions + self.escapeTransition self.smbm = SMBoolManager() self.buildGraph() # store at each step how many locations are available self.nbAvailLocs = [] if self.log.getEffectiveLevel() == logging.DEBUG: self.log.debug("Display items at locations:") for loc in self.locations: self.log.debug('{:>50}: {:>16}'.format(loc.Name, loc.itemName))
), # thanks ponk! https://youtu.be/jil5zTBCF1s sm.canDoLowGauntlet())) locationsDict["Bomb"].AccessFrom = {'Landing Site': lambda sm: SMBool(True)} locationsDict["Bomb"].Available = ( lambda sm: sm.wand(sm.haveItem('Morph'), sm.traverse('FlywayRight'))) locationsDict["Bomb"].PostAvailable = ( lambda sm: sm.wor(sm.knowsAlcatrazEscape(), sm.canPassBombPassages())) locationsDict["Energy Tank, Terminator"].AccessFrom = { 'Landing Site': lambda sm: sm.canPassTerminatorBombWall(), 'Lower Mushrooms Left': lambda sm: sm.canPassCrateriaGreenPirates(), 'Gauntlet Top': lambda sm: sm.haveItem('Morph') } locationsDict["Energy Tank, Terminator"].Available = (lambda sm: SMBool(True)) locationsDict["Reserve Tank, Brinstar"].AccessFrom = { 'Green Brinstar Elevator': lambda sm: sm.wor(RomPatches.has(RomPatches.BrinReserveBlueDoors), sm.traverse('MainShaftRight')) } locationsDict["Reserve Tank, Brinstar"].Available = (lambda sm: sm.wand( sm.wor(sm.canMockball(), sm.haveItem('SpeedBooster')), sm.wor(RomPatches.has(RomPatches.BrinReserveBlueDoors), sm.traverse('EarlySupersRight')))) locationsDict["Charge Beam"].AccessFrom = {'Big Pink': lambda sm: SMBool(True)} locationsDict["Charge Beam"].Available = (lambda sm: sm.canPassBombPassages()) locationsDict["Morphing Ball"].AccessFrom = { 'Blue Brinstar Elevator Bottom': lambda sm: SMBool(True) } locationsDict["Morphing Ball"].Available = (lambda sm: SMBool(True)) locationsDict["Energy Tank, Brinstar Ceiling"].AccessFrom = { 'Blue Brinstar Elevator Bottom': lambda sm: sm.wor(RomPatches.has(RomPatches.BlueBrinstarBlueDoor),
def canOpenEyeDoors(self): sm = self.smbm return sm.wor(RomPatches.has(RomPatches.NoGadoras), sm.haveMissileOrSuper())
def setDoorsColor(): # depending on loaded patches, force some doors to blue, excluding them from randomization if RomPatches.has(RomPatches.BlueBrinstarBlueDoor): DoorsManager.doors['ConstructionZoneRight'].forceBlue() if RomPatches.has(RomPatches.BrinReserveBlueDoors): DoorsManager.doors['MainShaftRight'].forceBlue() DoorsManager.doors['EarlySupersRight'].forceBlue() if RomPatches.has(RomPatches.EtecoonSupersBlueDoor): DoorsManager.doors['EtecoonEnergyTankLeft'].forceBlue() #if RomPatches.has(RomPatches.SpongeBathBlueDoor): # DoorsManager.doors[''].forceBlue() if RomPatches.has(RomPatches.HiJumpAreaBlueDoor): DoorsManager.doors['BusinessCenterBottomLeft'].forceBlue() if RomPatches.has(RomPatches.SpeedAreaBlueDoors): DoorsManager.doors['BubbleMountainTopRight'].forceBlue() DoorsManager.doors['SpeedBoosterHallRight'].forceBlue() if RomPatches.has(RomPatches.MamaTurtleBlueDoor): DoorsManager.doors['FishTankRight'].forceBlue() if RomPatches.has(RomPatches.HellwayBlueDoor): DoorsManager.doors['RedTowerElevatorLeft'].forceBlue() if RomPatches.has(RomPatches.RedTowerBlueDoors): DoorsManager.doors['RedBrinstarElevatorTop'].forceBlue() if RomPatches.has(RomPatches.AreaRandoBlueDoors): DoorsManager.doors['GreenHillZoneTopRight'].forceBlue() DoorsManager.doors['NoobBridgeRight'].forceBlue() DoorsManager.doors['LeCoudeBottom'].forceBlue() DoorsManager.doors['KronicBoostBottomLeft'].forceBlue() else: # no area rando, prevent some doors to be in the grey doors pool DoorsManager.doors['GreenPiratesShaftBottomRight'].canGrey = False DoorsManager.doors['CrocomireSpeedwayBottom'].canGrey = False DoorsManager.doors['KronicBoostBottomLeft'].canGrey = False if RomPatches.has(RomPatches.AreaRandoMoreBlueDoors): DoorsManager.doors['KihunterBottom'].forceBlue() DoorsManager.doors['GreenPiratesShaftBottomRight'].forceBlue() if RomPatches.has(RomPatches.CrocBlueDoors): DoorsManager.doors['CrocomireSpeedwayBottom'].forceBlue() if RomPatches.has(RomPatches.CrabShaftBlueDoor): DoorsManager.doors['CrabShaftRight'].forceBlue()
def canFireChargedShots(self): sm = self.smbm return sm.wor(sm.haveItem('Charge'), RomPatches.has(RomPatches.NerfedCharge))
def canOpenRedDoors(self): sm = self.smbm return sm.wor( sm.wand(sm.wnot(RomPatches.has(RomPatches.RedDoorsMissileOnly)), sm.haveMissileOrSuper()), sm.haveItem('Missile'))
def getPiratesPseudoScrewCoeff(self): ret = 1.0 if RomPatches.has(RomPatches.NerfedCharge).bool == True: ret = 4.0 return ret
def heatProof(self): sm = self.smbm return sm.wor(sm.haveItem('Varia'), sm.wand(sm.wnot(RomPatches.has(RomPatches.NoGravityEnvProtection)), sm.wnot(RomPatches.has(RomPatches.ProgressiveSuits)), sm.haveItem('Gravity')))
def getPiratesPseudoScrewCoeff(self): sm = self.smbm ret = 1.0 if RomPatches.has(sm.player, RomPatches.NerfedCharge).bool == True: ret = 4.0 return ret
def canClimbBottomRedTower(self): sm = self.smbm return sm.wor(RomPatches.has(RomPatches.RedTowerLeftPassage), sm.haveItem('HiJump'), sm.haveItem('Ice'), sm.canFly(), sm.canShortCharge())
def loadRom(self, rom, interactive=False, magic=None, startAP=None): # startAP param is only use for seedless if rom == None: # TODO::add a --logic parameter for seedless Logic.factory('varia') self.romFileName = 'seedless' self.majorsSplit = 'Full' self.areaRando = True self.bossRando = True self.escapeRando = False self.escapeTimer = "03:00" self.startAP = startAP RomPatches.setDefaultPatches(startAP) self.startArea = getAccessPoint(startAP).Start['solveArea'] # in seedless load all the vanilla transitions self.areaTransitions = vanillaTransitions[:] self.bossTransitions = vanillaBossesTransitions[:] self.escapeTransition = [vanillaEscapeTransitions[0]] # in seedless we allow mixing of area and boss transitions self.hasMixedTransitions = True self.curGraphTransitions = self.bossTransitions + self.areaTransitions + self.escapeTransition self.locations = Logic.locations for loc in self.locations: loc.itemName = 'Nothing' # set doors related to default patches DoorsManager.setDoorsColor() self.doorsRando = False else: self.romFileName = rom self.romLoader = RomLoader.factory(rom, magic) Logic.factory(self.romLoader.readLogic()) self.romLoader.readNothingId() self.locations = Logic.locations self.majorsSplit = self.romLoader.assignItems(self.locations) (self.startAP, self.startArea, startPatches) = self.romLoader.getStartAP() (self.areaRando, self.bossRando, self.escapeRando) = self.romLoader.loadPatches() RomPatches.ActivePatches += startPatches self.escapeTimer = self.romLoader.getEscapeTimer() self.doorsRando = self.romLoader.loadDoorsColor() if interactive == False: print( "ROM {} majors: {} area: {} boss: {} escape: {} patches: {} activePatches: {}" .format(rom, self.majorsSplit, self.areaRando, self.bossRando, self.escapeRando, sorted(self.romLoader.getPatches()), sorted(RomPatches.ActivePatches))) else: print( "majors: {} area: {} boss: {} escape: {} activepatches: {}" .format(self.majorsSplit, self.areaRando, self.bossRando, self.escapeRando, sorted(RomPatches.ActivePatches))) (self.areaTransitions, self.bossTransitions, self.escapeTransition, self.hasMixedTransitions) = self.romLoader.getTransitions() if interactive == True and self.debug == False: # in interactive area mode we build the graph as we play along if self.areaRando == True and self.bossRando == True: self.curGraphTransitions = [] elif self.areaRando == True: self.curGraphTransitions = self.bossTransitions[:] elif self.bossRando == True: self.curGraphTransitions = self.areaTransitions[:] else: self.curGraphTransitions = self.bossTransitions + self.areaTransitions if self.escapeRando == False: self.curGraphTransitions += self.escapeTransition else: self.curGraphTransitions = self.bossTransitions + self.areaTransitions + self.escapeTransition self.smbm = SMBoolManager() self.areaGraph = AccessGraph(Logic.accessPoints, self.curGraphTransitions) # store at each step how many locations are available self.nbAvailLocs = [] if self.log.getEffectiveLevel() == logging.DEBUG: self.log.debug("Display items at locations:") for loc in self.locations: self.log.debug('{:>50}: {:>16}'.format(loc.Name, loc.itemName))
def canTraverseCrabTunnelLeftToRight(self): sm = self.smbm return sm.wand( sm.traverse('MainStreetBottomRight'), sm.wor(sm.haveItem('Super'), RomPatches.has(RomPatches.AreaRandoGatesOther)))
def canPassLowerNorfairChozo(self): sm = self.smbm # to require one more CF if no heat protection because of distance to cover, wait times, acid... return sm.wand(sm.canHellRun(**Settings.hellRunsTable['LowerNorfair']['Entrance -> GT via Chozo']), sm.canUsePowerBombs(), sm.wor(RomPatches.has(RomPatches.LNChozoSJCheckDisabled), sm.haveItem('SpaceJump')))