def setUp(self): self.world = MultiWorld(1) args = Namespace() for name, option in AutoWorld.AutoWorldRegister.world_types[ "A Link to the Past"].options.items(): setattr(args, name, {1: option.from_any(option.default)}) self.world.set_options(args) self.world.set_default_common_options() self.world.logic[1] = "owglitches" self.world.mode[1] = "inverted" self.world.difficulty_requirements[1] = difficulties['normal'] create_inverted_regions(self.world, 1) create_dungeons(self.world, 1) create_shops(self.world, 1) link_inverted_entrances(self.world, 1) self.world.worlds[1].create_items() self.world.required_medallions[1] = ['Ether', 'Quake'] self.world.itempool.extend(get_dungeon_item_pool(self.world)) self.world.itempool.extend( ItemFactory([ 'Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7' ], 1)) self.world.get_location('Agahnim 1', 1).item = None self.world.get_location('Agahnim 2', 1).item = None self.world.precollected_items[1].clear() self.world.itempool.append(ItemFactory('Pegasus Boots', 1)) mark_light_world_regions(self.world, 1) self.world.worlds[1].set_rules()
def set_rules(world: MultiWorld, player: int): for i in range(1, 16): set_rule( world.get_location( f"IDLE for at least {int(i / 2)} minutes {30 if (i % 2) > 0 else 0} seconds", player), lambda state: state._archipidle_location_is_accessible(player, 0)) for i in range(16, 31): set_rule( world.get_location( f"IDLE for at least {int(i / 2)} minutes {30 if (i % 2) > 0 else 0} seconds", player), lambda state: state._archipidle_location_is_accessible(player, 4)) for i in range(31, 51): set_rule( world.get_location( f"IDLE for at least {int(i / 2)} minutes {30 if (i % 2) > 0 else 0} seconds", player), lambda state: state._archipidle_location_is_accessible(player, 10)) for i in range(51, 101): set_rule( world.get_location( f"IDLE for at least {int(i / 2)} minutes {30 if (i % 2) > 0 else 0} seconds", player), lambda state: state._archipidle_location_is_accessible(player, 20))
def place_first_progression_item(world: MultiWorld, player: int, excluded_items: Set[str], locked_locations: List[str]): for item in world.precollected_items[player]: if item.name in starter_progression_items: return local_starter_progression_items = tuple( item for item in starter_progression_items if item not in world.non_local_items[player].value) non_excluded_starter_progression_locations = tuple( location for location in starter_progression_locations if location not in world.exclude_locations[player].value) if not local_starter_progression_items or not non_excluded_starter_progression_locations: return progression_item = world.random.choice(local_starter_progression_items) location = world.random.choice(non_excluded_starter_progression_locations) excluded_items.add(progression_item) locked_locations.append(location) item = create_item_with_correct_settings(world, player, progression_item) world.get_location(location, player).place_locked_item(item)
def set_mission_progress_rules(world: MultiWorld, player: int): for (k1, v1), (k2, v2), (k3, v3), (k4, v4), (k5, v5) in \ zip(sorted(first_mission_location_table.items()), sorted(second_mission_location_table.items()), sorted(third_mission_location_table.items()), sorted(fourth_mission_location_table.items()), sorted(fifth_mission_location_table.items())): if world.include_missions[player].value >= 2: set_rule( world.get_location(k2, player), lambda state, k1=k1: state.can_reach(k1, "Location", player)) if world.include_missions[player].value >= 3: set_rule( world.get_location(k3, player), lambda state, k2=k2: state.can_reach(k2, "Location", player)) if world.include_missions[player].value >= 4: set_rule( world.get_location(k4, player), lambda state, k3=k3: state.can_reach(k3, "Location", player)) if world.include_missions[player].value >= 5: set_rule( world.get_location(k5, player), lambda state, k4=k4: state.can_reach(k4, "Location", player))
def set_completion_rules(world: MultiWorld, player: int): def reachable_locations(state): postgame_advancements = get_postgame_advancements( world.required_bosses[player].current_key) return [ location for location in world.get_locations() if location.player == player and location.name not in postgame_advancements and location.address != None and location.can_reach(state) ] def defeated_required_bosses(state): return (world.required_bosses[player].current_key not in {"ender_dragon", "both"} or state.has("Defeat Ender Dragon", player)) and \ (world.required_bosses[player].current_key not in {"wither", "both"} or state.has("Defeat Wither", player)) # 103 total advancements. Goal is to complete X advancements and then defeat the dragon. # There are 11 possible postgame advancements; 5 for dragon, 5 for wither, 1 shared between them # Hence the max for completion is 92 egg_shards = min(world.egg_shards_required[player], world.egg_shards_available[player]) completion_requirements = lambda state: len(reachable_locations(state)) >= world.advancement_goal[player] and \ state.has("Dragon Egg Shard", player, egg_shards) world.completion_condition[player] = lambda state: completion_requirements( state) and defeated_required_bosses(state) # Set rules on postgame advancements for adv_name in get_postgame_advancements( world.required_bosses[player].current_key): add_rule(world.get_location(adv_name, player), completion_requirements)
def setUp(self): self.world = MultiWorld(1) args = Namespace() for name, option in AutoWorld.AutoWorldRegister.world_types[ "A Link to the Past"].options.items(): setattr(args, name, {1: option.from_any(option.default)}) self.world.set_options(args) self.world.set_default_common_options() self.starting_regions = [] # Where to start exploring self.remove_exits = [] # Block dungeon exits self.world.difficulty_requirements[1] = difficulties['normal'] create_regions(self.world, 1) create_dungeons(self.world, 1) create_shops(self.world, 1) for exitname, regionname in mandatory_connections: connect_simple(self.world, exitname, regionname, 1) connect_simple(self.world, 'Big Bomb Shop', 'Big Bomb Shop', 1) self.world.get_region('Menu', 1).exits = [] self.world.swamp_patch_required[1] = True self.world.worlds[1].set_rules() self.world.worlds[1].create_items() self.world.itempool.extend(get_dungeon_item_pool(self.world)) self.world.itempool.extend( ItemFactory([ 'Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7' ], 1))
def fast_fill( world: MultiWorld, item_pool: typing.List[Item], fill_locations: typing.List[Location] ) -> typing.Tuple[typing.List[Item], typing.List[Location]]: placing = min(len(item_pool), len(fill_locations)) for item, location in zip(item_pool, fill_locations): world.push_item(location, item, False) return item_pool[placing:], fill_locations[placing:]
class TestInvertedBombRules(unittest.TestCase): def setUp(self): self.world = MultiWorld(1) self.world.mode[1] = "inverted" self.world.difficulty_requirements[1] = difficulties['normal'] create_inverted_regions(self.world, 1) create_dungeons(self.world, 1) #TODO: Just making sure I haven't missed an entrance. It would be good to test the rules make sense as well. def testInvertedBombRulesAreComplete(self): entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors + Inverted_Old_Man_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors) must_exits = list(Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit) for entrance_name in (entrances + must_exits): if entrance_name not in [ 'Desert Palace Entrance (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)' ]: entrance = self.world.get_entrance(entrance_name, 1) connect_entrance(self.world, entrance_name, 'Inverted Big Bomb Shop', 1) set_inverted_big_bomb_rules(self.world, 1) entrance.connected_region.entrances.remove(entrance) entrance.connected_region = None def testInvalidEntrancesAreNotUsed(self): entrances = list(Inverted_Blacksmith_Multi_Cave_Doors + Blacksmith_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors + Inverted_Bomb_Shop_Single_Cave_Doors) invalid_entrances = [ 'Desert Palace Entrance (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)', 'Pyramid Fairy' ] for invalid_entrance in invalid_entrances: self.assertNotIn(invalid_entrance, entrances) def testInvalidEntrances(self): for entrance_name in [ 'Desert Palace Entrance (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)' ]: entrance = self.world.get_entrance(entrance_name, 1) connect_entrance(self.world, entrance_name, 'Inverted Big Bomb Shop', 1) with self.assertRaises(Exception): set_inverted_big_bomb_rules(self.world, 1) entrance.connected_region.entrances.remove(entrance) entrance.connected_region = None
def flood_items(world: MultiWorld) -> None: # get items to distribute world.random.shuffle(world.itempool) itempool = world.itempool progress_done = False # sweep once to pick up preplaced items world.state.sweep_for_events() # fill world from top of itempool while we can while not progress_done: location_list = world.get_unfilled_locations() world.random.shuffle(location_list) spot_to_fill = None for location in location_list: if location.can_fill(world.state, itempool[0]): spot_to_fill = location break if spot_to_fill: item = itempool.pop(0) world.push_item(spot_to_fill, item, True) continue # ran out of spots, check if we need to step in and correct things if len(world.get_reachable_locations()) == len(world.get_locations()): progress_done = True continue # need to place a progress item instead of an already placed item, find candidate item_to_place = None candidate_item_to_place = None for item in itempool: if item.advancement: candidate_item_to_place = item if world.unlocks_new_location(item): item_to_place = item break # we might be in a situation where all new locations require multiple items to reach. # If that is the case, just place any advancement item we've found and continue trying if item_to_place is None: if candidate_item_to_place is not None: item_to_place = candidate_item_to_place else: raise FillError('No more progress items left to place.') # find item to replace with progress item location_list = world.get_reachable_locations() world.random.shuffle(location_list) for location in location_list: if location.item is not None and not location.item.advancement: # safe to replace replace_item = location.item replace_item.location = None itempool.append(replace_item) world.push_item(location, item_to_place, True) itempool.remove(item_to_place) break
def setUp(self): self.world = MultiWorld(1) self.world.mode[1] = "inverted" args = Namespace for name, option in AutoWorld.AutoWorldRegister.world_types[ "A Link to the Past"].options.items(): setattr(args, name, {1: option.from_any(option.default)}) self.world.set_options(args) self.world.set_default_common_options() self.world.difficulty_requirements[1] = difficulties['normal'] create_inverted_regions(self.world, 1) create_dungeons(self.world, 1)
def assign_starter_item(world: MultiWorld, player: int, excluded_items: Set[str], locked_locations: List[str], location: str, item_list: Tuple[str, ...]): item_name = world.random.choice(item_list) excluded_items.add(item_name) item = create_item_with_correct_settings(world, player, item_name) world.get_location(location, player).place_locked_item(item) locked_locations.append(location)
def create_events(world: MultiWorld, player: int, total_locations: int): num_of_events = total_locations // 25 if total_locations / 25 == num_of_events: num_of_events -= 1 for i in range(num_of_events): event_loc = RiskOfRainLocation(player, f"Pickup{(i + 1) * 25}", None, world.get_region('Petrichor V', player)) event_loc.place_locked_item( RiskOfRainItem(f"Pickup{(i + 1) * 25}", ItemClassification.progression, None, player)) event_loc.access_rule(lambda state, i=i: state.can_reach( f"ItemPickup{((i + 1) * 25) - 1}", player)) world.get_region('Petrichor V', player).locations.append(event_loc)
def setup_default_world(world_type) -> MultiWorld: world = MultiWorld(1) world.game[1] = world_type.game world.player_name = {1: "Tester"} world.set_seed() args = Namespace() for name, option in world_type.options.items(): setattr(args, name, {1: option.from_any(option.default)}) world.set_options(args) world.set_default_common_options() for step in gen_steps: call_all(world, step) return world
def fillRegion(world: MultiWorld, region: Region, items: List[Item]) -> List[Item]: items = items.copy() while len(items) > 0: location = region.locations.pop(0) region.locations.append(location) if location.item: return items item = items.pop(0) world.push_item(location, item, False) location.event = item.advancement return items
def adjust(args): # Create a fake world and OOTWorld to use as a base world = MultiWorld(1) world.slot_seeds = {1: random} ootworld = OOTWorld(world, 1) # Set options in the fake OOTWorld for name, option in chain(cosmetic_options.items(), sfx_options.items()): result = getattr(args, name, None) if result is None: if issubclass(option, Choice): result = option.name_lookup[option.default] elif issubclass(option, Range) or issubclass(option, Toggle): result = option.default else: raise Exception("Unsupported option type") setattr(ootworld, name, result) ootworld.logic_rules = 'glitched' if args.is_glitched else 'glitchless' ootworld.death_link = args.deathlink delete_zootdec = False if os.path.splitext(args.rom)[-1] in ['.z64', '.n64']: # Load up the ROM rom = Rom(file=args.rom, force_use=True) delete_zootdec = True elif os.path.splitext(args.rom)[-1] == '.apz5': # Load vanilla ROM rom = Rom(file=args.vanilla_rom, force_use=True) # Patch file apply_patch_file(rom, args.rom) else: raise Exception("Invalid file extension; requires .n64, .z64, .apz5") # Call patch_cosmetics try: patch_cosmetics(ootworld, rom) rom.write_byte(rom.sym('DEATH_LINK'), args.deathlink) # Output new file path_pieces = os.path.splitext(args.rom) decomp_path = path_pieces[0] + '-adjusted-decomp.n64' comp_path = path_pieces[0] + '-adjusted.n64' rom.write_to_file(decomp_path) os.chdir(data_path("Compress")) compress_rom_file(decomp_path, comp_path) os.remove(decomp_path) finally: if delete_zootdec: os.chdir(os.path.split(__file__)[0]) os.remove("ZOOTDEC.z64") return comp_path
class TestInvertedOWG(TestBase): def setUp(self): self.world = MultiWorld(1) self.world.logic[1] = "owglitches" self.world.mode[1] = "inverted" self.world.difficulty_requirements[1] = difficulties['normal'] create_inverted_regions(self.world, 1) create_dungeons(self.world, 1) create_shops(self.world, 1) link_inverted_entrances(self.world, 1) generate_itempool(self.world, 1) self.world.required_medallions[1] = ['Ether', 'Quake'] self.world.itempool.extend(get_dungeon_item_pool(self.world)) self.world.itempool.extend( ItemFactory([ 'Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7' ], 1)) self.world.get_location('Agahnim 1', 1).item = None self.world.get_location('Agahnim 2', 1).item = None self.world.precollected_items.clear() self.world.itempool.append(ItemFactory('Pegasus Boots', 1)) mark_light_world_regions(self.world, 1) set_rules(self.world, 1)
def get_same_seed(world: MultiWorld, seed_def: tuple) -> str: seeds: Dict[tuple, str] = getattr(world, "__named_seeds", {}) if seed_def in seeds: return seeds[seed_def] seeds[seed_def] = str(world.random.randint(0, 2**64)) world.__named_seeds = seeds return seeds[seed_def]
def set_boss_gate_rules(world: MultiWorld, player: int, gate_bosses: typing.Dict[int, int]): for x in range(len(gate_bosses)): if boss_has_requirement(gate_bosses[x + 1]): add_rule( world.get_location(boss_gate_set[x], player), lambda state: state.has( ItemName.knuckles_shovel_claws, player))
def generate_multi_world(players: int = 1) -> MultiWorld: multi_world = MultiWorld(players) multi_world.player_name = {} for i in range(players): player_id = i + 1 world = World(multi_world, player_id) multi_world.game[player_id] = world multi_world.worlds[player_id] = world multi_world.player_name[player_id] = "Test Player " + str(player_id) region = Region("Menu", RegionType.Generic, "Menu Region Hint", player_id, multi_world) multi_world.regions.append(region) multi_world.set_seed(0) multi_world.set_default_common_options() return multi_world
def setUp(self): self.world = MultiWorld(1) self.world.game[1] = "Hollow Knight" import Options for hk_option in Options.hollow_knight_randomize_options: getattr(self.world, hk_option)[1] = True create_regions(self.world, 1) gen_hollow(self.world, 1)
def setUp(self): self.world = MultiWorld(1) self.starting_regions = [] # Where to start exploring self.remove_exits = [] # Block dungeon exits self.world.difficulty_requirements[1] = difficulties['normal'] create_regions(self.world, 1) create_dungeons(self.world, 1) create_shops(self.world, 1) for exitname, regionname in mandatory_connections: connect_simple(self.world, exitname, regionname, 1) connect_simple(self.world, 'Big Bomb Shop', 'Big Bomb Shop', 1) self.world.get_region('Menu', 1).exits = [] self.world.swamp_patch_required[1] = True set_rules(self.world, 1) generate_itempool(self.world, 1) self.world.itempool.extend(get_dungeon_item_pool(self.world)) self.world.itempool.extend(ItemFactory(['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'], 1))
def set_rules(world: MultiWorld, player: int): shapes = get_shapes(world, player) if world.logic[player] != 'nologic': from worlds.generic import Rules allowed_packs = world.max_science_pack[player].get_allowed_packs() for tech_name, technology in technology_table.items(): # loose nodes location = world.get_location(tech_name, player) Rules.set_rule(location, technology.build_rule(allowed_packs, player)) prequisites = shapes.get(tech_name) if prequisites: locations = {world.get_location(requisite, player) for requisite in prequisites} Rules.add_rule(location, lambda state, locations=locations: all(state.can_reach(loc) for loc in locations)) # get all technologies world.completion_condition[player] = lambda state: all(state.has(technology, player) for technology in advancement_technologies)
def connect_regions(world: MultiWorld, player: int, source: str, target: str, rule): sourceRegion = world.get_region(source, player) targetRegion = world.get_region(target, player) connection = Entrance(player,'', sourceRegion) connection.access_rule = rule sourceRegion.exits.append(connection) connection.connect(targetRegion)
def generate_mod(world: MultiWorld, player: int, seedname: str): global template, locale_template with template_load_lock: if not template: mod_template_folder = Utils.local_path("data", "factorio", "mod_template") template = jinja2.Template(open(os.path.join(mod_template_folder, "data-final-fixes.lua")).read()) locale_template = jinja2.Template(open(os.path.join(mod_template_folder, "locale", "en", "locale.cfg")).read()) control_template = jinja2.Template(open(os.path.join(mod_template_folder, "control.lua")).read()) # get data for templates player_names = {x: world.player_names[x][0] for x in world.player_ids} locations = [] for location in world.get_filled_locations(player): if not location.name.startswith("recipe-"): # introduce this as a new location property? locations.append((location.name, location.item.name, location.item.player)) mod_name = f"archipelago-client-{seedname}-{player}" tech_cost = {0: 0.1, 1: 0.25, 2: 0.5, 3: 1, 4: 2, 5: 5, 6: 10}[world.tech_cost[player].value] template_data = {"locations": locations, "player_names" : player_names, "tech_table": tech_table, "mod_name": mod_name, "allowed_science_packs": world.max_science_pack[player].get_allowed_packs(), "tech_cost_scale": tech_cost, "tech_tree_layout_prerequisites": world.tech_tree_layout_prerequisites[player]} for factorio_option in Options.factorio_options: template_data[factorio_option] = getattr(world, factorio_option)[player].value control_code = control_template.render(**template_data) data_final_fixes_code = template.render(**template_data) mod_dir = Utils.output_path(mod_name)+"_"+Utils.__version__ en_locale_dir = os.path.join(mod_dir, "locale", "en") os.makedirs(en_locale_dir, exist_ok=True) shutil.copytree(Utils.local_path("data", "factorio", "mod"), mod_dir, dirs_exist_ok=True) with open(os.path.join(mod_dir, "data-final-fixes.lua"), "wt") as f: f.write(data_final_fixes_code) with open(os.path.join(mod_dir, "control.lua"), "wt") as f: f.write(control_code) locale_content = locale_template.render(**template_data) with open(os.path.join(en_locale_dir, "locale.cfg"), "wt") as f: f.write(locale_content) info = base_info.copy() info["name"] = mod_name with open(os.path.join(mod_dir, "info.json"), "wt") as f: json.dump(info, f, indent=4) # zip the result zf_path = os.path.join(mod_dir+".zip") with zipfile.ZipFile(zf_path, compression=zipfile.ZIP_DEFLATED, mode='w') as zf: for root, dirs, files in os.walk(mod_dir): for file in files: zf.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), os.path.join(mod_dir, '..'))) shutil.rmtree(mod_dir)
def stage_write_spoiler(cls, world: MultiWorld, spoiler_handle): hk_players = world.get_game_players(cls.game) spoiler_handle.write('\n\nCharm Notches:') for player in hk_players: name = world.get_player_name(player) spoiler_handle.write(f'\n{name}\n') hk_world: HKWorld = world.worlds[player] for charm_number, cost in enumerate(hk_world.charm_costs): spoiler_handle.write(f"\n{charm_names[charm_number]}: {cost}") spoiler_handle.write('\n\nShop Prices:') for player in hk_players: name = world.get_player_name(player) spoiler_handle.write(f'\n{name}\n') hk_world: HKWorld = world.worlds[player] for shop_name, unit_name in cls.shops.items(): for x in range(1, hk_world.created_multi_locations[shop_name]+1): loc = world.get_location(hk_world.get_multi_location_name(shop_name, x), player) spoiler_handle.write(f"\n{loc}: {loc.item} costing {loc.cost} {unit_name}")
def set_completion_rules(world: MultiWorld, player: int): width_req = 10-5 height_req = 10-5 bomb_req = 20-5 completion_requirements = lambda state: \ state.has("Map Width", player, width_req) and \ state.has("Map Height", player, height_req) and \ state.has("Map Bombs", player, bomb_req) world.completion_condition[player] = lambda state: completion_requirements(state)
def set_rules(world: MultiWorld, player: int): set_rule(world.get_location(("Tile 6"), player), lambda state: state._has_total(player, 1)) set_rule(world.get_location(("Tile 7"), player), lambda state: state._has_total(player, 2)) set_rule(world.get_location(("Tile 8"), player), lambda state: state._has_total(player, 3)) set_rule(world.get_location(("Tile 9"), player), lambda state: state._has_total(player, 4)) set_rule(world.get_location(("Tile 10"), player), lambda state: state._has_total(player, 5)) set_rule(world.get_location(("Tile 11"), player), lambda state: state._has_total(player, 6)) set_rule(world.get_location(("Tile 12"), player), lambda state: state._has_total(player, 7)) set_rule(world.get_location(("Tile 13"), player), lambda state: state._has_total(player, 8)) set_rule(world.get_location(("Tile 14"), player), lambda state: state._has_total(player, 9)) set_rule(world.get_location(("Tile 15"), player), lambda state: state._has_total(player, 10)) set_rule(world.get_location(("Tile 16"), player), lambda state: state._has_total(player, 11)) set_rule(world.get_location(("Tile 17"), player), lambda state: state._has_total(player, 12)) set_rule(world.get_location(("Tile 18"), player), lambda state: state._has_total(player, 13)) set_rule(world.get_location(("Tile 19"), player), lambda state: state._has_total(player, 14)) set_rule(world.get_location(("Tile 20"), player), lambda state: state._has_total(player, 15)) set_rule(world.get_location(("Tile 21"), player), lambda state: state._has_total(player, 16)) set_rule(world.get_location(("Tile 22"), player), lambda state: state._has_total(player, 17)) set_rule(world.get_location(("Tile 23"), player), lambda state: state._has_total(player, 18)) set_rule(world.get_location(("Tile 24"), player), lambda state: state._has_total(player, 19)) set_rule(world.get_location(("Tile 25"), player), lambda state: state._has_total(player, 20))
def setUp(self): self.world = MultiWorld(1) self.world.logic[1] = "minorglitches" self.world.difficulty_requirements[1] = difficulties['normal'] create_regions(self.world, 1) create_dungeons(self.world, 1) create_shops(self.world, 1) link_entrances(self.world, 1) generate_itempool(self.world, 1) self.world.required_medallions[1] = ['Ether', 'Quake'] self.world.itempool.extend(get_dungeon_item_pool(self.world)) self.world.itempool.extend( ItemFactory([ 'Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7' ], 1)) self.world.get_location('Agahnim 1', 1).item = None self.world.get_location('Agahnim 2', 1).item = None mark_dark_world_regions(self.world, 1) set_rules(self.world, 1)
def set_rules(world: MultiWorld, player: int, player_logic: WitnessPlayerLogic, locat: WitnessPlayerLocations): """ Sets all rules for all locations """ for location in locat.CHECK_LOCATION_TABLE: real_location = location if location in locat.EVENT_LOCATION_TABLE: real_location = location[:-7] panel = StaticWitnessLogic.CHECKS_BY_NAME[real_location] check_hex = panel["checkHex"] rule = make_lambda(check_hex, world, player, player_logic, locat) set_rule(world.get_location(location, player), rule) world.completion_condition[player] = \ lambda state: state.has('Victory', player)
def gen_factorio(world: MultiWorld, player: int): static_nodes = world._static_nodes = {"automation", "logistics"} # turn dynamic/option? for tech_name, tech_id in tech_table.items(): tech_item = Item(tech_name, tech_name in advancement_technologies, tech_id, player) tech_item.game = "Factorio" if tech_name in static_nodes: loc = world.get_location(tech_name, player) loc.item = tech_item loc.locked = True loc.event = tech_item.advancement else: world.itempool.append(tech_item) set_rules(world, player)