From 878185173ea8d66056f1b5047d8e2ed562d8bb91 Mon Sep 17 00:00:00 2001 From: Carter Hesterman Date: Tue, 6 Aug 2024 15:33:24 -0600 Subject: [PATCH] Cleanup Rules and Region --- worlds/civ_6/Regions.py | 47 +++++++++++++++++----------------------- worlds/civ_6/Rules.py | 31 +++++++++++++------------- worlds/civ_6/__init__.py | 2 +- 3 files changed, 36 insertions(+), 44 deletions(-) diff --git a/worlds/civ_6/Regions.py b/worlds/civ_6/Regions.py index c5eec18083..49a3fd9dbc 100644 --- a/worlds/civ_6/Regions.py +++ b/worlds/civ_6/Regions.py @@ -12,13 +12,6 @@ if TYPE_CHECKING: from Items import CivVIItemData -def get_required_items_for_era(era: EraType): - """Gets the specific techs/civics that are required for the specified era""" - era_required_items = {} - era_required_items = get_era_required_items_data() - return era_required_items[era.value] - - def get_cumulative_prereqs_for_era(end_era: EraType, exclude_progressive_items: bool = True, item_table: Dict[str, 'CivVIItemData'] = None) -> List['CivVIItemData']: """Gets the specific techs/civics that are required for the specified era as well as all previous eras""" cumulative_prereqs = [] @@ -44,7 +37,7 @@ def get_cumulative_prereqs_for_era(end_era: EraType, exclude_progressive_items: return [get_item_by_civ_name(prereq, item_table) for prereq in cumulative_prereqs] -def has_required_progressive_districts(state: CollectionState, era: EraType, player: int): +def has_required_progressive_districts(state: CollectionState, era: EraType, player: int) -> bool: """ If player has progressive items enabled, it will count how many progressive techs it should have, otherwise return the default array""" progressive_districts = get_progressive_districts_data() @@ -73,7 +66,7 @@ def has_required_progressive_districts(state: CollectionState, era: EraType, pla return True -def has_required_progressive_eras(state: CollectionState, era: EraType, player: int): +def has_required_progressive_eras(state: CollectionState, era: EraType, player: int) -> bool: """Checks, for the given era, how many are required to proceed to the next era. Ancient = 1, Classical = 2, etc. Assumes 2 required for classical and starts from there so as to decrease odds of hard locking without the turns to get the items""" if era == EraType.ERA_FUTURE or era == EraType.ERA_INFORMATION: return True @@ -83,19 +76,21 @@ def has_required_progressive_eras(state: CollectionState, era: EraType, player: return state.has(format_item_name("PROGRESSIVE_ERA"), player, era_index + 2) -def has_required_items(state: CollectionState, era: EraType, player: int, has_progressive_districts: bool, has_progressive_eras: bool): - required_items = False - required_eras = False +def has_required_items(state: CollectionState, era: EraType, world: 'CivVIWorld') -> bool: + player = world.player + has_progressive_districts = world.options.progression_style != "none" + has_progressive_eras = world.options.progression_style == "eras_and_districts" + if has_progressive_districts: required_items = has_required_progressive_districts(state, era, player) else: - era_required_items = [get_item_by_civ_name(item, state.multiworld.worlds[player].item_table).name for item in get_era_required_items_data()[era.value]] + era_required_items = [get_item_by_civ_name(item, world.item_table).name for item in get_era_required_items_data()[era.value]] required_items = state.has_all(era_required_items, player) - if has_progressive_eras: - required_eras = has_required_progressive_eras(state, era, player) - else: - required_eras = True + if not required_items: + return False + + required_eras = has_required_progressive_eras(state, era, player) if has_progressive_eras else True return required_items and required_eras @@ -104,7 +99,6 @@ def create_regions(world: 'CivVIWorld', options: CivVIOptions, player: int): menu = Region("Menu", player, world.multiworld) world.multiworld.regions.append(menu) - has_progressive_items = options.progression_style != "none" has_progressive_eras = options.progression_style == "eras_and_districts" has_goody_huts = options.shuffle_goody_hut_rewards has_boosts = options.boostsanity @@ -115,7 +109,6 @@ def create_regions(world: 'CivVIWorld', options: CivVIOptions, player: int): era_locations = {location.name: location.code for key, location in world.location_by_era[era.value].items()} - # If progressive_eras is not enabled, then era check types from the era_locations if not has_progressive_eras: era_locations = {key: value for key, value in era_locations.items() if key.split("_")[0] != "ERA"} if not has_goody_huts: @@ -133,41 +126,41 @@ def create_regions(world: 'CivVIWorld', options: CivVIOptions, player: int): world.get_region(EraType.ERA_ANCIENT.value).connect( world.get_region(EraType.ERA_CLASSICAL.value), None, lambda state: has_required_items( - state, EraType.ERA_ANCIENT, player, has_progressive_items, has_progressive_eras) + state, EraType.ERA_ANCIENT, world) ) world.get_region(EraType.ERA_CLASSICAL.value).connect( world.get_region(EraType.ERA_MEDIEVAL.value), None, lambda state: has_required_items( - state, EraType.ERA_CLASSICAL, player, has_progressive_items, has_progressive_eras) + state, EraType.ERA_CLASSICAL, world) ) world.get_region(EraType.ERA_MEDIEVAL.value).connect( world.get_region(EraType.ERA_RENAISSANCE.value), None, lambda state: has_required_items( - state, EraType.ERA_MEDIEVAL, player, has_progressive_items, has_progressive_eras) + state, EraType.ERA_MEDIEVAL, world) ) world.get_region(EraType.ERA_RENAISSANCE.value).connect( world.get_region(EraType.ERA_INDUSTRIAL.value), None, lambda state: has_required_items( - state, EraType.ERA_RENAISSANCE, player, has_progressive_items, has_progressive_eras) + state, EraType.ERA_RENAISSANCE, world) ) world.get_region(EraType.ERA_INDUSTRIAL.value).connect( world.get_region(EraType.ERA_MODERN.value), None, lambda state: has_required_items( - state, EraType.ERA_INDUSTRIAL, player, has_progressive_items, has_progressive_eras) + state, EraType.ERA_INDUSTRIAL, world) ) world.get_region(EraType.ERA_MODERN.value).connect( world.get_region(EraType.ERA_ATOMIC.value), None, lambda state: has_required_items( - state, EraType.ERA_MODERN, player, has_progressive_items, has_progressive_eras) + state, EraType.ERA_MODERN, world) ) world.get_region(EraType.ERA_ATOMIC.value).connect( world.get_region(EraType.ERA_INFORMATION.value), None, lambda state: has_required_items( - state, EraType.ERA_ATOMIC, player, has_progressive_items, has_progressive_eras) + state, EraType.ERA_ATOMIC, world) ) world.get_region(EraType.ERA_INFORMATION.value).connect( - world.get_region(EraType.ERA_FUTURE.value), None, lambda state: has_required_items(state, EraType.ERA_INFORMATION, player, has_progressive_items, has_progressive_eras)) + world.get_region(EraType.ERA_FUTURE.value), None, lambda state: has_required_items(state, EraType.ERA_INFORMATION, world)) world.multiworld.completion_condition[player] = lambda state: state.can_reach( EraType.ERA_FUTURE.value, "Region", player) diff --git a/worlds/civ_6/Rules.py b/worlds/civ_6/Rules.py index abd0fde502..bdcd688d84 100644 --- a/worlds/civ_6/Rules.py +++ b/worlds/civ_6/Rules.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, List, Dict +from typing import TYPE_CHECKING, Callable, List, Dict from BaseClasses import CollectionState from .Items import get_item_by_civ_name from .Data import get_boosts_data @@ -12,9 +12,9 @@ if TYPE_CHECKING: from . import CivVIWorld -def generate_has_required_items_lambda(prereqs: List[str], required_count: int, has_progressive_items: bool, player: int): +def generate_has_required_items_lambda(prereqs: List[str], required_count: int, player: int) -> Callable[[CollectionState, int], bool]: def has_required_items_lambda(state: CollectionState): - return has_required_items(state, prereqs, required_count, has_progressive_items, player) + return has_required_items(state, prereqs, required_count, player) return has_required_items_lambda @@ -28,17 +28,18 @@ def create_boost_rules(world: 'CivVIWorld'): if not boost_data or boost_data.PrereqRequiredCount == 0: continue - has_progressive_items = world.options.progression_style != "none" set_rule(world_location, - generate_has_required_items_lambda(boost_data.Prereq, boost_data.PrereqRequiredCount, has_progressive_items, world.player) + generate_has_required_items_lambda(boost_data.Prereq, boost_data.PrereqRequiredCount, world.player) ) -def has_required_items(state: CollectionState, prereqs: List[str], required_count: int, has_progressive_items: bool, player: int): +def has_required_items(state: CollectionState, prereqs: List[str], required_count: int, player: int) -> bool: + world: 'CivVIWorld' = state.multiworld.worlds[player] + has_progressive_items = world.options.progression_style != "none" if has_progressive_items: - items = [get_item_by_civ_name(item, state.multiworld.worlds[player].item_table).name for item in convert_items_to_have_progression(prereqs)] - progressive_items: Dict[str, int] = {} count = 0 + items = [get_item_by_civ_name(item, world.item_table).name for item in convert_items_to_have_progression(prereqs)] + progressive_items: Dict[str, int] = {} for item in items: if "Progressive" in item: if not progressive_items.get(item): @@ -49,14 +50,12 @@ def has_required_items(state: CollectionState, prereqs: List[str], required_coun count += 1 for item, required_progressive_item_count in progressive_items.items(): - if state.count(item, player) >= required_progressive_item_count: + if state.has(item, player, required_progressive_item_count): count += required_progressive_item_count - if count > 0: - pass return count >= required_count else: - count = 0 - for prereq in prereqs: - if state.has(get_item_by_civ_name(prereq, state.multiworld.worlds[player].item_table).name, player): - count += 1 - return count >= required_count + total = state.count_from_list_unique( + [ + get_item_by_civ_name(prereq, state.multiworld.worlds[player].item_table).name for prereq in prereqs + ], player) + return total >= required_count diff --git a/worlds/civ_6/__init__.py b/worlds/civ_6/__init__.py index 222895b293..17e08b31f2 100644 --- a/worlds/civ_6/__init__.py +++ b/worlds/civ_6/__init__.py @@ -73,7 +73,7 @@ class CivVIWorld(World): for _item_name, location in locations.items(): self.location_table[location.name] = location - def get_filler_item_name(self): + def get_filler_item_name(self) -> str: return get_random_filler_by_rarity(self, FillerItemRarity.COMMON, self.item_table).name def create_regions(self):