102 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
	
| from .Locations import MinecraftAdvancement, advancement_table
 | |
| 
 | |
| from BaseClasses import Region, Entrance, Location, MultiWorld, Item
 | |
| 
 | |
| def minecraft_create_regions(world: MultiWorld, player: int):
 | |
| 
 | |
|     def MCRegion(region_name: str, exits=[]):
 | |
|         ret = Region(region_name, None, region_name, player)
 | |
|         ret.world = world
 | |
|         ret.locations = [ MinecraftAdvancement(player, loc_name, loc_data.id, ret) 
 | |
|             for loc_name, loc_data in advancement_table.items() 
 | |
|             if loc_data.region == region_name ]
 | |
|         for exit in exits: 
 | |
|             ret.exits.append(Entrance(player, exit, ret))
 | |
|         return ret
 | |
| 
 | |
|     world.regions += [MCRegion(*r) for r in mc_regions]
 | |
| 
 | |
|     for (exit, region) in mandatory_connections:
 | |
|         world.get_entrance(exit, player).connect(world.get_region(region, player))
 | |
| 
 | |
| def link_minecraft_structures(world: MultiWorld, player: int):
 | |
| 
 | |
|     # Get all unpaired exits and all regions without entrances (except the Menu)
 | |
|     # This function is destructive on these lists. 
 | |
|     exits = [exit.name for r in world.regions if r.player == player for exit in r.exits if exit.connected_region == None]
 | |
|     structs = [r.name for r in world.regions if r.player == player and r.entrances == [] and r.name != 'Menu']
 | |
|     try: 
 | |
|         assert len(exits) == len(structs)
 | |
|     except AssertionError as e: # this should never happen
 | |
|         raise Exception(f"Could not obtain equal numbers of Minecraft exits and structures for player {player}") from e
 | |
|     num_regions = len(exits)
 | |
|     pairs = {}
 | |
| 
 | |
|     def check_valid_connection(exit, struct): 
 | |
|         if (exit in exits) and (struct in structs) and (exit not in pairs): 
 | |
|             return True
 | |
|         return False
 | |
| 
 | |
|     def set_pair(exit, struct): 
 | |
|         pairs[exit] = struct
 | |
|         exits.remove(exit)
 | |
|         structs.remove(struct)
 | |
| 
 | |
|     # Plando stuff. Remove any utilized exits/structs from the lists. 
 | |
|     # Raise error if trying to put Nether Fortress in the End. 
 | |
| 
 | |
|     if world.shuffle_structures[player]: 
 | |
|         # Can't put Nether Fortress in the End
 | |
|         if 'The End Structure' in exits and 'Nether Fortress' in structs: 
 | |
|             try: 
 | |
|                 end_struct = world.random.choice([s for s in structs if s != 'Nether Fortress'])
 | |
|                 set_pair('The End Structure', end_struct)
 | |
|             except IndexError as e: 
 | |
|                 raise Exception(f"Plando forced Nether Fortress in the End for player {player}") from e
 | |
|         world.random.shuffle(structs)
 | |
|         for exit, struct in zip(exits[:], structs[:]): 
 | |
|             set_pair(exit, struct)
 | |
|     else: # write remaining default connections
 | |
|         for (exit, struct) in default_connections: 
 | |
|             if exit in exits: 
 | |
|                 set_pair(exit, struct)
 | |
| 
 | |
|     # Make sure we actually paired everything; might fail if plando
 | |
|     try:
 | |
|         assert len(exits) == len(structs) == 0
 | |
|     except AssertionError as e: 
 | |
|         raise Exception(f"Failed to connect all Minecraft structures for player {player}; check plando settings in yaml") from e
 | |
| 
 | |
|     for exit, struct in pairs.items():
 | |
|         world.get_entrance(exit, player).connect(world.get_region(struct, player))
 | |
|         if world.shuffle_structures[player]:
 | |
|             world.spoiler.set_entrance(exit, struct, 'entrance', player)
 | |
| 
 | |
| # (Region name, list of exits)
 | |
| mc_regions = [
 | |
|     ('Menu', ['New World']),
 | |
|     ('Overworld', ['Nether Portal', 'End Portal', 'Overworld Structure 1', 'Overworld Structure 2']),
 | |
|     ('The Nether', ['Nether Structure 1', 'Nether Structure 2']),
 | |
|     ('The End', ['The End Structure']),
 | |
|     ('Village', []),
 | |
|     ('Pillager Outpost', []),
 | |
|     ('Nether Fortress', []),
 | |
|     ('Bastion Remnant', []),
 | |
|     ('End City', [])
 | |
| ]
 | |
| 
 | |
| # (Entrance, region pointed to)
 | |
| mandatory_connections = [
 | |
|     ('New World', 'Overworld'),
 | |
|     ('Nether Portal', 'The Nether'),
 | |
|     ('End Portal', 'The End')
 | |
| ]
 | |
| 
 | |
| default_connections = {
 | |
|     ('Overworld Structure 1', 'Village'),
 | |
|     ('Overworld Structure 2', 'Pillager Outpost'),
 | |
|     ('Nether Structure 1', 'Nether Fortress'),
 | |
|     ('Nether Structure 2', 'Bastion Remnant'),
 | |
|     ('The End Structure', 'End City')
 | |
| }
 |