Exemplo n.º 1
0
 def escapeGraph(self, emptyContainer, graph, maxDiff):
     if not self.escapeRando:
         return
     possibleTargets, dst, path = self.getPossibleEscapeTargets(
         emptyContainer, graph, maxDiff)
     # update graph with escape transition
     graph.addTransition(escapeSource, dst)
     # get timer value
     self.escapeTimer(graph, path)
     self.log.debug("escapeGraph: ({}, {}) timer: {}".format(
         escapeSource, dst, graph.EscapeAttributes['Timer']))
     # animals
     GraphUtils.escapeAnimalsTransitions(graph, possibleTargets, dst)
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
 def setDefaultPatches(startAP):
     # called by the isolver in seedless mode.
     # activate only layout patch (the most common one), red tower blue doors and the startAP's patches.
     from graph.graph_access import GraphUtils
     RomPatches.ActivePatches = [
         RomPatches.RedTowerBlueDoors
     ] + RomPatches.TotalLayout + GraphUtils.getGraphPatches(startAP)
Exemplo n.º 4
0
 def setNothingId(self, startAP, itemLocs):
     # morph ball loc by default
     self.nothingId = 0x1a
     # if not default start, use first loc with a nothing
     if not GraphUtils.isStandardStart(startAP):
         firstNothing = next((il.Location for il in itemLocs if il.Item.Category == 'Nothing' and 'Boss' not in il.Location.Class), None)
         if firstNothing is not None:
             self.nothingId = firstNothing.Id
Exemplo n.º 5
0
 def createGraph(self):
     transitions = self.graphSettings.plandoRandoTransitions
     if transitions is None:
         transitions = []
         if self.minimizerN is not None:
             transitions = GraphUtils.createMinimizerTransitions(
                 self.graphSettings.startAP, self.minimizerN)
         else:
             if not self.bossRando:
                 transitions += vanillaBossesTransitions
             else:
                 transitions += GraphUtils.createBossesTransitions()
             if not self.areaRando:
                 transitions += vanillaTransitions
             else:
                 transitions += GraphUtils.createAreaTransitions(
                     self.graphSettings.lightAreaRando)
     return AccessGraph(accessPoints, transitions,
                        self.graphSettings.dotFile)
 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)
Exemplo n.º 7
0
    def loadTransitions(self):
        # return the transitions
        rooms = GraphUtils.getRooms()
        bossTransitions = {}
        areaTransitions = {}
        for accessPoint in accessPoints:
            if accessPoint.isInternal() == True:
                continue
            key = self.getTransition(accessPoint.ExitInfo['DoorPtr'])

            destAP = rooms[key]
            if accessPoint.Boss == True or destAP.Boss == True:
                bossTransitions[accessPoint.Name] = destAP.Name
            else:
                areaTransitions[accessPoint.Name] = destAP.Name

        def removeBiTrans(transitions):
            # remove bidirectionnal transitions
            # can't del keys in a dict while iterating it
            transitionsCopy = copy.copy(transitions)
            for src in transitionsCopy:
                if src in transitions:
                    dest = transitions[src]
                    if dest in transitions:
                        if transitions[dest] == src:
                            del transitions[dest]

            return [(t, transitions[t]) for t in transitions]

        # get escape transition
        escapeSrcAP = getAccessPoint('Tourian Escape Room 4 Top Right')
        key = self.getTransition(escapeSrcAP.ExitInfo['DoorPtr'])
        escapeDstAP = rooms[key]
        escapeTransition = [(escapeSrcAP.Name, escapeDstAP.Name)]

        areaTransitions = removeBiTrans(areaTransitions)
        bossTransitions = removeBiTrans(bossTransitions)

        return (areaTransitions, bossTransitions, escapeTransition, GraphUtils.hasMixedTransitions(areaTransitions, bossTransitions))
Exemplo n.º 8
0
def getDefaultMultiValues():
    from graph.graph_access import GraphUtils
    defaultMultiValues = {
        'startLocation':
        GraphUtils.getStartAccessPointNames(),
        'majorsSplit': ['Full', 'Major', 'Chozo'],
        'progressionSpeed': [
            'slowest', 'slow', 'medium', 'fast', 'fastest', 'basic',
            'VARIAble', 'speedrun'
        ],
        'progressionDifficulty': ['easier', 'normal', 'harder'],
        'morphPlacement': ['early', 'late', 'normal'],
        'energyQty': ['ultra sparse', 'sparse', 'medium', 'vanilla']
    }
    return defaultMultiValues
    def savePlando(self, lock, escapeTimer):
        # store filled locations addresses in the ROM for next creating session
        from rando.Items import ItemManager
        locsItems = {}
        itemLocs = []
        for loc in self.visitedLocations:
            locsItems[loc.Name] = loc.itemName
        for loc in self.locations:
            if loc.Name in locsItems:
                itemLocs.append(
                    ItemLocation(ItemManager.getItem(loc.itemName), loc))
            else:
                # put nothing items in unused locations
                itemLocs.append(
                    ItemLocation(ItemManager.getItem("Nothing"), loc))

        # patch the ROM
        if lock == True:
            import random
            magic = random.randint(1, 0xffff)
        else:
            magic = None
        romPatcher = RomPatcher(magic=magic, plando=True)
        patches = [
            'credits_varia.ips', 'tracking.ips', "Escape_Animals_Disable",
            'beam_doors.ips'
        ]
        if magic != None:
            patches.insert(0, 'race_mode.ips')
            patches.append('race_mode_credits.ips')
        romPatcher.addIPSPatches(patches)

        plms = []
        if self.areaRando == True or self.bossRando == True or self.escapeRando == True:
            doors = GraphUtils.getDoorConnections(self.fillGraph(),
                                                  self.areaRando,
                                                  self.bossRando,
                                                  self.escapeRando, False)
            romPatcher.writeDoorConnections(doors)
            if magic == None:
                doorsPtrs = GraphUtils.getAps2DoorsPtrs()
                romPatcher.writePlandoTransitions(
                    self.curGraphTransitions, doorsPtrs,
                    len(vanillaBossesTransitions) + len(vanillaTransitions))
            if self.escapeRando == True and escapeTimer != None:
                # convert from '03:00' to number of seconds
                escapeTimer = int(escapeTimer[0:2]) * 60 + int(
                    escapeTimer[3:5])
                romPatcher.applyEscapeAttributes(
                    {
                        'Timer': escapeTimer,
                        'Animals': None
                    }, plms)

        # write plm table & random doors
        romPatcher.writePlmTable(plms, self.areaRando, self.bossRando,
                                 self.startAP)

        romPatcher.setNothingId(self.startAP, itemLocs)
        romPatcher.writeItemsLocs(itemLocs)
        romPatcher.writeItemsNumber()
        romPatcher.writeSpoiler(itemLocs)
        romPatcher.writeNothingId()

        class FakeRandoSettings:
            def __init__(self):
                self.qty = {'energy': 'plando'}
                self.progSpeed = 'plando'
                self.progDiff = 'plando'
                self.restrictions = {'Suits': False, 'Morph': 'plando'}
                self.superFun = {}

        randoSettings = FakeRandoSettings()
        romPatcher.writeRandoSettings(randoSettings, itemLocs)
        if magic != None:
            romPatcher.writeMagic()
        else:
            romPatcher.writePlandoAddresses(self.visitedLocations)

        romPatcher.commitIPS()
        romPatcher.end()

        data = romPatcher.romFile.data
        preset = os.path.splitext(os.path.basename(self.presetFileName))[0]
        seedCode = 'FX'
        if self.bossRando == True:
            seedCode = 'B' + seedCode
        if self.areaRando == True:
            seedCode = 'A' + seedCode
        from time import gmtime, strftime
        fileName = 'VARIA_Plandomizer_{}{}_{}.sfc'.format(
            seedCode, strftime("%Y%m%d%H%M%S", gmtime()), preset)
        data["fileName"] = fileName
        # error msg in json to be displayed by the web site
        data["errorMsg"] = ""
        with open(self.outputFileName, 'w') as jsonFile:
            json.dump(data, jsonFile)
 def loadPlandoTransitions(self):
     # add escape transition
     transitionsAddr = self.romLoader.getPlandoTransitions(
         len(vanillaBossesTransitions) + len(vanillaTransitions) + 1)
     return GraphUtils.getTransitions(transitionsAddr)
Exemplo n.º 11
0
     const=35,
     default=None,
     choices=[str(i) for i in range(30, 101)] + ["random"])
 parser.add_argument('--minimizerTourian',
                     help="Tourian speedup in minimizer mode",
                     dest='minimizerTourian',
                     nargs='?',
                     const=True,
                     default=False)
 parser.add_argument('--startAP',
                     help="Name of the Access Point to start from",
                     dest='startAP',
                     nargs='?',
                     default="Landing Site",
                     choices=['random'] +
                     GraphUtils.getStartAccessPointNames())
 parser.add_argument('--startLocation',
                     help="Name of the Access Point to start from",
                     dest='startAP',
                     nargs='?',
                     default="Landing Site",
                     choices=['random'] +
                     GraphUtils.getStartAccessPointNames())
 parser.add_argument('--startLocationList',
                     help="list to choose from when random",
                     dest='startLocationList',
                     nargs='?',
                     default=None)
 parser.add_argument('--debug',
                     '-d',
                     help="activate debug logging",
Exemplo n.º 12
0
 def createItemLocContainer(self):
     self.getForbidden()
     self.log.debug("LAST CHECKPOOL")
     if not self.checkPool():
         self.log.debug("createItemLocContainer: checkPool fail")
         return None
     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':
         itemTypes = {
             item.Type
             for item in self.container.itemPool
             if item.Category not in ['Energy', 'Nothing', 'Boss']
         }
         itemTypes.remove('Missile')
         items = [
             self.container.getNextItemInPool(itemType)
             for itemType in itemTypes
         ]
         restrictionDict = {}
         for item in items:
             itemType = item.Type
             poss = self.services.possibleLocations(item, self.startAP,
                                                    self.container)
             for loc in poss:
                 if loc.GraphArea not in restrictionDict:
                     restrictionDict[loc.GraphArea] = {}
                 if itemType not in restrictionDict[loc.GraphArea]:
                     restrictionDict[loc.GraphArea][itemType] = set()
                 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 += ['Energy Tank, Brinstar Ceiling']
             for area, locDict in restrictionDict.items():
                 if area == 'Crateria':
                     locDict['Morph'] = set(morphLocs)
                 elif 'Morph' in locDict:
                     del locDict['Morph']
         self.restrictions.addPlacementRestrictions(restrictionDict)
     self.fillRestrictedLocations()
     self.settings.collectAlreadyPlacedItemLocations(self.container)
     self.settings.updateSuperFun(self.superFun)
     return self.container
Exemplo n.º 13
0
 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)