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 getDmgReduction(self, envDmg=True): ret = 1.0 sm = self.smbm hasVaria = sm.haveItem('Varia') hasGrav = sm.haveItem('Gravity') items = [] if RomPatches.has(RomPatches.NoGravityEnvProtection): if hasVaria: items = ['Varia'] if envDmg: ret = 4.0 else: ret = 2.0 if hasGrav and not envDmg: ret = 4.0 items = ['Gravity'] elif RomPatches.has(RomPatches.ProgressiveSuits): if hasVaria: items.append('Varia') ret *= 2 if hasGrav: items.append('Gravity') ret *= 2 else: if hasVaria: ret = 2.0 items = ['Varia'] if hasGrav: ret = 4.0 items = ['Gravity'] return (ret, items)
def enoughMajors(self, smbm, majorLocations): # the end condition if self.itemsPickup == 'all': return len(majorLocations) == 0 elif self.itemsPickup == 'any': return True elif self.itemsPickup == 'minimal': canResistRainbow = ((smbm.haveItemCount('ETank', 3) and smbm.haveItem('Varia')) or smbm.haveItemCount('ETank', 6) or RomPatches.has(RomPatches.NerfedRainbowBeam)) return (smbm.haveItem('Morph') # pass bomb block passages and (smbm.haveItem('Bomb') or smbm.haveItem('PowerBomb')) # mother brain rainbow attack and canResistRainbow # lower norfair access and (smbm.haveItem('Varia') or smbm.wand(smbm.wnot(RomPatches.has(RomPatches.NoGravityEnvProtection)), smbm.wnot(RomPatches.has(RomPatches.ProgressiveSuits)))) # gravity is checked below # speed or ice to access botwoon and (smbm.haveItem('SpeedBooster') or smbm.haveItem('Ice')) # draygon access and smbm.haveItem('Gravity') # all boss locs collected (draygon pickup is not on draygon location) and not any(loc.isBoss() for loc in majorLocations)) else: return False
def enoughStuffTourian(self): sm = self.smbm ret = self.smbm.wand(sm.wor(RomPatches.has(RomPatches.TourianSpeedup), sm.wand(sm.canPassMetroids(), sm.canPassZebetites())), sm.canOpenRedDoors(), sm.enoughStuffsMotherbrain(), sm.wor(RomPatches.has(RomPatches.OpenZebetites), sm.haveItem('Morph'))) return ret
def canGoThroughLowerNorfairEnemy(self, nmyHealth, nbNmy, nmyHitDmg, supDmg=300.0): sm = self.smbm if sm.heatProof().bool == True: # supers only if sm.itemCount('Super')*5*supDmg >= nbNmy*nmyHealth: return SMBool(True, 0, items=['Super']) # - or with taking damage as well? (dmgRed, redItems) = sm.getDmgReduction(envDmg=False) dmg = nmyHitDmg / dmgRed if (sm.itemCount('Super')*5*supDmg)/nmyHealth + (sm.energyReserveCount()*100 - 2)/dmg >= nbNmy: # display all the available energy in the solver. return SMBool(True, 0, items=redItems+['Super', '{}-ETank - {}-Reserve'.format(self.smbm.itemCount('ETank'), self.smbm.itemCount('Reserve'))]) else: # NOTE: assuming mult=1 for LN hellrun here. we can, because this function is only called # in "main LN" areas (ie not GT), which has a mult of 1 mult = 1.0 if sm.wand(RomPatches.has(RomPatches.ProgressiveSuits), sm.haveItem('Gravity')).bool == True: # half heat protection mult *= 2.0 nCF = self.getLNRequiredCFs(mult) canCF = self.canCrystalFlash(nCF + 1) if canCF.bool == True: return canCF return sm.knowsDodgeLowerNorfairEnemies()
def canClimbBottomRedTower(self): sm = self.smbm return sm.wor(sm.wor(RomPatches.has(RomPatches.RedTowerLeftPassage), sm.haveItem('HiJump'), sm.haveItem('Ice'), sm.canFly()), sm.canShortCharge())
def enoughStuffTourian(self): sm = self.smbm ret = self.smbm.wand(sm.wor(RomPatches.has(RomPatches.TourianSpeedup), sm.wand(sm.canPassMetroids(), sm.canPassZebetites())), sm.enoughStuffsMotherbrain()) return ret
def mbEtankCheck(self): sm = self.smbm if sm.wor(RomPatches.has(RomPatches.NerfedRainbowBeam), RomPatches.has(RomPatches.TourianSpeedup)): # "add" energy for difficulty calculations energy = 2.8 if sm.haveItem('Varia') else 2.6 return (True, energy) nTanks = sm.energyReserveCount() energyDiff = 0 if sm.haveItem('Varia') == False: # "remove" 3 etanks (accounting for rainbow beam damage without varia) if nTanks < 6: return (False, 0) energyDiff = -3 elif nTanks < 3: return (False, 0) return (True, energyDiff)
def canHellRun(self, hellRun, mult=1.0, minE=2): sm = self.smbm items = [] isHeatProof = sm.heatProof() if isHeatProof == True: return isHeatProof if sm.wand(RomPatches.has(RomPatches.ProgressiveSuits), sm.haveItem('Gravity')).bool == True: # half heat protection mult *= 2.0 minE /= 2.0 items.append('Gravity') if self.energyReserveCount() >= minE: if hellRun != 'LowerNorfair': ret = self.energyReserveCountOkHellRun(hellRun, mult) if ret.bool == True: ret._items.append(items) return ret else: nCF = self.getLNRequiredCFs(mult) ret = sm.wand(self.energyReserveCountOkHellRun(hellRun, mult), self.canCrystalFlash(nCF)) if ret.bool == True: if sm.haveItem('Gravity') == True: ret.difficulty *= 0.7 ret._items.append('Gravity') elif sm.haveItem('ScrewAttack') == True: ret.difficulty *= 0.7 ret._items.append('ScrewAttack') #nPB = self.smbm.itemCount('PowerBomb') #print("canHellRun LN. tanks=" + str(tanks) + ", nCF=" + str(nCF) + ", nPB=" + str(nPB) + ", mult=" + str(mult) + ", heatProof=" + str(isHeatProof.bool) + ", ret=" + str(ret)) return ret else: return smboolFalse
def canOpenRedDoors(self): sm = self.smbm return sm.wor( sm.wand( sm.wnot( RomPatches.has(sm.player, RomPatches.RedDoorsMissileOnly)), sm.haveMissileOrSuper()), sm.haveItem('Missile'))
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 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')))
def canAccessBillyMays(self): sm = self.smbm return sm.wand( sm.wor(RomPatches.has(RomPatches.BlueBrinstarBlueDoor), sm.traverse('ConstructionZoneRight')), sm.canUsePowerBombs(), sm.wor(sm.knowsBillyMays(), sm.haveItem('Gravity'), sm.haveItem('SpaceJump')))
def canPassForgottenHighway(self, fromWs): sm = self.smbm suitless = sm.wand(sm.haveItem('HiJump'), sm.knowsGravLessLevel1()) if fromWs is True and RomPatches.has(RomPatches.EastOceanPlatforms).bool is False: suitless = sm.wand(suitless, # to break water line and go through the door on the right sm.haveItem('SpaceJump')) return sm.wand(sm.wor(sm.haveItem('Gravity'), suitless), sm.haveItem('Morph')) # for crab maze
def canEnterCathedral(self, mult=1.0): sm = self.smbm return sm.wand(sm.traverse('CathedralEntranceRight'), sm.wor(sm.wand(sm.canHellRun('MainUpperNorfair', mult), sm.wor(sm.wor(RomPatches.has(RomPatches.CathedralEntranceWallJump), sm.haveItem('HiJump'), sm.canFly()), sm.wor(sm.haveItem('SpeedBooster'), # spark sm.canSpringBallJump()))), sm.wand(sm.canHellRun('MainUpperNorfair', 0.5*mult), sm.haveItem('Morph'), sm.knowsNovaBoost())))
def getRoomsVisibility(self, solver, areaGraph, sm): # add graph access points roomsVisibility = set([ self.transition2isolver(ap.Name) + 'Svg' for ap in solver.areaGraph.availAccessPoints ]) # add available locations roomsVisibility.update([ loc + 'Svg' for loc, data in self.state["availableLocationsWeb"].items() if data["difficulty"] != "break" ]) # add visited locations roomsVisibility.update([ loc + 'Svg' for loc, data in self.state["visitedLocationsWeb"].items() if 'accessPoint' in data and data['accessPoint'] + 'Svg' in roomsVisibility ]) # add special rooms that have conditions to traverse them but no item in them, # so we need to know if they are visible or not if 'crocomireRoomTopSvg' in roomsVisibility and sm.enoughStuffCroc(): roomsVisibility.add('CrocomireSvg') if 'greenBrinstarElevatorSvg' in roomsVisibility and sm.traverse( 'MainShaftBottomRight'): roomsVisibility.add('DachoraRoomLeftSvg') if 'bigPinkSvg' in roomsVisibility and sm.canPassDachoraRoom(): roomsVisibility.add('DachoraRoomCenterSvg') if ('redBrinstarElevatorSvg' in roomsVisibility and sm.wor(RomPatches.has(RomPatches.HellwayBlueDoor), sm.traverse('RedTowerElevatorLeft'))) or ( 'redTowerTopLeftSvg' in roomsVisibility and sm.canClimbRedTower()): roomsVisibility.add('HellwaySvg') if 'businessCenterSvg' in roomsVisibility and sm.haveItem( 'SpeedBooster'): roomsVisibility.add('FrogSpeedwayCenterSvg') if 'crabShaftLeftSvg' in roomsVisibility or 'redFishRoomLeftSvg' in roomsVisibility or ( 'mainStreetBottomSvg' in roomsVisibility and sm.canDoOuterMaridia()): roomsVisibility.add('westMaridiaSvg') if 'mainStreetBottomSvg' in roomsVisibility and sm.canTraverseCrabTunnelLeftToRight( ): roomsVisibility.add('CrabTunnelSvg') if 'SpaceJumpSvg' in roomsVisibility and ( 'colosseumTopRightSvg' in roomsVisibility or 'leCoudeRightSvg' in roomsVisibility): roomsVisibility.add('CacatacAlleySvg') return list(roomsVisibility)
def getForbiddenMovement(self): self.log.debug("getForbiddenMovement BEGIN. forbidden="+str(self.forbiddenItems)) removableMovement = [mvt for mvt in self.movementItems if self.checkPool([mvt])] if 'Bomb' in removableMovement and not RomPatches.has(RomPatches.BombTorizoWake) and Objectives.isGoalActive("activate chozo robots"): # in this objective, without VARIA tweaks, BT has to wake so give bombs removableMovement.remove('Bomb') self.log.debug("getForbiddenMovement removable="+str(removableMovement)) if len(removableMovement) > 0: # remove at least the most important self.forbiddenItems.append(removableMovement.pop(0)) self.addForbidden(removableMovement + [None]) else: self.superFun.remove('Movement') self.log.debug('Super Fun : Could not remove any movement item') self.log.debug("getForbiddenMovement END. forbidden="+str(self.forbiddenItems))
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) }
def canOpenEyeDoors(self): sm = self.smbm return sm.wor(RomPatches.has(RomPatches.NoGadoras), sm.haveMissileOrSuper())
def getPiratesPseudoScrewCoeff(self): sm = self.smbm ret = 1.0 if RomPatches.has(sm.player, RomPatches.NerfedCharge).bool == True: ret = 4.0 return ret
def canPassRedTowerToMaridiaNode(self): sm = self.smbm return sm.wand(sm.haveItem('Morph'), RomPatches.has(RomPatches.AreaRandoGatesBase))
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()
), # 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 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 canFireChargedShots(self): sm = self.smbm return sm.wor(sm.haveItem('Charge'), RomPatches.has(RomPatches.NerfedCharge))
def getPiratesPseudoScrewCoeff(self): ret = 1.0 if RomPatches.has(RomPatches.NerfedCharge).bool == True: ret = 4.0 return ret
def canTraverseCrabTunnelLeftToRight(self): sm = self.smbm return sm.wand( sm.traverse('MainStreetBottomRight'), sm.wor(sm.haveItem('Super'), RomPatches.has(RomPatches.AreaRandoGatesOther)))