Adds The Legend of Zelda: The Wind Waker as a supported game in Archipelago. The game uses [LagoLunatic's randomizer](https://github.com/LagoLunatic/wwrando) as its base (regarding logic, options, etc.) and builds from there.
		
			
				
	
	
		
			374 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			374 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from collections.abc import Iterable
 | 
						|
from typing import TYPE_CHECKING, NamedTuple, Optional
 | 
						|
 | 
						|
from BaseClasses import Item
 | 
						|
from BaseClasses import ItemClassification as IC
 | 
						|
from worlds.AutoWorld import World
 | 
						|
 | 
						|
if TYPE_CHECKING:
 | 
						|
    from .randomizers.Dungeons import Dungeon
 | 
						|
 | 
						|
 | 
						|
def item_factory(items: str | Iterable[str], world: World) -> Item | list[Item]:
 | 
						|
    """
 | 
						|
    Create items based on their names.
 | 
						|
    Depending on the input, this function can return a single item or a list of items.
 | 
						|
 | 
						|
    :param items: The name or names of the items to create.
 | 
						|
    :param world: The game world.
 | 
						|
    :raises KeyError: If an unknown item name is provided.
 | 
						|
    :return: A single item or a list of items.
 | 
						|
    """
 | 
						|
    ret: list[Item] = []
 | 
						|
    singleton = False
 | 
						|
    if isinstance(items, str):
 | 
						|
        items = [items]
 | 
						|
        singleton = True
 | 
						|
    for item in items:
 | 
						|
        if item in ITEM_TABLE:
 | 
						|
            ret.append(world.create_item(item))
 | 
						|
        else:
 | 
						|
            raise KeyError(f"Unknown item {item}")
 | 
						|
 | 
						|
    return ret[0] if singleton else ret
 | 
						|
 | 
						|
 | 
						|
class TWWItemData(NamedTuple):
 | 
						|
    """
 | 
						|
    This class represents the data for an item in The Wind Waker.
 | 
						|
 | 
						|
    :param type: The type of the item (e.g., "Item", "Dungeon Item").
 | 
						|
    :param classification: The item's classification (progression, useful, filler).
 | 
						|
    :param code: The unique code identifier for the item.
 | 
						|
    :param quantity: The number of this item available.
 | 
						|
    :param item_id: The ID used to represent the item in-game.
 | 
						|
    """
 | 
						|
 | 
						|
    type: str
 | 
						|
    classification: IC
 | 
						|
    code: Optional[int]
 | 
						|
    quantity: int
 | 
						|
    item_id: Optional[int]
 | 
						|
 | 
						|
 | 
						|
class TWWItem(Item):
 | 
						|
    """
 | 
						|
    This class represents an item in The Wind Waker.
 | 
						|
 | 
						|
    :param name: The item's name.
 | 
						|
    :param player: The ID of the player who owns the item.
 | 
						|
    :param data: The data associated with this item.
 | 
						|
    :param classification: Optional classification to override the default.
 | 
						|
    """
 | 
						|
 | 
						|
    game: str = "The Wind Waker"
 | 
						|
    type: Optional[str]
 | 
						|
    dungeon: Optional["Dungeon"] = None
 | 
						|
 | 
						|
    def __init__(self, name: str, player: int, data: TWWItemData, classification: Optional[IC] = None) -> None:
 | 
						|
        super().__init__(
 | 
						|
            name,
 | 
						|
            data.classification if classification is None else classification,
 | 
						|
            None if data.code is None else TWWItem.get_apid(data.code),
 | 
						|
            player,
 | 
						|
        )
 | 
						|
 | 
						|
        self.type = data.type
 | 
						|
        self.item_id = data.item_id
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def get_apid(code: int) -> int:
 | 
						|
        """
 | 
						|
        Compute the Archipelago ID for the given item code.
 | 
						|
 | 
						|
        :param code: The unique code for the item.
 | 
						|
        :return: The computed Archipelago ID.
 | 
						|
        """
 | 
						|
        base_id: int = 2322432
 | 
						|
        return base_id + code
 | 
						|
 | 
						|
    @property
 | 
						|
    def dungeon_item(self) -> Optional[str]:
 | 
						|
        """
 | 
						|
        Determine if the item is a dungeon item and, if so, returns its type.
 | 
						|
 | 
						|
        :return: The type of dungeon item, or `None` if it is not a dungeon item.
 | 
						|
        """
 | 
						|
        if self.type in ("Small Key", "Big Key", "Map", "Compass"):
 | 
						|
            return self.type
 | 
						|
        return None
 | 
						|
 | 
						|
 | 
						|
ITEM_TABLE: dict[str, TWWItemData] = {
 | 
						|
    "Telescope":                 TWWItemData("Item",      IC.useful,                       0,  1, 0x20),
 | 
						|
  # "Boat's Sail":               TWWItemData("Item",      IC.progression,                  1,  1, 0x78),  # noqa: E131
 | 
						|
    "Wind Waker":                TWWItemData("Item",      IC.progression,                  2,  1, 0x22),
 | 
						|
    "Grappling Hook":            TWWItemData("Item",      IC.progression,                  3,  1, 0x25),
 | 
						|
    "Spoils Bag":                TWWItemData("Item",      IC.progression,                  4,  1, 0x24),
 | 
						|
    "Boomerang":                 TWWItemData("Item",      IC.progression,                  5,  1, 0x2D),
 | 
						|
    "Deku Leaf":                 TWWItemData("Item",      IC.progression,                  6,  1, 0x34),
 | 
						|
    "Tingle Tuner":              TWWItemData("Item",      IC.progression,                  7,  1, 0x21),
 | 
						|
    "Iron Boots":                TWWItemData("Item",      IC.progression,                  8,  1, 0x29),
 | 
						|
    "Magic Armor":               TWWItemData("Item",      IC.progression,                  9,  1, 0x2A),
 | 
						|
    "Bait Bag":                  TWWItemData("Item",      IC.progression,                 10,  1, 0x2C),
 | 
						|
    "Bombs":                     TWWItemData("Item",      IC.progression,                 11,  1, 0x31),
 | 
						|
    "Delivery Bag":              TWWItemData("Item",      IC.progression,                 12,  1, 0x30),
 | 
						|
    "Hookshot":                  TWWItemData("Item",      IC.progression,                 13,  1, 0x2F),
 | 
						|
    "Skull Hammer":              TWWItemData("Item",      IC.progression,                 14,  1, 0x33),
 | 
						|
    "Power Bracelets":           TWWItemData("Item",      IC.progression,                 15,  1, 0x28),
 | 
						|
 | 
						|
    "Hero's Charm":              TWWItemData("Item",      IC.useful,                      16,  1, 0x43),
 | 
						|
    "Hurricane Spin":            TWWItemData("Item",      IC.useful,                      17,  1, 0xAA),
 | 
						|
    "Dragon Tingle Statue":      TWWItemData("Item",      IC.progression,                 18,  1, 0xA3),
 | 
						|
    "Forbidden Tingle Statue":   TWWItemData("Item",      IC.progression,                 19,  1, 0xA4),
 | 
						|
    "Goddess Tingle Statue":     TWWItemData("Item",      IC.progression,                 20,  1, 0xA5),
 | 
						|
    "Earth Tingle Statue":       TWWItemData("Item",      IC.progression,                 21,  1, 0xA6),
 | 
						|
    "Wind Tingle Statue":        TWWItemData("Item",      IC.progression,                 22,  1, 0xA7),
 | 
						|
 | 
						|
    "Wind's Requiem":            TWWItemData("Item",      IC.progression,                 23,  1, 0x6D),
 | 
						|
    "Ballad of Gales":           TWWItemData("Item",      IC.progression,                 24,  1, 0x6E),
 | 
						|
    "Command Melody":            TWWItemData("Item",      IC.progression,                 25,  1, 0x6F),
 | 
						|
    "Earth God's Lyric":         TWWItemData("Item",      IC.progression,                 26,  1, 0x70),
 | 
						|
    "Wind God's Aria":           TWWItemData("Item",      IC.progression,                 27,  1, 0x71),
 | 
						|
    "Song of Passing":           TWWItemData("Item",      IC.progression,                 28,  1, 0x72),
 | 
						|
 | 
						|
    "Triforce Shard 1":          TWWItemData("Item",      IC.progression,                 29,  1, 0x61),
 | 
						|
    "Triforce Shard 2":          TWWItemData("Item",      IC.progression,                 30,  1, 0x62),
 | 
						|
    "Triforce Shard 3":          TWWItemData("Item",      IC.progression,                 31,  1, 0x63),
 | 
						|
    "Triforce Shard 4":          TWWItemData("Item",      IC.progression,                 32,  1, 0x64),
 | 
						|
    "Triforce Shard 5":          TWWItemData("Item",      IC.progression,                 33,  1, 0x65),
 | 
						|
    "Triforce Shard 6":          TWWItemData("Item",      IC.progression,                 34,  1, 0x66),
 | 
						|
    "Triforce Shard 7":          TWWItemData("Item",      IC.progression,                 35,  1, 0x67),
 | 
						|
    "Triforce Shard 8":          TWWItemData("Item",      IC.progression,                 36,  1, 0x68),
 | 
						|
 | 
						|
    "Skull Necklace":            TWWItemData("Item",      IC.filler,                      37,  9, 0x45),
 | 
						|
    "Boko Baba Seed":            TWWItemData("Item",      IC.filler,                      38,  1, 0x46),
 | 
						|
    "Golden Feather":            TWWItemData("Item",      IC.filler,                      39,  9, 0x47),
 | 
						|
    "Knight's Crest":            TWWItemData("Item",      IC.filler,                      40,  3, 0x48),
 | 
						|
    "Red Chu Jelly":             TWWItemData("Item",      IC.filler,                      41,  1, 0x49),
 | 
						|
    "Green Chu Jelly":           TWWItemData("Item",      IC.filler,                      42,  1, 0x4A),
 | 
						|
    "Joy Pendant":               TWWItemData("Item",      IC.filler,                      43, 20, 0x1F),
 | 
						|
    "All-Purpose Bait":          TWWItemData("Item",      IC.filler,                      44,  1, 0x82),
 | 
						|
    "Hyoi Pear":                 TWWItemData("Item",      IC.filler,                      45,  4, 0x83),
 | 
						|
 | 
						|
    "Note to Mom":               TWWItemData("Item",      IC.progression,                 46,  1, 0x99),
 | 
						|
    "Maggie's Letter":           TWWItemData("Item",      IC.progression,                 47,  1, 0x9A),
 | 
						|
    "Moblin's Letter":           TWWItemData("Item",      IC.progression,                 48,  1, 0x9B),
 | 
						|
    "Cabana Deed":               TWWItemData("Item",      IC.progression,                 49,  1, 0x9C),
 | 
						|
    "Fill-Up Coupon":            TWWItemData("Item",      IC.useful,                      50,  1, 0x9E),
 | 
						|
 | 
						|
    "Nayru's Pearl":             TWWItemData("Item",      IC.progression,                 51,  1, 0x69),
 | 
						|
    "Din's Pearl":               TWWItemData("Item",      IC.progression,                 52,  1, 0x6A),
 | 
						|
    "Farore's Pearl":            TWWItemData("Item",      IC.progression,                 53,  1, 0x6B),
 | 
						|
 | 
						|
    "Progressive Sword":         TWWItemData("Item",      IC.progression,                 54,  4, 0x38),
 | 
						|
    "Progressive Shield":        TWWItemData("Item",      IC.progression,                 55,  2, 0x3B),
 | 
						|
    "Progressive Picto Box":     TWWItemData("Item",      IC.progression,                 56,  2, 0x23),
 | 
						|
    "Progressive Bow":           TWWItemData("Item",      IC.progression,                 57,  3, 0x27),
 | 
						|
    "Progressive Magic Meter":   TWWItemData("Item",      IC.progression,                 58,  2, 0xB1),
 | 
						|
    "Quiver Capacity Upgrade":   TWWItemData("Item",      IC.progression,                 59,  2, 0xAF),
 | 
						|
    "Bomb Bag Capacity Upgrade": TWWItemData("Item",      IC.useful,                      60,  2, 0xAD),
 | 
						|
    "Wallet Capacity Upgrade":   TWWItemData("Item",      IC.progression,                 61,  2, 0xAB),
 | 
						|
    "Empty Bottle":              TWWItemData("Item",      IC.progression,                 62,  4, 0x50),
 | 
						|
 | 
						|
    "Triforce Chart 1":          TWWItemData("Item",      IC.progression_skip_balancing,  63,  1, 0xFE),
 | 
						|
    "Triforce Chart 2":          TWWItemData("Item",      IC.progression_skip_balancing,  64,  1, 0xFD),
 | 
						|
    "Triforce Chart 3":          TWWItemData("Item",      IC.progression_skip_balancing,  65,  1, 0xFC),
 | 
						|
    "Triforce Chart 4":          TWWItemData("Item",      IC.progression_skip_balancing,  66,  1, 0xFB),
 | 
						|
    "Triforce Chart 5":          TWWItemData("Item",      IC.progression_skip_balancing,  67,  1, 0xFA),
 | 
						|
    "Triforce Chart 6":          TWWItemData("Item",      IC.progression_skip_balancing,  68,  1, 0xF9),
 | 
						|
    "Triforce Chart 7":          TWWItemData("Item",      IC.progression_skip_balancing,  69,  1, 0xF8),
 | 
						|
    "Triforce Chart 8":          TWWItemData("Item",      IC.progression_skip_balancing,  70,  1, 0xF7),
 | 
						|
    "Treasure Chart 1":          TWWItemData("Item",      IC.progression_skip_balancing,  71,  1, 0xE7),
 | 
						|
    "Treasure Chart 2":          TWWItemData("Item",      IC.progression_skip_balancing,  72,  1, 0xEE),
 | 
						|
    "Treasure Chart 3":          TWWItemData("Item",      IC.progression_skip_balancing,  73,  1, 0xE0),
 | 
						|
    "Treasure Chart 4":          TWWItemData("Item",      IC.progression_skip_balancing,  74,  1, 0xE1),
 | 
						|
    "Treasure Chart 5":          TWWItemData("Item",      IC.progression_skip_balancing,  75,  1, 0xF2),
 | 
						|
    "Treasure Chart 6":          TWWItemData("Item",      IC.progression_skip_balancing,  76,  1, 0xEA),
 | 
						|
    "Treasure Chart 7":          TWWItemData("Item",      IC.progression_skip_balancing,  77,  1, 0xCC),
 | 
						|
    "Treasure Chart 8":          TWWItemData("Item",      IC.progression_skip_balancing,  78,  1, 0xD4),
 | 
						|
    "Treasure Chart 9":          TWWItemData("Item",      IC.progression_skip_balancing,  79,  1, 0xDA),
 | 
						|
    "Treasure Chart 10":         TWWItemData("Item",      IC.progression_skip_balancing,  80,  1, 0xDE),
 | 
						|
    "Treasure Chart 11":         TWWItemData("Item",      IC.progression_skip_balancing,  81,  1, 0xF6),
 | 
						|
    "Treasure Chart 12":         TWWItemData("Item",      IC.progression_skip_balancing,  82,  1, 0xE9),
 | 
						|
    "Treasure Chart 13":         TWWItemData("Item",      IC.progression_skip_balancing,  83,  1, 0xCF),
 | 
						|
    "Treasure Chart 14":         TWWItemData("Item",      IC.progression_skip_balancing,  84,  1, 0xDD),
 | 
						|
    "Treasure Chart 15":         TWWItemData("Item",      IC.progression_skip_balancing,  85,  1, 0xF5),
 | 
						|
    "Treasure Chart 16":         TWWItemData("Item",      IC.progression_skip_balancing,  86,  1, 0xE3),
 | 
						|
    "Treasure Chart 17":         TWWItemData("Item",      IC.progression_skip_balancing,  87,  1, 0xD7),
 | 
						|
    "Treasure Chart 18":         TWWItemData("Item",      IC.progression_skip_balancing,  88,  1, 0xE4),
 | 
						|
    "Treasure Chart 19":         TWWItemData("Item",      IC.progression_skip_balancing,  89,  1, 0xD1),
 | 
						|
    "Treasure Chart 20":         TWWItemData("Item",      IC.progression_skip_balancing,  90,  1, 0xF3),
 | 
						|
    "Treasure Chart 21":         TWWItemData("Item",      IC.progression_skip_balancing,  91,  1, 0xCE),
 | 
						|
    "Treasure Chart 22":         TWWItemData("Item",      IC.progression_skip_balancing,  92,  1, 0xD9),
 | 
						|
    "Treasure Chart 23":         TWWItemData("Item",      IC.progression_skip_balancing,  93,  1, 0xF1),
 | 
						|
    "Treasure Chart 24":         TWWItemData("Item",      IC.progression_skip_balancing,  94,  1, 0xEB),
 | 
						|
    "Treasure Chart 25":         TWWItemData("Item",      IC.progression_skip_balancing,  95,  1, 0xD6),
 | 
						|
    "Treasure Chart 26":         TWWItemData("Item",      IC.progression_skip_balancing,  96,  1, 0xD3),
 | 
						|
    "Treasure Chart 27":         TWWItemData("Item",      IC.progression_skip_balancing,  97,  1, 0xCD),
 | 
						|
    "Treasure Chart 28":         TWWItemData("Item",      IC.progression_skip_balancing,  98,  1, 0xE2),
 | 
						|
    "Treasure Chart 29":         TWWItemData("Item",      IC.progression_skip_balancing,  99,  1, 0xE6),
 | 
						|
    "Treasure Chart 30":         TWWItemData("Item",      IC.progression_skip_balancing, 100,  1, 0xF4),
 | 
						|
    "Treasure Chart 31":         TWWItemData("Item",      IC.progression_skip_balancing, 101,  1, 0xF0),
 | 
						|
    "Treasure Chart 32":         TWWItemData("Item",      IC.progression_skip_balancing, 102,  1, 0xD0),
 | 
						|
    "Treasure Chart 33":         TWWItemData("Item",      IC.progression_skip_balancing, 103,  1, 0xEF),
 | 
						|
    "Treasure Chart 34":         TWWItemData("Item",      IC.progression_skip_balancing, 104,  1, 0xE5),
 | 
						|
    "Treasure Chart 35":         TWWItemData("Item",      IC.progression_skip_balancing, 105,  1, 0xE8),
 | 
						|
    "Treasure Chart 36":         TWWItemData("Item",      IC.progression_skip_balancing, 106,  1, 0xD8),
 | 
						|
    "Treasure Chart 37":         TWWItemData("Item",      IC.progression_skip_balancing, 107,  1, 0xD5),
 | 
						|
    "Treasure Chart 38":         TWWItemData("Item",      IC.progression_skip_balancing, 108,  1, 0xED),
 | 
						|
    "Treasure Chart 39":         TWWItemData("Item",      IC.progression_skip_balancing, 109,  1, 0xEC),
 | 
						|
    "Treasure Chart 40":         TWWItemData("Item",      IC.progression_skip_balancing, 110,  1, 0xDF),
 | 
						|
    "Treasure Chart 41":         TWWItemData("Item",      IC.progression_skip_balancing, 111,  1, 0xD2),
 | 
						|
 | 
						|
    "Tingle's Chart":            TWWItemData("Item",      IC.filler,                     112,  1, 0xDC),
 | 
						|
    "Ghost Ship Chart":          TWWItemData("Item",      IC.progression,                113,  1, 0xDB),
 | 
						|
    "Octo Chart":                TWWItemData("Item",      IC.filler,                     114,  1, 0xCA),
 | 
						|
    "Great Fairy Chart":         TWWItemData("Item",      IC.filler,                     115,  1, 0xC9),
 | 
						|
    "Secret Cave Chart":         TWWItemData("Item",      IC.filler,                     116,  1, 0xC6),
 | 
						|
    "Light Ring Chart":          TWWItemData("Item",      IC.filler,                     117,  1, 0xC5),
 | 
						|
    "Platform Chart":            TWWItemData("Item",      IC.filler,                     118,  1, 0xC4),
 | 
						|
    "Beedle's Chart":            TWWItemData("Item",      IC.filler,                     119,  1, 0xC3),
 | 
						|
    "Submarine Chart":           TWWItemData("Item",      IC.filler,                     120,  1, 0xC2),
 | 
						|
 | 
						|
    "Green Rupee":               TWWItemData("Item",      IC.filler,                     121,  1, 0x01),
 | 
						|
    "Blue Rupee":                TWWItemData("Item",      IC.filler,                     122,  2, 0x02),
 | 
						|
    "Yellow Rupee":              TWWItemData("Item",      IC.filler,                     123,  3, 0x03),
 | 
						|
    "Red Rupee":                 TWWItemData("Item",      IC.filler,                     124,  8, 0x04),
 | 
						|
    "Purple Rupee":              TWWItemData("Item",      IC.filler,                     125, 10, 0x05),
 | 
						|
    "Orange Rupee":              TWWItemData("Item",      IC.useful,                     126, 15, 0x06),
 | 
						|
    "Silver Rupee":              TWWItemData("Item",      IC.useful,                     127, 20, 0x0F),
 | 
						|
    "Rainbow Rupee":             TWWItemData("Item",      IC.useful,                     128,  1, 0xB8),
 | 
						|
 | 
						|
    "Piece of Heart":            TWWItemData("Item",      IC.useful,                     129, 44, 0x07),
 | 
						|
    "Heart Container":           TWWItemData("Item",      IC.useful,                     130,  6, 0x08),
 | 
						|
 | 
						|
    "DRC Big Key":               TWWItemData("Big Key",   IC.progression,                131,  1, 0x14),
 | 
						|
    "DRC Small Key":             TWWItemData("Small Key", IC.progression,                132,  4, 0x13),
 | 
						|
    "FW Big Key":                TWWItemData("Big Key",   IC.progression,                133,  1, 0x40),
 | 
						|
    "FW Small Key":              TWWItemData("Small Key", IC.progression,                134,  1, 0x1D),
 | 
						|
    "TotG Big Key":              TWWItemData("Big Key",   IC.progression,                135,  1, 0x5C),
 | 
						|
    "TotG Small Key":            TWWItemData("Small Key", IC.progression,                136,  2, 0x5B),
 | 
						|
    "ET Big Key":                TWWItemData("Big Key",   IC.progression,                138,  1, 0x74),
 | 
						|
    "ET Small Key":              TWWItemData("Small Key", IC.progression,                139,  3, 0x73),
 | 
						|
    "WT Big Key":                TWWItemData("Big Key",   IC.progression,                140,  1, 0x81),
 | 
						|
    "WT Small Key":              TWWItemData("Small Key", IC.progression,                141,  2, 0x77),
 | 
						|
    "DRC Dungeon Map":           TWWItemData("Map",       IC.filler,                     142,  1, 0x1B),
 | 
						|
    "DRC Compass":               TWWItemData("Compass",   IC.filler,                     143,  1, 0x1C),
 | 
						|
    "FW Dungeon Map":            TWWItemData("Map",       IC.filler,                     144,  1, 0x41),
 | 
						|
    "FW Compass":                TWWItemData("Compass",   IC.filler,                     145,  1, 0x5A),
 | 
						|
    "TotG Dungeon Map":          TWWItemData("Map",       IC.filler,                     146,  1, 0x5D),
 | 
						|
    "TotG Compass":              TWWItemData("Compass",   IC.filler,                     147,  1, 0x5E),
 | 
						|
    "FF Dungeon Map":            TWWItemData("Map",       IC.filler,                     148,  1, 0x5F),
 | 
						|
    "FF Compass":                TWWItemData("Compass",   IC.filler,                     149,  1, 0x60),
 | 
						|
    "ET Dungeon Map":            TWWItemData("Map",       IC.filler,                     150,  1, 0x75),
 | 
						|
    "ET Compass":                TWWItemData("Compass",   IC.filler,                     151,  1, 0x76),
 | 
						|
    "WT Dungeon Map":            TWWItemData("Map",       IC.filler,                     152,  1, 0x84),
 | 
						|
    "WT Compass":                TWWItemData("Compass",   IC.filler,                     153,  1, 0x85),
 | 
						|
 | 
						|
    "Victory":                   TWWItemData("Event",     IC.progression,               None,  1, None),
 | 
						|
}
 | 
						|
 | 
						|
ISLAND_NUMBER_TO_CHART_NAME = {
 | 
						|
    1: "Treasure Chart 25",
 | 
						|
    2: "Treasure Chart 7",
 | 
						|
    3: "Treasure Chart 24",
 | 
						|
    4: "Triforce Chart 2",
 | 
						|
    5: "Treasure Chart 11",
 | 
						|
    6: "Triforce Chart 7",
 | 
						|
    7: "Treasure Chart 13",
 | 
						|
    8: "Treasure Chart 41",
 | 
						|
    9: "Treasure Chart 29",
 | 
						|
    10: "Treasure Chart 22",
 | 
						|
    11: "Treasure Chart 18",
 | 
						|
    12: "Treasure Chart 30",
 | 
						|
    13: "Treasure Chart 39",
 | 
						|
    14: "Treasure Chart 19",
 | 
						|
    15: "Treasure Chart 8",
 | 
						|
    16: "Treasure Chart 2",
 | 
						|
    17: "Treasure Chart 10",
 | 
						|
    18: "Treasure Chart 26",
 | 
						|
    19: "Treasure Chart 3",
 | 
						|
    20: "Treasure Chart 37",
 | 
						|
    21: "Treasure Chart 27",
 | 
						|
    22: "Treasure Chart 38",
 | 
						|
    23: "Triforce Chart 1",
 | 
						|
    24: "Treasure Chart 21",
 | 
						|
    25: "Treasure Chart 6",
 | 
						|
    26: "Treasure Chart 14",
 | 
						|
    27: "Treasure Chart 34",
 | 
						|
    28: "Treasure Chart 5",
 | 
						|
    29: "Treasure Chart 28",
 | 
						|
    30: "Treasure Chart 35",
 | 
						|
    31: "Triforce Chart 3",
 | 
						|
    32: "Triforce Chart 6",
 | 
						|
    33: "Treasure Chart 1",
 | 
						|
    34: "Treasure Chart 20",
 | 
						|
    35: "Treasure Chart 36",
 | 
						|
    36: "Treasure Chart 23",
 | 
						|
    37: "Treasure Chart 12",
 | 
						|
    38: "Treasure Chart 16",
 | 
						|
    39: "Treasure Chart 4",
 | 
						|
    40: "Treasure Chart 17",
 | 
						|
    41: "Treasure Chart 31",
 | 
						|
    42: "Triforce Chart 5",
 | 
						|
    43: "Treasure Chart 9",
 | 
						|
    44: "Triforce Chart 4",
 | 
						|
    45: "Treasure Chart 40",
 | 
						|
    46: "Triforce Chart 8",
 | 
						|
    47: "Treasure Chart 15",
 | 
						|
    48: "Treasure Chart 32",
 | 
						|
    49: "Treasure Chart 33",
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
LOOKUP_ID_TO_NAME: dict[int, str] = {
 | 
						|
    TWWItem.get_apid(data.code): item for item, data in ITEM_TABLE.items() if data.code is not None
 | 
						|
}
 | 
						|
 | 
						|
item_name_groups = {
 | 
						|
    "Songs": {
 | 
						|
        "Wind's Requiem",
 | 
						|
        "Ballad of Gales",
 | 
						|
        "Command Melody",
 | 
						|
        "Earth God's Lyric",
 | 
						|
        "Wind God's Aria",
 | 
						|
        "Song of Passing",
 | 
						|
    },
 | 
						|
    "Mail": {
 | 
						|
        "Note to Mom",
 | 
						|
        "Maggie's Letter",
 | 
						|
        "Moblin's Letter",
 | 
						|
    },
 | 
						|
    "Special Charts": {
 | 
						|
        "Tingle's Chart",
 | 
						|
        "Ghost Ship Chart",
 | 
						|
        "Octo Chart",
 | 
						|
        "Great Fairy Chart",
 | 
						|
        "Secret Cave Chart",
 | 
						|
        "Light Ring Chart",
 | 
						|
        "Platform Chart",
 | 
						|
        "Beedle's Chart",
 | 
						|
        "Submarine Chart",
 | 
						|
    },
 | 
						|
}
 | 
						|
# generic groups, (Name, substring)
 | 
						|
_simple_groups = {
 | 
						|
    ("Tingle Statues", "Tingle Statue"),
 | 
						|
    ("Shards", "Shard"),
 | 
						|
    ("Pearls", "Pearl"),
 | 
						|
    ("Triforce Charts", "Triforce Chart"),
 | 
						|
    ("Treasure Charts", "Treasure Chart"),
 | 
						|
    ("Small Keys", "Small Key"),
 | 
						|
    ("Big Keys", "Big Key"),
 | 
						|
    ("Rupees", "Rupee"),
 | 
						|
    ("Dungeon Items", "Compass"),
 | 
						|
    ("Dungeon Items", "Map"),
 | 
						|
}
 | 
						|
for basename, substring in _simple_groups:
 | 
						|
    if basename not in item_name_groups:
 | 
						|
        item_name_groups[basename] = set()
 | 
						|
    for itemname in ITEM_TABLE:
 | 
						|
        if substring in itemname:
 | 
						|
            item_name_groups[basename].add(itemname)
 |