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 |