예제 #1
0
 def findStartupProgItemPair(self, ap, container):
     self.log.debug("findStartupProgItemPair")
     (itemLocDict, isProg) = self.getPossiblePlacements(ap, container, ComebackCheckType.NoCheck)
     assert not isProg
     items = list(itemLocDict.keys())
     random.shuffle(items)
     for item in items:
         cont = copy.copy(container)
         loc = random.choice(itemLocDict[item])
         itemLoc1 = ItemLocation(item, loc)
         self.log.debug("itemLoc1 attempt: "+getItemLocStr(itemLoc1))
         newAP = self.collect(ap, cont, itemLoc1)
         if self.cache is not None:
             self.cache.reset()
         (ild, isProg) = self.getPossiblePlacements(newAP, cont, ComebackCheckType.NoCheck)
         if isProg:
             item2 = random.choice(list(ild.keys()))
             itemLoc2 = ItemLocation(item2, random.choice(ild[item2]))
             self.log.debug("itemLoc2: "+getItemLocStr(itemLoc2))
             return (itemLoc1, itemLoc2)
     return None
 def generateItem(self):
     itemLocDict, possibleProg = self.services.getPossiblePlacements(self.ap, self.container, self.getComebackCheck())
     if self.isEarlyGame() and possibleProg == True:
         # cheat a little bit if non-standard start: place early
         # progression away from crateria/blue brin if possible
         startAp = getAccessPoint(self.startAP)
         if startAp.GraphArea != "Crateria":
             newItemLocDict = {}
             for w, locs in itemLocDict.items():
                 filtered = [loc for loc in locs if loc['GraphArea'] != 'Crateria']
                 if len(filtered) > 0:
                     newItemLocDict[w] = filtered
             if len(newItemLocDict) > 0:
                 itemLocDict = newItemLocDict
     itemLoc = self.chooseItemLoc(itemLocDict, possibleProg)
     self.log.debug("generateItem. itemLoc="+"None" if itemLoc is None else getItemLocStr(itemLoc))
     return itemLoc
예제 #3
0
    def escapeTrigger(self, emptyContainer, graph, maxDiff, escapeTrigger):
        container = emptyContainer
        sm = container.sm
        allItemLocs,progItemLocs,split = escapeTrigger[0],escapeTrigger[1],escapeTrigger[2]
        # check if crateria is connected, if not replace Tourian
        # connection with Climb and add special escape patch to Climb
        if not any(il.Location.GraphArea == "Crateria" for il in allItemLocs):
            escapeAttr = graph.EscapeAttributes
            if "patches" not in escapeAttr:
                escapeAttr['patches'] = []
            escapeAttr['patches'] += ['climb_disable_bomb_blocks.ips', "Climb_Asleep"]
            src, _ = next(t for t in graph.InterAreaTransitions if t[1].Name == "Golden Four")
            graph.removeTransitions("Golden Four")
            graph.addTransition(src.Name, "Climb Bottom Left")
            # disconnect the other side of G4
            graph.addTransition("Golden Four", "Golden Four")
        # remove vanilla escape transition
        graph.addTransition('Tourian Escape Room 4 Top Right', 'Tourian Escape Room 4 Top Right')
        # filter garbage itemLocs
        ilCheck = lambda il: not il.Location.isBoss() and not il.Location.restricted and il.Item.Category != "Nothing"
        # update item% objectives
        accessibleItems = [il.Item for il in allItemLocs if ilCheck(il)]
        majorUpgrades = [item.Type for item in accessibleItems if item.BeamBits != 0 or item.ItemBits != 0]
        sm.objectives.setItemPercentFuncs(len(accessibleItems), majorUpgrades)
        if split == "Scavenger":
            # update escape access for scav with last scav loc
            lastScavItemLoc = progItemLocs[-1]
            sm.objectives.updateScavengerEscapeAccess(lastScavItemLoc.Location.accessPoint)
            sm.objectives.setScavengerHuntFunc(lambda sm, ap: sm.haveItem(lastScavItemLoc.Item.Type))
        else:
            # update "collect all items in areas" funcs
            availLocsByArea=defaultdict(list)
            for itemLoc in allItemLocs:
                if ilCheck(itemLoc) and (split.startswith("Full") or itemLoc.Location.isClass(split)):
                    availLocsByArea[itemLoc.Location.GraphArea].append(itemLoc.Location.Name)
            self.log.debug("escapeTrigger. availLocsByArea="+str(availLocsByArea))
            sm.objectives.setAreaFuncs({area:lambda sm,ap:SMBool(len(container.getLocs(lambda loc: loc.Name in availLocsByArea[area]))==0) for area in availLocsByArea})
        self.log.debug("escapeTrigger. collect locs until G4 access")
        # collect all item/locations up until we can pass G4 (the escape triggers)
        itemLocs = allItemLocs[:]
        ap = "Landing Site" # dummy value it'll be overwritten at first collection
        while len(itemLocs) > 0 and not (sm.canPassG4() and graph.canAccess(sm, ap, "Landing Site", maxDiff)):
            il = itemLocs.pop(0)
            if il.Location.restricted:
                continue
            self.log.debug("collecting " + getItemLocStr(il))
            container.collect(il)
            ap = il.Location.accessPoint
        # final update of item% obj
        collectedLocsAccessPoints = {il.Location.accessPoint for il in container.itemLocations}
        sm.objectives.updateItemPercentEscapeAccess(list(collectedLocsAccessPoints))
        possibleTargets = self._getTargets(sm, graph, maxDiff)
        # try to escape from all the possible objectives APs
        possiblePaths = []
        for goal in Objectives.activeGoals:
            n, possibleAccessPoints = goal.escapeAccessPoints
            count = 0
            for ap in possibleAccessPoints:
                self.log.debug("escapeTrigger. testing AP " + ap)
                path = graph.accessPath(sm, ap, 'Landing Site', maxDiff)
                if path is not None:
                    self.log.debug("escapeTrigger. add path from "+ap)
                    possiblePaths.append(path)
                    count += 1
            if count < n:
                # there is a goal we cannot escape from
                self.log.debug("escapeTrigger. goal %s: found %d/%d possible escapes, abort" % (goal.name, count, n))
                return (None, None)
        # try and get a path from all possible areas
        self.log.debug("escapeTrigger. completing paths")
        allAreas = {il.Location.GraphArea for il in allItemLocs if not il.Location.restricted and not il.Location.GraphArea in ["Tourian", "Ceres"]}
        def getStartArea(path):
            return path[0].GraphArea
        def apCheck(ap):
            nonlocal graph, possiblePaths
            apObj = graph.accessPoints[ap]
            return apObj.GraphArea not in [getStartArea(path) for path in possiblePaths]
        escapeAPs = [ap for ap in collectedLocsAccessPoints if apCheck(ap)]
        for ap in escapeAPs:
            path = graph.accessPath(sm, ap, 'Landing Site', maxDiff)
            if path is not None:
                self.log.debug("escapeTrigger. add path from "+ap)
                possiblePaths.append(path)
        def areaPathCheck():
            nonlocal allAreas, possiblePaths
            startAreas = {getStartArea(path) for path in possiblePaths}
            return len(allAreas - startAreas) == 0
        while not areaPathCheck() and len(itemLocs) > 0:
            il = itemLocs.pop(0)
            if il.Location.restricted:
                continue
            self.log.debug("collecting " + getItemLocStr(il))
            container.collect(il)
            ap = il.Location.accessPoint
            if apCheck(ap):
                path = graph.accessPath(sm, ap, 'Landing Site', maxDiff)
                if path is not None:
                    self.log.debug("escapeTrigger. add path from "+ap)
                    possiblePaths.append(path)

        return (possibleTargets, possiblePaths)