76 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
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
 |