Files
Grinch-AP/worlds/civ_6/Regions.py

129 lines
4.5 KiB
Python
Raw Normal View History

New Game Implementation: Civilization VI (#3736) * Init * remove submodule * Init * Update docs * Fix tests * Update to use apcivvi * Update Readme and codeowners * Minor changes * Remove .value from options (except starting hint) * Minor updates * remove unnecessary property * Cleanup Rules and Region * Fix output file generation * Implement feedback * Remove 'AP' tag and fix issue with format strings and using same quotes * Update worlds/civ_6/__init__.py Co-authored-by: Scipio Wright <scipiowright@gmail.com> * Minor docs changes * minor updates * Small rework of create items * Minor updates * Remove unused variable * Move client to Launcher Components with rest of similar clients * Revert "Move client to Launcher Components with rest of similar clients" This reverts commit f9fd5df9fdf19eaf4f1de54e21e3c33a74f02364. * modify component * Fix generation issues * Fix tests * Minor change * Add improvement and test case * Minor options changes * . * Preliminary Review * Fix failing test due to slot data serialization * Format json * Remove exclude missable boosts * Update options (update goody hut text, make research multiplier a range) * Update docs punctuation and slot data init * Move priority/excluded locations into options * Implement docs PR feedback * PR Feedback for options * PR feedback misc * Update location classification and fix client type * Fix typings * Update research cost multiplier * Remove unnecessary location priority code * Remove extrenous use of items() * WIP PR Feedback * WIP PR Feedback * Add victory event * Add option set for death link effect * PR improvements * Update post fill hint to support items with multiple classifications * remove unnecessary len * Move location exclusion logic * Update test to use set instead of accidental dict * Update docs around progressive eras and boost locations * Update docs for options to be more readable * Fix issue with filler items and prehints * Update filler_data to be static * Update links in docs * Minor updates and PR feedback * Update boosts data * Update era required items * Update existing techs * Update existing techs * move boost data class * Update reward data * Update prereq data * Update new items and progressive districts * Remove unused code * Make filler item name func more efficient * Update death link text * Move Civ6 to the end of readme * Fix bug with hidden locations and location.name * Partial PR Feedback Implementation * Format changes * Minor review feedback * Modify access rules to use list created in generate_early * Modify boost rules to precalculate requirements * Remove option checks from access rules * Fix issue with pre initialized dicts * Add inno setup for civ6 client * Update inno_setup.iss --------- Co-authored-by: Scipio Wright <scipiowright@gmail.com> Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: Exempt-Medic <ExemptMedic@Gmail.com> Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
2025-03-10 07:53:26 -06:00
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Union
from BaseClasses import CollectionState, LocationProgressType, Region
from worlds.generic.Rules import add_rule, set_rule
from .Data import (
get_boosts_data,
)
from .Enum import EraType
from .Locations import GOODY_HUT_LOCATION_NAMES, CivVILocation
if TYPE_CHECKING:
from . import CivVIWorld
def has_progressive_eras(
state: CollectionState, era: EraType, world: "CivVIWorld"
) -> bool:
return state.has(
"Progressive Era", world.player, world.era_required_progressive_era_counts[era]
)
def has_non_progressive_items(
state: CollectionState, era: EraType, world: "CivVIWorld"
) -> bool:
return state.has_all(world.era_required_non_progressive_items[era], world.player)
def has_progressive_items(
state: CollectionState, era: EraType, world: "CivVIWorld"
) -> bool:
return state.has_all_counts(
world.era_required_progressive_items_counts[era], world.player
)
def create_regions(world: "CivVIWorld"):
menu = Region("Menu", world.player, world.multiworld)
world.multiworld.regions.append(menu)
optional_location_inclusions: Dict[str, Union[bool, int]] = {
"ERA": world.options.progression_style
== world.options.progression_style.option_eras_and_districts,
"GOODY": world.options.shuffle_goody_hut_rewards.value,
"BOOST": world.options.boostsanity.value,
}
regions: List[Region] = []
previous_era: EraType = EraType.ERA_ANCIENT
for era in EraType:
era_region = Region(era.value, world.player, world.multiworld)
era_locations: Dict[str, Optional[int]] = {}
for key, location in world.location_by_era[era.value].items():
category = key.split("_")[0]
if optional_location_inclusions.get(category, True):
era_locations[location.name] = location.code
era_region.add_locations(era_locations, CivVILocation)
regions.append(era_region)
world.multiworld.regions.append(era_region)
# Connect era to previous era if not ancient era
if era == EraType.ERA_ANCIENT:
menu.connect(world.get_region(EraType.ERA_ANCIENT.value))
continue
connection = world.get_region(previous_era.value).connect(
world.get_region(era.value)
)
# Access rules for eras
add_rule(
connection,
lambda state, previous_era=previous_era, world=world: has_non_progressive_items(
state, previous_era, world
),
)
if world.options.progression_style == "eras_and_districts":
add_rule(
connection,
lambda state, previous_era=previous_era, world=world: has_progressive_eras(
state, previous_era, world
),
)
if world.options.progression_style != "none":
add_rule(
connection,
lambda state, previous_era=previous_era, world=world: has_progressive_items(
state, previous_era, world
),
)
previous_era = era
future_era = world.get_region(EraType.ERA_FUTURE.value)
victory = CivVILocation(world.player, "Complete a victory type", None, future_era)
victory.place_locked_item(world.create_event("Victory"))
future_era.locations.append(victory)
set_rule(
victory,
lambda state: state.can_reach_region(EraType.ERA_FUTURE.value, world.player),
)
world.multiworld.completion_condition[world.player] = lambda state: state.has(
"Victory", world.player
)
exclude_necessary_locations(world)
def exclude_necessary_locations(world: "CivVIWorld"):
forced_excluded_location_names: Set[str] = set()
if world.options.shuffle_goody_hut_rewards:
forced_excluded_location_names.update(GOODY_HUT_LOCATION_NAMES)
if world.options.boostsanity:
boost_data_list = get_boosts_data()
excluded_boosts = {
boost_data.Type
for boost_data in boost_data_list
if boost_data.Classification == "EXCLUDED"
}
forced_excluded_location_names.update(excluded_boosts)
for location_name in forced_excluded_location_names:
location = world.get_location(location_name)
location.progress_type = LocationProgressType.EXCLUDED