def createItemLocContainer(self): self.getForbidden() self.log.debug("LAST CHECKPOOL") if not self.checkPool(): self.log.debug("createItemLocContainer: checkPool fail") return None self.checkDoorBeams() self.container = ItemLocContainer(self.sm, self.getItemPool(), self.locations) if self.restrictions.isLateMorph(): self.restrictions.lateMorphInit(self.startAP, self.container, self.services) isStdStart = GraphUtils.isStandardStart(self.startAP) # ensure we have an area layout that can put morph outside start area # TODO::allow for custom start which doesn't require morph early if self.graphSettings.areaRando and isStdStart and not self.restrictions.suitsRestrictions and self.restrictions.lateMorphForbiddenArea is None: self.container = None self.log.debug("createItemLocContainer: checkLateMorph fail") return None # checkStart needs the container if not self.checkStart(): self.container = None self.log.debug("createItemLocContainer: checkStart fail") return None # add placement restriction helpers for random fill if self.settings.progSpeed == 'speedrun': restrictionDict = self.getSpeedrunRestrictionsDict() self.restrictions.addPlacementRestrictions(restrictionDict) self.settings.collectAlreadyPlacedItemLocations(self.container) self.fillRestrictedLocations() self.settings.updateSuperFun(self.superFun) return self.container
def getSpeedrunRestrictionsDict(self): itemTypes = { item.Type for item in self.container.itemPool if item.Category not in Restrictions.NoCheckCat } allAreas = {loc.GraphArea for loc in self.locations} items = [ self.container.getNextItemInPool(itemType) for itemType in itemTypes ] restrictionDict = {} for area in allAreas: restrictionDict[area] = {} for itemType in itemTypes: restrictionDict[area][itemType] = set() for item in items: itemType = item.Type poss = self.services.possibleLocations(item, self.startAP, self.container) for loc in poss: restrictionDict[loc.GraphArea][itemType].add(loc.Name) if self.restrictions.isEarlyMorph() and GraphUtils.isStandardStart( self.startAP): morphLocs = ['Morphing Ball'] if self.restrictions.split in ['Full', 'Major']: dboost = self.sm.knowsCeilingDBoost() if dboost.bool == True and dboost.difficulty <= self.settings.maxDiff: morphLocs.append('Energy Tank, Brinstar Ceiling') for area, locDict in restrictionDict.items(): if area == 'Crateria': locDict['Morph'] = set(morphLocs) else: locDict['Morph'] = set() return restrictionDict
def applyStartAP(self, apName, plms, doors): ap = getAccessPoint(apName) if not GraphUtils.isStandardStart(apName): # not Ceres or Landing Site, so Zebes will be awake plms.append('Morph_Zebes_Awake') (w0, w1) = getWord(ap.Start['spawn']) if 'doors' in ap.Start: doors += ap.Start['doors'] doors.append(0x0) addr = 0x10F200 patch = [w0, w1] + doors assert (addr + len(patch)) < 0x10F210, "Stopped before new_game overwrite" patchDict = { 'StartAP': { addr: patch }, } self.applyIPSPatch('StartAP', patchDict) # handle custom saves if 'save' in ap.Start: self.applyIPSPatch(ap.Start['save']) plms.append(ap.Start['save']) # handle optional rom patches if 'rom_patches' in ap.Start: for patch in ap.Start['rom_patches']: self.applyIPSPatch(patch)
def __init__(self, startAP, graph, restrictions, emptyContainer, endDate=infinity): super(FrontFiller, self).__init__(startAP, graph, restrictions, emptyContainer, endDate) self.choice = ItemThenLocChoice(restrictions) self.stdStart = GraphUtils.isStandardStart(self.startAP)
def createItemLocContainer(self, endDate, vcr=None): self.getForbidden() self.log.debug("LAST CHECKPOOL") if not self.checkPool(): self.log.debug("createItemLocContainer: last checkPool fail") return None # reset restricted in locs from previous attempt for loc in self.locations: loc.restricted = False for loc in self.restrictedLocs: self.log.debug( "createItemLocContainer: loc is restricted: {}".format( loc.Name)) loc.restricted = True self.checkDoorBeams() self.container = ItemLocContainer(self.sm, self.getItemPool(), self.locations) if self.restrictions.isLateMorph(): self.restrictions.lateMorphInit(self.startAP, self.container, self.services) isStdStart = GraphUtils.isStandardStart(self.startAP) # ensure we have an area layout that can put morph outside start area # TODO::allow for custom start which doesn't require morph early if self.graphSettings.areaRando and isStdStart and not self.restrictions.suitsRestrictions and self.restrictions.lateMorphForbiddenArea is None: self.container = None self.log.debug("createItemLocContainer: checkLateMorph fail") return None # checkStart needs the container if not self.checkStart(): self.container = None self.log.debug("createItemLocContainer: checkStart fail") return None self.settings.collectAlreadyPlacedItemLocations(self.container) self.fillRestrictedLocations() if self.restrictions.split == 'Scavenger': # initScavenger will actually fill up the container using random fill, # the scavenger "filler" will focus on determining mandatory route self.container = self.initScavenger(endDate, vcr) if self.container is None: self.log.debug("createItemLocContainer: initScavenger fail") return None elif self.settings.progSpeed == 'speedrun': # add placement restriction helpers for random fill self.restrictions.setPlacementRestrictions( self.getRestrictionsDict()) self.settings.updateSuperFun(self.superFun) return self.container
def __init__(self, graphSettings, areaGraph, restrictions, container, endDate): super(FillerProgSpeed, self).__init__(graphSettings.startAP, areaGraph, restrictions, container, endDate) distanceProp = 'GraphArea' if graphSettings.areaRando else 'Area' self.stdStart = GraphUtils.isStandardStart(self.startAP) self.progSpeedParams = ProgSpeedParameters(self.restrictions, len(container.unusedLocations)) self.choice = ItemThenLocChoiceProgSpeed(restrictions, self.progSpeedParams, distanceProp, self.services)
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('vanilla') self.romFileName = 'seedless' self.majorsSplit = 'Full' self.masterMajorsSplit = '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 self.hasNothing = 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.masterMajorsSplit) = self.romLoader.assignItems(self.locations) (self.startAP, self.startArea, startPatches) = self.romLoader.getStartAP() if not GraphUtils.isStandardStart(self.startAP) 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) = self.romLoader.loadPatches() RomPatches.ActivePatches += startPatches self.escapeTimer = self.romLoader.getEscapeTimer() self.doorsRando = self.romLoader.loadDoorsColor() self.hasNothing = self.checkLocsForNothing() 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))
args.suitsRestriction = bool(random.getrandbits(1)) logger.debug("suitsRestriction: {}".format(args.suitsRestriction)) if args.hideItems == 'random': args.hideItems = bool(random.getrandbits(1)) if args.morphPlacement == 'random': if args.morphPlacementList != None: morphPlacements = args.morphPlacementList.split(',') args.morphPlacement = random.choice(morphPlacements) # Scavenger Hunt constraints if args.majorsSplit == 'Scavenger': forceArg('progressionSpeed', 'speedrun', "'Progression speed' forced to speedrun") progSpeed = "speedrun" forceArg('hud', True, "'VARIA HUD' forced to on", webValue='on') if not GraphUtils.isStandardStart(args.startLocation): forceArg('startLocation', "Landing Site", "Start Location forced to Landing Site because of Scavenger mode") if args.morphPlacement == 'late': forceArg('morphPlacement', 'normal', "'Morph Placement' forced to normal instead of late") # use escape rando for auto escape trigger if args.tourian == 'Disabled': forceArg('escapeRando', True, "'Escape randomization' forced to on", webValue='on') forceArg('noRemoveEscapeEnemies', True, "Enemies enabled during escape sequence", webArg='removeEscapeEnemies', webValue='off') # random fill makes certain options unavailable if (progSpeed == 'speedrun' or progSpeed == 'basic') and args.majorsSplit != 'Scavenger': forceArg('progressionDifficulty', 'normal', "'Progression difficulty' forced to normal") progDiff = args.progressionDifficulty logger.debug("progressionDifficulty: {}".format(progDiff)) if args.strictMinors == 'random': args.strictMinors = bool(random.getrandbits(1))