137 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			137 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								from .patches import enemies, bingo
							 | 
						||
| 
								 | 
							
								from .locations.items import *
							 | 
						||
| 
								 | 
							
								from .entranceInfo import ENTRANCE_INFO
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MULTI_CHEST_OPTIONS = [MAGIC_POWDER, BOMB, MEDICINE, RUPEES_50, RUPEES_20, RUPEES_100, RUPEES_200, RUPEES_500, SEASHELL, GEL, ARROWS_10, SINGLE_ARROW]
							 | 
						||
| 
								 | 
							
								MULTI_CHEST_WEIGHTS = [20,           20,   20,       50,        50,        20,         10,         5,          5,        20,  10,        10]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# List of all the possible locations where we can place our starting house
							 | 
						||
| 
								 | 
							
								start_locations = [
							 | 
						||
| 
								 | 
							
								    "phone_d8",
							 | 
						||
| 
								 | 
							
								    "rooster_house",
							 | 
						||
| 
								 | 
							
								    "writes_phone",
							 | 
						||
| 
								 | 
							
								    "castle_phone",
							 | 
						||
| 
								 | 
							
								    "photo_house",
							 | 
						||
| 
								 | 
							
								    "start_house",
							 | 
						||
| 
								 | 
							
								    "prairie_right_phone",
							 | 
						||
| 
								 | 
							
								    "banana_seller",
							 | 
						||
| 
								 | 
							
								    "prairie_low_phone",
							 | 
						||
| 
								 | 
							
								    "animal_phone",
							 | 
						||
| 
								 | 
							
								]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class WorldSetup:
							 | 
						||
| 
								 | 
							
								    def __init__(self):
							 | 
						||
| 
								 | 
							
								        self.entrance_mapping = {k: k for k in ENTRANCE_INFO.keys()}
							 | 
						||
| 
								 | 
							
								        self.boss_mapping = list(range(9))
							 | 
						||
| 
								 | 
							
								        self.miniboss_mapping = {
							 | 
						||
| 
								 | 
							
								            # Main minibosses
							 | 
						||
| 
								 | 
							
								            0: "ROLLING_BONES", 1: "HINOX", 2: "DODONGO", 3: "CUE_BALL", 4: "GHOMA", 5: "SMASHER", 6: "GRIM_CREEPER", 7: "BLAINO",
							 | 
						||
| 
								 | 
							
								            # Color dungeon needs to be special, as always.
							 | 
						||
| 
								 | 
							
								            "c1": "AVALAUNCH", "c2": "GIANT_BUZZ_BLOB",
							 | 
						||
| 
								 | 
							
								            # Overworld
							 | 
						||
| 
								 | 
							
								            "moblin_cave": "MOBLIN_KING",
							 | 
						||
| 
								 | 
							
								            "armos_temple": "ARMOS_KNIGHT",
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        self.goal = None
							 | 
						||
| 
								 | 
							
								        self.bingo_goals = None
							 | 
						||
| 
								 | 
							
								        self.multichest = RUPEES_20
							 | 
						||
| 
								 | 
							
								        self.map = None  # Randomly generated map data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def getEntrancePool(self, settings, connectorsOnly=False):
							 | 
						||
| 
								 | 
							
								        entrances = []
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if connectorsOnly:
							 | 
						||
| 
								 | 
							
								            if settings.entranceshuffle in ("advanced", "expert", "insanity"):
							 | 
						||
| 
								 | 
							
								                entrances = [k for k, v in ENTRANCE_INFO.items() if v.type == "connector"]
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            return entrances
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if settings.dungeonshuffle and settings.entranceshuffle == "none":
							 | 
						||
| 
								 | 
							
								            entrances = [k for k, v in ENTRANCE_INFO.items() if v.type == "dungeon"]
							 | 
						||
| 
								 | 
							
								        if settings.entranceshuffle in ("simple", "advanced", "expert", "insanity"):
							 | 
						||
| 
								 | 
							
								            types = {"single"}
							 | 
						||
| 
								 | 
							
								            if settings.tradequest:
							 | 
						||
| 
								 | 
							
								                types.add("trade")
							 | 
						||
| 
								 | 
							
								            if settings.entranceshuffle in ("expert", "insanity"):
							 | 
						||
| 
								 | 
							
								                types.update(["dummy", "trade"])
							 | 
						||
| 
								 | 
							
								            if settings.entranceshuffle in ("insanity",):
							 | 
						||
| 
								 | 
							
								                types.add("insanity")
							 | 
						||
| 
								 | 
							
								            if settings.randomstartlocation:
							 | 
						||
| 
								 | 
							
								                types.add("start")
							 | 
						||
| 
								 | 
							
								            if settings.dungeonshuffle:
							 | 
						||
| 
								 | 
							
								                types.add("dungeon")
							 | 
						||
| 
								 | 
							
								            entrances = [k for k, v in ENTRANCE_INFO.items() if v.type in types]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return entrances
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def randomize(self, settings, rnd):
							 | 
						||
| 
								 | 
							
								        if settings.overworld == "dungeondive":
							 | 
						||
| 
								 | 
							
								            self.entrance_mapping = {"d%d" % (n): "d%d" % (n) for n in range(9)}
							 | 
						||
| 
								 | 
							
								        if settings.randomstartlocation and settings.entranceshuffle == "none":
							 | 
						||
| 
								 | 
							
								            start_location = start_locations[rnd.randrange(len(start_locations))]
							 | 
						||
| 
								 | 
							
								            if start_location != "start_house":
							 | 
						||
| 
								 | 
							
								                self.entrance_mapping[start_location] = "start_house"
							 | 
						||
| 
								 | 
							
								                self.entrance_mapping["start_house"] = start_location
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        entrances = self.getEntrancePool(settings)
							 | 
						||
| 
								 | 
							
								        for entrance in entrances.copy():
							 | 
						||
| 
								 | 
							
								            self.entrance_mapping[entrance] = entrances.pop(rnd.randrange(len(entrances)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Shuffle connectors among themselves
							 | 
						||
| 
								 | 
							
								        entrances = self.getEntrancePool(settings, connectorsOnly=True)
							 | 
						||
| 
								 | 
							
								        for entrance in entrances.copy():
							 | 
						||
| 
								 | 
							
								            self.entrance_mapping[entrance] = entrances.pop(rnd.randrange(len(entrances)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if settings.boss != "default":
							 | 
						||
| 
								 | 
							
								            values = list(range(9))
							 | 
						||
| 
								 | 
							
								            if settings.heartcontainers:
							 | 
						||
| 
								 | 
							
								                # Color dungeon boss does not drop a heart container so we cannot shuffle him when we
							 | 
						||
| 
								 | 
							
								                # have heart container shuffling
							 | 
						||
| 
								 | 
							
								                values.remove(8)
							 | 
						||
| 
								 | 
							
								            self.boss_mapping = []
							 | 
						||
| 
								 | 
							
								            for n in range(8 if settings.heartcontainers else 9):
							 | 
						||
| 
								 | 
							
								                value = rnd.choice(values)
							 | 
						||
| 
								 | 
							
								                self.boss_mapping.append(value)
							 | 
						||
| 
								 | 
							
								                if value in (3, 6) or settings.boss == "shuffle":
							 | 
						||
| 
								 | 
							
								                    values.remove(value)
							 | 
						||
| 
								 | 
							
								            if settings.heartcontainers:
							 | 
						||
| 
								 | 
							
								                self.boss_mapping += [8]
							 | 
						||
| 
								 | 
							
								        if settings.miniboss != "default":
							 | 
						||
| 
								 | 
							
								            values = [name for name in self.miniboss_mapping.values()]
							 | 
						||
| 
								 | 
							
								            for key in self.miniboss_mapping.keys():
							 | 
						||
| 
								 | 
							
								                self.miniboss_mapping[key] = rnd.choice(values)
							 | 
						||
| 
								 | 
							
								                if settings.miniboss == 'shuffle':
							 | 
						||
| 
								 | 
							
								                    values.remove(self.miniboss_mapping[key])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if settings.goal == 'random':
							 | 
						||
| 
								 | 
							
								            self.goal = rnd.randint(-1, 8)
							 | 
						||
| 
								 | 
							
								        elif settings.goal == 'open':
							 | 
						||
| 
								 | 
							
								            self.goal = -1
							 | 
						||
| 
								 | 
							
								        elif settings.goal in {"seashells", "bingo", "bingo-full"}:
							 | 
						||
| 
								 | 
							
								            self.goal = settings.goal
							 | 
						||
| 
								 | 
							
								        elif "-" in settings.goal:
							 | 
						||
| 
								 | 
							
								            a, b = settings.goal.split("-")
							 | 
						||
| 
								 | 
							
								            if a == "open":
							 | 
						||
| 
								 | 
							
								                a = -1
							 | 
						||
| 
								 | 
							
								            self.goal = rnd.randint(int(a), int(b))
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            self.goal = int(settings.goal)
							 | 
						||
| 
								 | 
							
								        if self.goal in {"bingo", "bingo-full"}:
							 | 
						||
| 
								 | 
							
								            self.bingo_goals = bingo.randomizeGoals(rnd, settings)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        self.multichest = rnd.choices(MULTI_CHEST_OPTIONS, MULTI_CHEST_WEIGHTS)[0]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def loadFromRom(self, rom):
							 | 
						||
| 
								 | 
							
								        import patches.overworld
							 | 
						||
| 
								 | 
							
								        if patches.overworld.isNormalOverworld(rom):
							 | 
						||
| 
								 | 
							
								            import patches.entrances
							 | 
						||
| 
								 | 
							
								            self.entrance_mapping = patches.entrances.readEntrances(rom)
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            self.entrance_mapping = {"d%d" % (n): "d%d" % (n) for n in range(9)}
							 | 
						||
| 
								 | 
							
								        self.boss_mapping = patches.enemies.readBossMapping(rom)
							 | 
						||
| 
								 | 
							
								        self.miniboss_mapping = patches.enemies.readMiniBossMapping(rom)
							 | 
						||
| 
								 | 
							
								        self.goal = 8 # Better then nothing
							 |