95 lines
4.2 KiB
Python
95 lines
4.2 KiB
Python
import sys, random, time
|
|
|
|
from ..utils import log
|
|
from ..logic.logic import Logic
|
|
from ..graph.graph_utils import GraphUtils, getAccessPoint
|
|
from ..rando.Restrictions import Restrictions
|
|
from ..rando.RandoServices import RandoServices
|
|
from ..rando.GraphBuilder import GraphBuilder
|
|
from ..rando.RandoSetup import RandoSetup
|
|
from ..rando.Items import ItemManager
|
|
from ..rando.ItemLocContainer import ItemLocation
|
|
from ..utils.vcr import VCR
|
|
from ..utils.doorsmanager import DoorsManager
|
|
|
|
# entry point for rando execution ("randomize" method)
|
|
class RandoExec(object):
|
|
def __init__(self, seedName, vcr, randoSettings, graphSettings, player):
|
|
self.errorMsg = ""
|
|
self.seedName = seedName
|
|
self.vcr = vcr
|
|
self.randoSettings = randoSettings
|
|
self.graphSettings = graphSettings
|
|
self.log = log.get('RandoExec')
|
|
self.player = player
|
|
|
|
# processes settings to :
|
|
# - create Restrictions and GraphBuilder objects
|
|
# - create graph and item loc container using a RandoSetup instance: in area rando, if it fails, iterate on possible graph layouts
|
|
# return container
|
|
def randomize(self):
|
|
vcr = VCR(self.seedName, 'rando') if self.vcr == True else None
|
|
self.errorMsg = ""
|
|
split = self.randoSettings.restrictions['MajorMinor']
|
|
graphBuilder = GraphBuilder(self.graphSettings)
|
|
container = None
|
|
i = 0
|
|
attempts = 500 if self.graphSettings.areaRando or self.graphSettings.doorsColorsRando or split == 'Scavenger' else 1
|
|
now = time.process_time()
|
|
endDate = sys.maxsize
|
|
if self.randoSettings.runtimeLimit_s < endDate:
|
|
endDate = now + self.randoSettings.runtimeLimit_s
|
|
self.updateLocationsClass(split)
|
|
while container is None and i < attempts and now <= endDate:
|
|
self.restrictions = Restrictions(self.randoSettings)
|
|
if self.graphSettings.doorsColorsRando == True:
|
|
DoorsManager.randomize(self.graphSettings.allowGreyDoors, self.player)
|
|
self.areaGraph = graphBuilder.createGraph()
|
|
services = RandoServices(self.areaGraph, self.restrictions)
|
|
setup = RandoSetup(self.graphSettings, Logic.locations, services, self.player)
|
|
self.setup = setup
|
|
container = setup.createItemLocContainer(endDate, vcr)
|
|
if container is None:
|
|
sys.stdout.write('*')
|
|
sys.stdout.flush()
|
|
i += 1
|
|
else:
|
|
self.errorMsg += '\n'.join(setup.errorMsgs)
|
|
now = time.process_time()
|
|
if container is None:
|
|
if self.graphSettings.areaRando:
|
|
self.errorMsg += "Could not find an area layout with these settings"
|
|
else:
|
|
self.errorMsg += "Unable to process settings"
|
|
self.areaGraph.printGraph()
|
|
return container
|
|
|
|
def updateLocationsClass(self, split):
|
|
if split != 'Full' and split != 'Scavenger':
|
|
startAP = getAccessPoint(self.graphSettings.startAP)
|
|
possibleMajLocs, preserveMajLocs, nMaj, nChozo = Logic.LocationsHelper.getStartMajors(startAP.Name)
|
|
if split == 'Major':
|
|
n = nMaj
|
|
elif split == 'Chozo':
|
|
n = nChozo
|
|
GraphUtils.updateLocClassesStart(startAP.GraphArea, split, possibleMajLocs, preserveMajLocs, n)
|
|
|
|
def postProcessItemLocs(self, itemLocs, hide):
|
|
# hide some items like in dessy's
|
|
if hide == True:
|
|
for itemLoc in itemLocs:
|
|
item = itemLoc.Item
|
|
loc = itemLoc.Location
|
|
if (item.Category != "Nothing"
|
|
and loc.CanHidden == True
|
|
and loc.Visibility == 'Visible'):
|
|
if bool(random.getrandbits(1)) == True:
|
|
loc.Visibility = 'Hidden'
|
|
# put nothing in unfilled locations
|
|
filledLocNames = [il.Location.Name for il in itemLocs]
|
|
unfilledLocs = [loc for loc in Logic.locations if loc.Name not in filledLocNames]
|
|
nothing = ItemManager.getItem('Nothing')
|
|
for loc in unfilledLocs:
|
|
loc.restricted = True
|
|
itemLocs.append(ItemLocation(nothing, loc, False))
|