import json from pathlib import Path from typing import Dict, NamedTuple, List, Optional from BaseClasses import Region, RegionType, Location EventId: Optional[int] = None CHAOS_TERMINATED_EVENT = 'Terminated Chaos' class LocationData(NamedTuple): name: str address: int class FF1Locations: _location_table: List[LocationData] = [] _location_table_lookup: Dict[str, LocationData] = {} def _populate_item_table_from_data(self): base_path = Path(__file__).parent file_path = (base_path / "data/locations.json").resolve() with open(file_path) as file: locations = json.load(file) # Hardcode progression and categories for now self._location_table = [LocationData(name, code) for name, code in locations.items()] self._location_table_lookup = {item.name: item for item in self._location_table} def _get_location_table(self) -> List[LocationData]: if not self._location_table or not self._location_table_lookup: self._populate_item_table_from_data() return self._location_table def _get_location_table_lookup(self) -> Dict[str, LocationData]: if not self._location_table or not self._location_table_lookup: self._populate_item_table_from_data() return self._location_table_lookup def get_location_name_to_address_dict(self) -> Dict[str, int]: data = {name: location.address for name, location in self._get_location_table_lookup().items()} data[CHAOS_TERMINATED_EVENT] = EventId return data @staticmethod def create_menu_region(player: int, locations: Dict[str, int], rules: Dict[str, List[List[str]]]) -> Region: menu_region = Region("Menu", RegionType.Generic, "Menu", player) for name, address in locations.items(): location = Location(player, name, address, menu_region) ## TODO REMOVE WHEN LOGIC FOR TOFR IS CORRECT if "ToFR" in name: rules_list = [["Rod", "Cube", "Lute", "Key", "Chime", "Oxyale", "Ship", "Canoe", "Floater", "Canal", "Crown", "Crystal", "Herb", "Tnt", "Adamant", "Slab", "Ruby", "Bottle"]] location.access_rule = generate_rule(rules_list, player) elif name in rules: rules_list = rules[name] location.access_rule = generate_rule(rules_list, player) menu_region.locations.append(location) return menu_region def generate_rule(rules_list, player): def x(state): for rule in rules_list: current_state = True for item in rule: if not state.has(item, player): current_state = False break if current_state: return True return False return x