Make hint costs relative
This commit is contained in:
		
							parent
							
								
									1b2283b173
								
							
						
					
					
						commit
						a231850911
					
				| 
						 | 
				
			
			@ -129,7 +129,7 @@ class CommonContext():
 | 
			
		|||
        self.input_requests = 0
 | 
			
		||||
 | 
			
		||||
        # game state
 | 
			
		||||
        self.player_names: typing.Dict[int: str] = {0: "Server"}
 | 
			
		||||
        self.player_names: typing.Dict[int: str] = {0: "Archipelago"}
 | 
			
		||||
        self.exit_event = asyncio.Event()
 | 
			
		||||
        self.watcher_event = asyncio.Event()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +194,7 @@ class CommonContext():
 | 
			
		|||
 | 
			
		||||
    def consume_players_package(self, package: typing.List[tuple]):
 | 
			
		||||
        self.player_names = {slot: name for team, slot, name, orig_name in package if self.team == team}
 | 
			
		||||
        self.player_names[0] = "Server"
 | 
			
		||||
        self.player_names[0] = "Archipelago"
 | 
			
		||||
 | 
			
		||||
    def event_invalid_slot(self):
 | 
			
		||||
        raise Exception('Invalid Slot; please verify that you have connected to the correct world.')
 | 
			
		||||
| 
						 | 
				
			
			@ -305,8 +305,8 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
 | 
			
		|||
            logger.info('Password required')
 | 
			
		||||
        logger.info(f"Forfeit setting: {args['forfeit_mode']}")
 | 
			
		||||
        logger.info(f"Remaining setting: {args['remaining_mode']}")
 | 
			
		||||
        logger.info(f"A !hint costs {args['hint_cost']} points and you get {args['location_check_points']}"
 | 
			
		||||
                     f" for each location checked.")
 | 
			
		||||
        logger.info(f"A !hint costs {args['hint_cost']}% of checks points and you get {args['location_check_points']}"
 | 
			
		||||
                     f" for each location checked. Use !hint for more information.")
 | 
			
		||||
        ctx.hint_cost = int(args['hint_cost'])
 | 
			
		||||
        ctx.check_points = int(args['location_check_points'])
 | 
			
		||||
        ctx.forfeit_mode = args['forfeit_mode']
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								Main.py
								
								
								
								
							
							
						
						
									
										15
									
								
								Main.py
								
								
								
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ import time
 | 
			
		|||
import zlib
 | 
			
		||||
import concurrent.futures
 | 
			
		||||
import pickle
 | 
			
		||||
from typing import Dict
 | 
			
		||||
from typing import Dict, Tuple
 | 
			
		||||
 | 
			
		||||
from BaseClasses import MultiWorld, CollectionState, Region, Item
 | 
			
		||||
from worlds.alttp.Items import ItemFactory, item_name_groups
 | 
			
		||||
| 
						 | 
				
			
			@ -501,7 +501,7 @@ def main(args, seed=None):
 | 
			
		|||
                rom_names.append(rom_name)
 | 
			
		||||
            slot_data = {}
 | 
			
		||||
            client_versions = {}
 | 
			
		||||
            minimum_versions = {"server": (0, 0, 4), "clients": client_versions}
 | 
			
		||||
            minimum_versions = {"server": (0, 1, 1), "clients": client_versions}
 | 
			
		||||
            games = {}
 | 
			
		||||
            for slot in world.player_ids:
 | 
			
		||||
                client_versions[slot] = (0, 0, 3)
 | 
			
		||||
| 
						 | 
				
			
			@ -520,6 +520,11 @@ def main(args, seed=None):
 | 
			
		|||
                    slots_data[option_name] = int(option.value)
 | 
			
		||||
            for slot in world.minecraft_player_ids:
 | 
			
		||||
                slot_data[slot] = fill_minecraft_slot_data(world, slot)
 | 
			
		||||
 | 
			
		||||
            locations_data: Dict[int, Dict[int, Tuple[int, int]]] = {player: {} for player in world.player_ids}
 | 
			
		||||
            for location in world.get_filled_locations():
 | 
			
		||||
                if type(location.address) == int:
 | 
			
		||||
                    locations_data[location.player][location.address] = (location.item.code, location.item.player)
 | 
			
		||||
            multidata = zlib.compress(pickle.dumps({
 | 
			
		||||
                "slot_data" : slot_data,
 | 
			
		||||
                "games": games,
 | 
			
		||||
| 
						 | 
				
			
			@ -527,11 +532,7 @@ def main(args, seed=None):
 | 
			
		|||
                "connect_names": connect_names,
 | 
			
		||||
                "remote_items": {player for player in range(1, world.players + 1) if
 | 
			
		||||
                                 world.remote_items[player]},
 | 
			
		||||
                "locations": {
 | 
			
		||||
                    (location.address, location.player):
 | 
			
		||||
                        (location.item.code, location.item.player)
 | 
			
		||||
                    for location in world.get_filled_locations() if
 | 
			
		||||
                    type(location.address) is int},
 | 
			
		||||
                "locations": locations_data,
 | 
			
		||||
                "checks_in_area": checks_in_area,
 | 
			
		||||
                "server_options": get_options()["server_options"],
 | 
			
		||||
                "er_hint_data": er_hint_data,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ class Context(Node):
 | 
			
		|||
        self.connect_names = {} # names of slots clients can connect to
 | 
			
		||||
        self.allow_forfeits = {}
 | 
			
		||||
        self.remote_items = set()
 | 
			
		||||
        self.locations = {}
 | 
			
		||||
        self.locations:typing.Dict[int, typing.Dict[int, typing.Tuple[int, int]]] = {}
 | 
			
		||||
        self.host = host
 | 
			
		||||
        self.port = port
 | 
			
		||||
        self.server_password = server_password
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +114,11 @@ class Context(Node):
 | 
			
		|||
        self.minimum_client_versions: typing.Dict[int, Utils.Version] = {}
 | 
			
		||||
        self.seed_name = ""
 | 
			
		||||
 | 
			
		||||
    def get_hint_cost(self, slot):
 | 
			
		||||
        if self.hint_cost:
 | 
			
		||||
            return max(0, int(self.hint_cost * 0.01 * len(self.locations[slot])))
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def load(self, multidatapath: str, use_embedded_server_options: bool = False):
 | 
			
		||||
        with open(multidatapath, 'rb') as f:
 | 
			
		||||
            data = f.read()
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +137,7 @@ class Context(Node):
 | 
			
		|||
 | 
			
		||||
        mdata_ver = decoded_obj["minimum_versions"]["server"]
 | 
			
		||||
        if mdata_ver > Utils._version_tuple:
 | 
			
		||||
            raise RuntimeError(f"Supplied Multidata requires a server of at least version {mdata_ver},"
 | 
			
		||||
            raise RuntimeError(f"Supplied Multidata (.archipelago) requires a server of at least version {mdata_ver},"
 | 
			
		||||
                               f"however this server is of version {Utils._version_tuple}")
 | 
			
		||||
        clients_ver = decoded_obj["minimum_versions"].get("clients", {})
 | 
			
		||||
        self.minimum_client_versions = {}
 | 
			
		||||
| 
						 | 
				
			
			@ -437,10 +442,6 @@ def get_received_items(ctx: Context, team: int, player: int) -> typing.List[Netw
 | 
			
		|||
    return ctx.received_items.setdefault((team, player), [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def tuplize_received_items(items):
 | 
			
		||||
    return [NetworkItem(item.item, item.location, item.player) for item in items]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def send_new_items(ctx: Context):
 | 
			
		||||
    for client in ctx.endpoints:
 | 
			
		||||
        if client.auth: # can't send to disconnected client
 | 
			
		||||
| 
						 | 
				
			
			@ -449,22 +450,22 @@ def send_new_items(ctx: Context):
 | 
			
		|||
                asyncio.create_task(ctx.send_msgs(client, [{
 | 
			
		||||
                    "cmd": "ReceivedItems",
 | 
			
		||||
                    "index": client.send_index,
 | 
			
		||||
                    "items": tuplize_received_items(items)[client.send_index:]}]))
 | 
			
		||||
                    "items": items[client.send_index:]}]))
 | 
			
		||||
                client.send_index = len(items)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def forfeit_player(ctx: Context, team: int, slot: int):
 | 
			
		||||
    # register any locations that are in the multidata
 | 
			
		||||
    all_locations = {location_id for location_id, location_slot in ctx.locations if location_slot == slot}
 | 
			
		||||
    all_locations = set(ctx.locations[slot])
 | 
			
		||||
    ctx.notify_all("%s (Team #%d) has forfeited" % (ctx.player_names[(team, slot)], team + 1))
 | 
			
		||||
    register_location_checks(ctx, team, slot, all_locations)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_remaining(ctx: Context, team: int, slot: int) -> typing.List[int]:
 | 
			
		||||
    items = []
 | 
			
		||||
    for (location, location_slot) in ctx.locations:
 | 
			
		||||
        if location_slot == slot and location not in ctx.location_checks[team, slot]:
 | 
			
		||||
            items.append(ctx.locations[location, slot][0])  # item ID
 | 
			
		||||
    for location_id in ctx.locations[slot]:
 | 
			
		||||
        if location_id not in ctx.location_checks[team, slot]:
 | 
			
		||||
            items.append(ctx.locations[slot][location_id][0])  # item ID
 | 
			
		||||
    return sorted(items)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -473,8 +474,8 @@ def register_location_checks(ctx: Context, team: int, slot: int, locations: typi
 | 
			
		|||
    if new_locations:
 | 
			
		||||
        ctx.client_activity_timers[team, slot] = datetime.datetime.now(datetime.timezone.utc)
 | 
			
		||||
        for location in new_locations:
 | 
			
		||||
            if (location, slot) in ctx.locations:
 | 
			
		||||
                item_id, target_player = ctx.locations[(location, slot)]
 | 
			
		||||
            if location in ctx.locations[slot]:
 | 
			
		||||
                item_id, target_player = ctx.locations[slot][location]
 | 
			
		||||
                new_item = NetworkItem(item_id, location, slot)
 | 
			
		||||
                if target_player != slot or slot in ctx.remote_items:
 | 
			
		||||
                    get_received_items(ctx, team, target_player).append(new_item)
 | 
			
		||||
| 
						 | 
				
			
			@ -504,29 +505,26 @@ def notify_team(ctx: Context, team: int, text: str):
 | 
			
		|||
def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[NetUtils.Hint]:
 | 
			
		||||
    hints = []
 | 
			
		||||
    seeked_item_id = lookup_any_item_name_to_id[item]
 | 
			
		||||
    for check, result in ctx.locations.items():
 | 
			
		||||
        item_id, receiving_player = result
 | 
			
		||||
        if receiving_player == slot and item_id == seeked_item_id:
 | 
			
		||||
            location_id, finding_player = check
 | 
			
		||||
            found = location_id in ctx.location_checks[team, finding_player]
 | 
			
		||||
            entrance = ctx.er_hint_data.get(finding_player, {}).get(location_id, "")
 | 
			
		||||
            hints.append(NetUtils.Hint(receiving_player, finding_player, location_id, item_id, found, entrance))
 | 
			
		||||
    for finding_player, check_data in ctx.locations.items():
 | 
			
		||||
        for location_id, result in check_data.items():
 | 
			
		||||
            item_id, receiving_player = result
 | 
			
		||||
            if receiving_player == slot and item_id == seeked_item_id:
 | 
			
		||||
                found = location_id in ctx.location_checks[team, finding_player]
 | 
			
		||||
                entrance = ctx.er_hint_data.get(finding_player, {}).get(location_id, "")
 | 
			
		||||
                hints.append(NetUtils.Hint(receiving_player, finding_player, location_id, item_id, found, entrance))
 | 
			
		||||
 | 
			
		||||
    return hints
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def collect_hints_location(ctx: Context, team: int, slot: int, location: str) -> typing.List[NetUtils.Hint]:
 | 
			
		||||
    hints = []
 | 
			
		||||
    seeked_location = Regions.lookup_name_to_id[location]
 | 
			
		||||
    for check, result in ctx.locations.items():
 | 
			
		||||
        location_id, finding_player = check
 | 
			
		||||
        if finding_player == slot and location_id == seeked_location:
 | 
			
		||||
            item_id, receiving_player = result
 | 
			
		||||
            found = location_id in ctx.location_checks[team, finding_player]
 | 
			
		||||
            entrance = ctx.er_hint_data.get(finding_player, {}).get(location_id, "")
 | 
			
		||||
            hints.append(NetUtils.Hint(receiving_player, finding_player, location_id, item_id, found, entrance))
 | 
			
		||||
            break  # each location has 1 item
 | 
			
		||||
    return hints
 | 
			
		||||
 | 
			
		||||
    seeked_location: int = Regions.lookup_name_to_id[location]
 | 
			
		||||
    item_id, receiving_player = ctx.locations[slot].get(seeked_location, (None, None))
 | 
			
		||||
    if item_id:
 | 
			
		||||
        found = seeked_location in ctx.location_checks[team, slot]
 | 
			
		||||
        entrance = ctx.er_hint_data.get(slot, {}).get(seeked_location, "")
 | 
			
		||||
        return [NetUtils.Hint(receiving_player, slot, seeked_location, item_id, found, entrance)]
 | 
			
		||||
    return []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def format_hint(ctx: Context, team: int, hint: NetUtils.Hint) -> str:
 | 
			
		||||
| 
						 | 
				
			
			@ -864,7 +862,7 @@ class ClientMessageProcessor(CommonCommandProcessor):
 | 
			
		|||
        """Use !hint {item_name/location_name}, for example !hint Lamp or !hint Link's House. """
 | 
			
		||||
        points_available = get_client_points(self.ctx, self.client)
 | 
			
		||||
        if not item_or_location:
 | 
			
		||||
            self.output(f"A hint costs {self.ctx.hint_cost} points. "
 | 
			
		||||
            self.output(f"A hint costs {self.ctx.get_hint_cost(self.client.slot)} points. "
 | 
			
		||||
                        f"You have {points_available} points.")
 | 
			
		||||
            hints = {hint.re_check(self.ctx, self.client.team) for hint in
 | 
			
		||||
                     self.ctx.hints[self.client.team, self.client.slot]}
 | 
			
		||||
| 
						 | 
				
			
			@ -885,7 +883,7 @@ class ClientMessageProcessor(CommonCommandProcessor):
 | 
			
		|||
                    hints = collect_hints(self.ctx, self.client.team, self.client.slot, item_name)
 | 
			
		||||
                else:  # location name
 | 
			
		||||
                    hints = collect_hints_location(self.ctx, self.client.team, self.client.slot, item_name)
 | 
			
		||||
 | 
			
		||||
                cost = self.ctx.get_hint_cost(self.client.slot)
 | 
			
		||||
                if hints:
 | 
			
		||||
                    new_hints = set(hints) - self.ctx.hints[self.client.team, self.client.slot]
 | 
			
		||||
                    old_hints = set(hints) - new_hints
 | 
			
		||||
| 
						 | 
				
			
			@ -899,8 +897,8 @@ class ClientMessageProcessor(CommonCommandProcessor):
 | 
			
		|||
 | 
			
		||||
                        if not not_found_hints:  # everything's been found, no need to pay
 | 
			
		||||
                            can_pay = 1000
 | 
			
		||||
                        elif self.ctx.hint_cost:
 | 
			
		||||
                            can_pay = points_available // self.ctx.hint_cost
 | 
			
		||||
                        elif cost:
 | 
			
		||||
                            can_pay = points_available // cost
 | 
			
		||||
                        else:
 | 
			
		||||
                            can_pay = 1000
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -926,7 +924,7 @@ class ClientMessageProcessor(CommonCommandProcessor):
 | 
			
		|||
                            else:
 | 
			
		||||
                                self.output(f"You can't afford the hint. "
 | 
			
		||||
                                            f"You have {points_available} points and need at least "
 | 
			
		||||
                                            f"{self.ctx.hint_cost}")
 | 
			
		||||
                                            f"{self.ctx.get_hint_cost(self.client.slot)}")
 | 
			
		||||
                        notify_hints(self.ctx, self.client.team, hints)
 | 
			
		||||
                        self.ctx.save()
 | 
			
		||||
                        return True
 | 
			
		||||
| 
						 | 
				
			
			@ -941,21 +939,19 @@ class ClientMessageProcessor(CommonCommandProcessor):
 | 
			
		|||
 | 
			
		||||
def get_checked_checks(ctx: Context, client: Client) -> typing.List[int]:
 | 
			
		||||
    return [location_id for
 | 
			
		||||
            location_id, slot in ctx.locations if
 | 
			
		||||
            slot == client.slot and
 | 
			
		||||
            location_id in ctx.locations[client.slot] if
 | 
			
		||||
            location_id in ctx.location_checks[client.team, client.slot]]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_missing_checks(ctx: Context, client: Client) -> typing.List[int]:
 | 
			
		||||
    return [location_id for
 | 
			
		||||
            location_id, slot in ctx.locations if
 | 
			
		||||
            slot == client.slot and
 | 
			
		||||
            location_id in ctx.locations[client.slot] if
 | 
			
		||||
            location_id not in ctx.location_checks[client.team, client.slot]]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_client_points(ctx: Context, client: Client) -> int:
 | 
			
		||||
    return (ctx.location_check_points * len(ctx.location_checks[client.team, client.slot]) -
 | 
			
		||||
            ctx.hint_cost * ctx.hints_used[client.team, client.slot])
 | 
			
		||||
            ctx.get_hint_cost(client.slot) * ctx.hints_used[client.team, client.slot])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def process_client_cmd(ctx: Context, client: Client, args: dict):
 | 
			
		||||
| 
						 | 
				
			
			@ -1032,7 +1028,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
 | 
			
		|||
            }]
 | 
			
		||||
            items = get_received_items(ctx, client.team, client.slot)
 | 
			
		||||
            if items:
 | 
			
		||||
                reply.append({"cmd": 'ReceivedItems', "index": 0, "items": tuplize_received_items(items)})
 | 
			
		||||
                reply.append({"cmd": 'ReceivedItems', "index": 0, "items": items})
 | 
			
		||||
                client.send_index = len(items)
 | 
			
		||||
 | 
			
		||||
            await ctx.send_msgs(client, reply)
 | 
			
		||||
| 
						 | 
				
			
			@ -1047,7 +1043,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
 | 
			
		|||
            if items:
 | 
			
		||||
                client.send_index = len(items)
 | 
			
		||||
                await ctx.send_msgs(client, [{"cmd": "ReceivedItems","index": 0,
 | 
			
		||||
                                              "items": tuplize_received_items(items)}])
 | 
			
		||||
                                              "items": items}])
 | 
			
		||||
 | 
			
		||||
        elif cmd == 'LocationChecks':
 | 
			
		||||
            register_location_checks(ctx, client.team, client.slot, args["locations"])
 | 
			
		||||
| 
						 | 
				
			
			@ -1058,7 +1054,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
 | 
			
		|||
                if type(location) is not int or location not in lookup_any_location_id_to_name:
 | 
			
		||||
                    await ctx.send_msgs(client, [{"cmd": "InvalidArguments", "text": 'LocationScouts'}])
 | 
			
		||||
                    return
 | 
			
		||||
                target_item, target_player = ctx.locations[location, client.slot]
 | 
			
		||||
                target_item, target_player = ctx.locations[client.slot][location]
 | 
			
		||||
                locs.append(NetworkItem(target_item, location, target_player))
 | 
			
		||||
 | 
			
		||||
            await ctx.send_msgs(client, [{'cmd': 'LocationInfo', 'locations': locs}])
 | 
			
		||||
| 
						 | 
				
			
			@ -1206,7 +1202,7 @@ class ServerCommandProcessor(CommonCommandProcessor):
 | 
			
		|||
            if usable:
 | 
			
		||||
                for client in self.ctx.endpoints:
 | 
			
		||||
                    if client.name == seeked_player:
 | 
			
		||||
                        new_item = NetworkItem(lookup_any_item_name_to_id[item], -1, client.slot)
 | 
			
		||||
                        new_item = NetworkItem(lookup_any_item_name_to_id[item], -1, 0)
 | 
			
		||||
                        get_received_items(self.ctx, client.team, client.slot).append(new_item)
 | 
			
		||||
                        self.ctx.notify_all('Cheat console: sending "' + item + '" to ' +
 | 
			
		||||
                                            self.ctx.get_aliased_name(client.team, client.slot))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -303,7 +303,10 @@ def handle_name(name: str, player: int, name_counter: Counter):
 | 
			
		|||
                                                                                                   name] > 1 else ''),
 | 
			
		||||
                                                                 player=player,
 | 
			
		||||
                                                                 PLAYER=(player if player > 1 else '')))
 | 
			
		||||
    return new_name.strip().replace(' ', '_')[:16]
 | 
			
		||||
    new_name = new_name.strip().replace(' ', '_')[:16]
 | 
			
		||||
    if new_name == "Archipelago":
 | 
			
		||||
        raise Exception(f"You cannot name yourself \"{new_name}\"")
 | 
			
		||||
    return new_name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def prefer_int(input_data: str) -> typing.Union[str, int]:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								Utils.py
								
								
								
								
							
							
						
						
									
										2
									
								
								Utils.py
								
								
								
								
							| 
						 | 
				
			
			@ -12,7 +12,7 @@ class Version(typing.NamedTuple):
 | 
			
		|||
    minor: int
 | 
			
		||||
    build: int
 | 
			
		||||
 | 
			
		||||
__version__ = "0.1.0"
 | 
			
		||||
__version__ = "0.1.1"
 | 
			
		||||
_version_tuple = tuplize_version(__version__)
 | 
			
		||||
 | 
			
		||||
import builtins
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,8 @@ server_options:
 | 
			
		|||
  # Client hint system
 | 
			
		||||
  # Points given to a player for each acquired item in their world
 | 
			
		||||
  location_check_points: 1
 | 
			
		||||
  # Point cost to receive a hint via !hint for players
 | 
			
		||||
  # Relative point cost to receive a hint via !hint for players
 | 
			
		||||
  # so for example hint_cost: 20 would mean that for every 20% of available checks, you get the ability to hint, for a total of 5
 | 
			
		||||
  hint_cost: 1000 # Set to 0 if you want free hints
 | 
			
		||||
  # Forfeit modes
 | 
			
		||||
  # "disabled" -> clients can't forfeit,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ from .minecraft.Items import lookup_id_to_name as mc
 | 
			
		|||
lookup_any_item_id_to_name = {**alttp, **hk, **Technologies.lookup_id_to_name, **mc}
 | 
			
		||||
assert len(alttp) + len(hk) + len(Technologies.lookup_id_to_name) + len(mc) == len(lookup_any_item_id_to_name)
 | 
			
		||||
lookup_any_item_name_to_id = {name: id for id, name in lookup_any_item_id_to_name.items()}
 | 
			
		||||
# assert len(lookup_any_item_name_to_id) == len(lookup_any_item_id_to_name) # currently broken: Single Arrow
 | 
			
		||||
 | 
			
		||||
from .alttp import Regions
 | 
			
		||||
from .hk import Locations
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +25,7 @@ assert len(Regions.lookup_id_to_name) + len(Locations.lookup_id_to_name) + \
 | 
			
		|||
       len(Technologies.lookup_id_to_name) + len(Advancements.lookup_id_to_name) == \
 | 
			
		||||
       len(lookup_any_location_id_to_name)
 | 
			
		||||
lookup_any_location_name_to_id = {name: id for id, name in lookup_any_location_id_to_name.items()}
 | 
			
		||||
assert len(lookup_any_location_name_to_id) == len(lookup_any_location_id_to_name)
 | 
			
		||||
 | 
			
		||||
network_data_package = {"lookup_any_location_id_to_name": lookup_any_location_id_to_name,
 | 
			
		||||
                        "lookup_any_item_id_to_name": lookup_any_item_id_to_name,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue