115 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
		
			4.7 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): 
 | 
						|
        try: 
 | 
						|
            assert exit in exits
 | 
						|
            assert struct in structs
 | 
						|
        except AssertionError as e: 
 | 
						|
            raise Exception(f"Invalid connection: {exit} => {struct} for player {player}")
 | 
						|
        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.plando_connections[player]:
 | 
						|
        for connection in world.plando_connections[player]:
 | 
						|
            try:
 | 
						|
                if connection.entrance == 'The End Structure' and connection.exit == 'Nether Fortress': 
 | 
						|
                    raise Exception(f"Cannot place Nether Fortress in the End for player {player}")
 | 
						|
                set_pair(connection.entrance, connection.exit)
 | 
						|
            except Exception as e:
 | 
						|
                raise Exception(f"Could not connect using {connection}") from e
 | 
						|
 | 
						|
    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: # should only happen if structs is emptied by plando
 | 
						|
                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')
 | 
						|
}
 |