diff --git a/KH1Client.py b/KH1Client.py new file mode 100644 index 000000000000..4c3ed501901b --- /dev/null +++ b/KH1Client.py @@ -0,0 +1,9 @@ +if __name__ == '__main__': + import ModuleUpdate + ModuleUpdate.update() + + import Utils + Utils.init_logging("KH1Client", exception_logger="Client") + + from worlds.kh1.Client import launch + launch() diff --git a/README.md b/README.md index 5b66e3db8782..a2e9d3e5e5a3 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ Currently, the following games are supported: * Yu-Gi-Oh! Ultimate Masters: World Championship Tournament 2006 * A Hat in Time * Old School Runescape +* Kingdom Hearts 1 For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 4f012c306be9..bba79c649fc1 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -78,6 +78,9 @@ # Kirby's Dream Land 3 /worlds/kdl3/ @Silvris +# Kingdom Hearts +/worlds/kh1/ @gaithern + # Kingdom Hearts 2 /worlds/kh2/ @JaredWeakStrike diff --git a/worlds/kh1/Client.py b/worlds/kh1/Client.py new file mode 100644 index 000000000000..acfd5dba3825 --- /dev/null +++ b/worlds/kh1/Client.py @@ -0,0 +1,258 @@ +from __future__ import annotations +import os +import json +import sys +import asyncio +import shutil +import logging +import re +import time +from calendar import timegm + +import ModuleUpdate +ModuleUpdate.update() + +import Utils +death_link = False +item_num = 1 + +logger = logging.getLogger("Client") + +if __name__ == "__main__": + Utils.init_logging("KH1Client", exception_logger="Client") + +from NetUtils import NetworkItem, ClientStatus +from CommonClient import gui_enabled, logger, get_base_parser, ClientCommandProcessor, \ + CommonContext, server_loop + + +def check_stdin() -> None: + if Utils.is_windows and sys.stdin: + print("WARNING: Console input is not routed reliably on Windows, use the GUI instead.") + +class KH1ClientCommandProcessor(ClientCommandProcessor): + def _cmd_deathlink(self): + """Toggles Deathlink""" + global death_link + if death_link: + death_link = False + self.output(f"Death Link turned off") + else: + death_link = True + self.output(f"Death Link turned on") + +class KH1Context(CommonContext): + command_processor: int = KH1ClientCommandProcessor + game = "Kingdom Hearts" + items_handling = 0b111 # full remote + + def __init__(self, server_address, password): + super(KH1Context, self).__init__(server_address, password) + self.send_index: int = 0 + self.syncing = False + self.awaiting_bridge = False + # self.game_communication_path: files go in this path to pass data between us and the actual game + if "localappdata" in os.environ: + self.game_communication_path = os.path.expandvars(r"%localappdata%/KH1FM") + else: + self.game_communication_path = os.path.expandvars(r"$HOME/KH1FM") + if not os.path.exists(self.game_communication_path): + os.makedirs(self.game_communication_path) + for root, dirs, files in os.walk(self.game_communication_path): + for file in files: + if file.find("obtain") <= -1: + os.remove(root+"/"+file) + + async def server_auth(self, password_requested: bool = False): + if password_requested and not self.password: + await super(KH1Context, self).server_auth(password_requested) + await self.get_username() + await self.send_connect() + + async def connection_closed(self): + await super(KH1Context, self).connection_closed() + for root, dirs, files in os.walk(self.game_communication_path): + for file in files: + if file.find("obtain") <= -1: + os.remove(root + "/" + file) + global item_num + item_num = 1 + + @property + def endpoints(self): + if self.server: + return [self.server] + else: + return [] + + async def shutdown(self): + await super(KH1Context, self).shutdown() + for root, dirs, files in os.walk(self.game_communication_path): + for file in files: + if file.find("obtain") <= -1: + os.remove(root+"/"+file) + global item_num + item_num = 1 + + def on_package(self, cmd: str, args: dict): + if cmd in {"Connected"}: + if not os.path.exists(self.game_communication_path): + os.makedirs(self.game_communication_path) + for ss in self.checked_locations: + filename = f"send{ss}" + with open(os.path.join(self.game_communication_path, filename), 'w') as f: + f.close() + + #Handle Slot Data + for key in list(args['slot_data'].keys()): + with open(os.path.join(self.game_communication_path, key + ".cfg"), 'w') as f: + f.write(str(args['slot_data'][key])) + f.close() + + ###Support Legacy Games + if "Required Reports" in list(args['slot_data'].keys()) and "required_reports_eotw" not in list(args['slot_data'].keys()): + reports_required = args['slot_data']["Required Reports"] + with open(os.path.join(self.game_communication_path, "required_reports.cfg"), 'w') as f: + f.write(str(reports_required)) + f.close() + ###End Support Legacy Games + + #End Handle Slot Data + + if cmd in {"ReceivedItems"}: + start_index = args["index"] + if start_index != len(self.items_received): + global item_num + for item in args['items']: + found = False + item_filename = f"AP_{str(item_num)}.item" + for filename in os.listdir(self.game_communication_path): + if filename == item_filename: + found = True + if not found: + with open(os.path.join(self.game_communication_path, item_filename), 'w') as f: + f.write(str(NetworkItem(*item).item) + "\n" + str(NetworkItem(*item).location) + "\n" + str(NetworkItem(*item).player)) + f.close() + item_num = item_num + 1 + + if cmd in {"RoomUpdate"}: + if "checked_locations" in args: + for ss in self.checked_locations: + filename = f"send{ss}" + with open(os.path.join(self.game_communication_path, filename), 'w') as f: + f.close() + + if cmd in {"PrintJSON"} and "type" in args: + if args["type"] == "ItemSend": + item = args["item"] + networkItem = NetworkItem(*item) + recieverID = args["receiving"] + senderID = networkItem.player + locationID = networkItem.location + if recieverID != self.slot and senderID == self.slot: + itemName = self.item_names.lookup_in_slot(networkItem.item, recieverID) + itemCategory = networkItem.flags + recieverName = self.player_names[recieverID] + filename = "sent" + with open(os.path.join(self.game_communication_path, filename), 'w') as f: + f.write( + re.sub('[^A-Za-z0-9 ]+', '',str(itemName))[:15] + "\n" + + re.sub('[^A-Za-z0-9 ]+', '',str(recieverName))[:6] + "\n" + + str(itemCategory) + "\n" + + str(locationID)) + f.close() + + def on_deathlink(self, data: dict[str, object]): + self.last_death_link = max(data["time"], self.last_death_link) + text = data.get("cause", "") + if text: + logger.info(f"DeathLink: {text}") + else: + logger.info(f"DeathLink: Received from {data['source']}") + with open(os.path.join(self.game_communication_path, 'dlreceive'), 'w') as f: + f.write(str(int(data["time"]))) + f.close() + + def run_gui(self): + """Import kivy UI system and start running it as self.ui_task.""" + from kvui import GameManager + + class KH1Manager(GameManager): + logging_pairs = [ + ("Client", "Archipelago") + ] + base_title = "Archipelago KH1 Client" + + self.ui = KH1Manager(self) + self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI") + + +async def game_watcher(ctx: KH1Context): + from .Locations import lookup_id_to_name + while not ctx.exit_event.is_set(): + global death_link + if death_link and "DeathLink" not in ctx.tags: + await ctx.update_death_link(death_link) + if not death_link and "DeathLink" in ctx.tags: + await ctx.update_death_link(death_link) + if ctx.syncing == True: + sync_msg = [{'cmd': 'Sync'}] + if ctx.locations_checked: + sync_msg.append({"cmd": "LocationChecks", "locations": list(ctx.locations_checked)}) + await ctx.send_msgs(sync_msg) + ctx.syncing = False + sending = [] + victory = False + for root, dirs, files in os.walk(ctx.game_communication_path): + for file in files: + if file.find("send") > -1: + st = file.split("send", -1)[1] + if st != "nil": + sending = sending+[(int(st))] + if file.find("victory") > -1: + victory = True + if file.find("dlsend") > -1 and "DeathLink" in ctx.tags: + st = file.split("dlsend", -1)[1] + if st != "nil": + if timegm(time.strptime(st, '%Y%m%d%H%M%S')) > ctx.last_death_link and int(time.time()) % int(timegm(time.strptime(st, '%Y%m%d%H%M%S'))) < 10: + await ctx.send_death(death_text = "Sora was defeated!") + if file.find("insynthshop") > -1: + await ctx.send_msgs([{ + "cmd": "LocationScouts", + "locations": [2656401,2656402,2656403,2656404,2656405,2656406], + "create_as_hint": 2 + }]) + ctx.locations_checked = sending + message = [{"cmd": 'LocationChecks', "locations": sending}] + await ctx.send_msgs(message) + if not ctx.finished_game and victory: + await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) + ctx.finished_game = True + await asyncio.sleep(0.1) + + +def launch(): + async def main(args): + ctx = KH1Context(args.connect, args.password) + ctx.server_task = asyncio.create_task(server_loop(ctx), name="server loop") + if gui_enabled: + ctx.run_gui() + ctx.run_cli() + progression_watcher = asyncio.create_task( + game_watcher(ctx), name="KH1ProgressionWatcher") + + await ctx.exit_event.wait() + ctx.server_address = None + + await progression_watcher + + await ctx.shutdown() + + import colorama + + parser = get_base_parser(description="KH1 Client, for text interfacing.") + + args, rest = parser.parse_known_args() + colorama.init() + asyncio.run(main(args)) + colorama.deinit() diff --git a/worlds/kh1/Items.py b/worlds/kh1/Items.py new file mode 100644 index 000000000000..bac98a9b3284 --- /dev/null +++ b/worlds/kh1/Items.py @@ -0,0 +1,532 @@ +from typing import Dict, NamedTuple, Optional, Set + +from BaseClasses import Item, ItemClassification + + +class KH1Item(Item): + game: str = "Kingdom Hearts" + + +class KH1ItemData(NamedTuple): + category: str + code: int + classification: ItemClassification = ItemClassification.filler + max_quantity: int = 1 + weight: int = 1 + + +def get_items_by_category(category: str) -> Dict[str, KH1ItemData]: + item_dict: Dict[str, KH1ItemData] = {} + for name, data in item_table.items(): + if data.category == category: + item_dict.setdefault(name, data) + + return item_dict + + +item_table: Dict[str, KH1ItemData] = { + "Victory": KH1ItemData("VIC", code = 264_0000, classification = ItemClassification.progression, ), + "Potion": KH1ItemData("Item", code = 264_1001, classification = ItemClassification.filler, ), + "Hi-Potion": KH1ItemData("Item", code = 264_1002, classification = ItemClassification.filler, ), + "Ether": KH1ItemData("Item", code = 264_1003, classification = ItemClassification.filler, ), + "Elixir": KH1ItemData("Item", code = 264_1004, classification = ItemClassification.filler, ), + #"B05": KH1ItemData("Item", code = 264_1005, classification = ItemClassification.filler, ), + "Mega-Potion": KH1ItemData("Item", code = 264_1006, classification = ItemClassification.filler, ), + "Mega-Ether": KH1ItemData("Item", code = 264_1007, classification = ItemClassification.filler, ), + "Megalixir": KH1ItemData("Item", code = 264_1008, classification = ItemClassification.filler, ), + #"Fury Stone": KH1ItemData("Synthesis", code = 264_1009, classification = ItemClassification.filler, ), + #"Power Stone": KH1ItemData("Synthesis", code = 264_1010, classification = ItemClassification.filler, ), + #"Energy Stone": KH1ItemData("Synthesis", code = 264_1011, classification = ItemClassification.filler, ), + #"Blazing Stone": KH1ItemData("Synthesis", code = 264_1012, classification = ItemClassification.filler, ), + #"Frost Stone": KH1ItemData("Synthesis", code = 264_1013, classification = ItemClassification.filler, ), + #"Lightning Stone": KH1ItemData("Synthesis", code = 264_1014, classification = ItemClassification.filler, ), + #"Dazzling Stone": KH1ItemData("Synthesis", code = 264_1015, classification = ItemClassification.filler, ), + #"Stormy Stone": KH1ItemData("Synthesis", code = 264_1016, classification = ItemClassification.filler, ), + "Protect Chain": KH1ItemData("Accessory", code = 264_1017, classification = ItemClassification.useful, ), + "Protera Chain": KH1ItemData("Accessory", code = 264_1018, classification = ItemClassification.useful, ), + "Protega Chain": KH1ItemData("Accessory", code = 264_1019, classification = ItemClassification.useful, ), + "Fire Ring": KH1ItemData("Accessory", code = 264_1020, classification = ItemClassification.useful, ), + "Fira Ring": KH1ItemData("Accessory", code = 264_1021, classification = ItemClassification.useful, ), + "Firaga Ring": KH1ItemData("Accessory", code = 264_1022, classification = ItemClassification.useful, ), + "Blizzard Ring": KH1ItemData("Accessory", code = 264_1023, classification = ItemClassification.useful, ), + "Blizzara Ring": KH1ItemData("Accessory", code = 264_1024, classification = ItemClassification.useful, ), + "Blizzaga Ring": KH1ItemData("Accessory", code = 264_1025, classification = ItemClassification.useful, ), + "Thunder Ring": KH1ItemData("Accessory", code = 264_1026, classification = ItemClassification.useful, ), + "Thundara Ring": KH1ItemData("Accessory", code = 264_1027, classification = ItemClassification.useful, ), + "Thundaga Ring": KH1ItemData("Accessory", code = 264_1028, classification = ItemClassification.useful, ), + "Ability Stud": KH1ItemData("Accessory", code = 264_1029, classification = ItemClassification.useful, ), + "Guard Earring": KH1ItemData("Accessory", code = 264_1030, classification = ItemClassification.useful, ), + "Master Earring": KH1ItemData("Accessory", code = 264_1031, classification = ItemClassification.useful, ), + "Chaos Ring": KH1ItemData("Accessory", code = 264_1032, classification = ItemClassification.useful, ), + "Dark Ring": KH1ItemData("Accessory", code = 264_1033, classification = ItemClassification.useful, ), + "Element Ring": KH1ItemData("Accessory", code = 264_1034, classification = ItemClassification.useful, ), + "Three Stars": KH1ItemData("Accessory", code = 264_1035, classification = ItemClassification.useful, ), + "Power Chain": KH1ItemData("Accessory", code = 264_1036, classification = ItemClassification.useful, ), + "Golem Chain": KH1ItemData("Accessory", code = 264_1037, classification = ItemClassification.useful, ), + "Titan Chain": KH1ItemData("Accessory", code = 264_1038, classification = ItemClassification.useful, ), + "Energy Bangle": KH1ItemData("Accessory", code = 264_1039, classification = ItemClassification.useful, ), + "Angel Bangle": KH1ItemData("Accessory", code = 264_1040, classification = ItemClassification.useful, ), + "Gaia Bangle": KH1ItemData("Accessory", code = 264_1041, classification = ItemClassification.useful, ), + "Magic Armlet": KH1ItemData("Accessory", code = 264_1042, classification = ItemClassification.useful, ), + "Rune Armlet": KH1ItemData("Accessory", code = 264_1043, classification = ItemClassification.useful, ), + "Atlas Armlet": KH1ItemData("Accessory", code = 264_1044, classification = ItemClassification.useful, ), + "Heartguard": KH1ItemData("Accessory", code = 264_1045, classification = ItemClassification.useful, ), + "Ribbon": KH1ItemData("Accessory", code = 264_1046, classification = ItemClassification.useful, ), + "Crystal Crown": KH1ItemData("Accessory", code = 264_1047, classification = ItemClassification.useful, ), + "Brave Warrior": KH1ItemData("Accessory", code = 264_1048, classification = ItemClassification.useful, ), + "Ifrit's Horn": KH1ItemData("Accessory", code = 264_1049, classification = ItemClassification.useful, ), + "Inferno Band": KH1ItemData("Accessory", code = 264_1050, classification = ItemClassification.useful, ), + "White Fang": KH1ItemData("Accessory", code = 264_1051, classification = ItemClassification.useful, ), + "Ray of Light": KH1ItemData("Accessory", code = 264_1052, classification = ItemClassification.useful, ), + "Holy Circlet": KH1ItemData("Accessory", code = 264_1053, classification = ItemClassification.useful, ), + "Raven's Claw": KH1ItemData("Accessory", code = 264_1054, classification = ItemClassification.useful, ), + "Omega Arts": KH1ItemData("Accessory", code = 264_1055, classification = ItemClassification.useful, ), + "EXP Earring": KH1ItemData("Accessory", code = 264_1056, classification = ItemClassification.useful, ), + #"A41": KH1ItemData("Accessory", code = 264_1057, classification = ItemClassification.useful, ), + "EXP Ring": KH1ItemData("Accessory", code = 264_1058, classification = ItemClassification.useful, ), + "EXP Bracelet": KH1ItemData("Accessory", code = 264_1059, classification = ItemClassification.useful, ), + "EXP Necklace": KH1ItemData("Accessory", code = 264_1060, classification = ItemClassification.useful, ), + "Firagun Band": KH1ItemData("Accessory", code = 264_1061, classification = ItemClassification.useful, ), + "Blizzagun Band": KH1ItemData("Accessory", code = 264_1062, classification = ItemClassification.useful, ), + "Thundagun Band": KH1ItemData("Accessory", code = 264_1063, classification = ItemClassification.useful, ), + "Ifrit Belt": KH1ItemData("Accessory", code = 264_1064, classification = ItemClassification.useful, ), + "Shiva Belt": KH1ItemData("Accessory", code = 264_1065, classification = ItemClassification.useful, ), + "Ramuh Belt": KH1ItemData("Accessory", code = 264_1066, classification = ItemClassification.useful, ), + "Moogle Badge": KH1ItemData("Accessory", code = 264_1067, classification = ItemClassification.useful, ), + "Cosmic Arts": KH1ItemData("Accessory", code = 264_1068, classification = ItemClassification.useful, ), + "Royal Crown": KH1ItemData("Accessory", code = 264_1069, classification = ItemClassification.useful, ), + "Prime Cap": KH1ItemData("Accessory", code = 264_1070, classification = ItemClassification.useful, ), + "Obsidian Ring": KH1ItemData("Accessory", code = 264_1071, classification = ItemClassification.useful, ), + #"A56": KH1ItemData("Accessory", code = 264_1072, classification = ItemClassification.filler, ), + #"A57": KH1ItemData("Accessory", code = 264_1073, classification = ItemClassification.filler, ), + #"A58": KH1ItemData("Accessory", code = 264_1074, classification = ItemClassification.filler, ), + #"A59": KH1ItemData("Accessory", code = 264_1075, classification = ItemClassification.filler, ), + #"A60": KH1ItemData("Accessory", code = 264_1076, classification = ItemClassification.filler, ), + #"A61": KH1ItemData("Accessory", code = 264_1077, classification = ItemClassification.filler, ), + #"A62": KH1ItemData("Accessory", code = 264_1078, classification = ItemClassification.filler, ), + #"A63": KH1ItemData("Accessory", code = 264_1079, classification = ItemClassification.filler, ), + #"A64": KH1ItemData("Accessory", code = 264_1080, classification = ItemClassification.filler, ), + #"Kingdom Key": KH1ItemData("Keyblades", code = 264_1081, classification = ItemClassification.useful, ), + #"Dream Sword": KH1ItemData("Keyblades", code = 264_1082, classification = ItemClassification.useful, ), + #"Dream Shield": KH1ItemData("Keyblades", code = 264_1083, classification = ItemClassification.useful, ), + #"Dream Rod": KH1ItemData("Keyblades", code = 264_1084, classification = ItemClassification.useful, ), + "Wooden Sword": KH1ItemData("Keyblades", code = 264_1085, classification = ItemClassification.useful, ), + "Jungle King": KH1ItemData("Keyblades", code = 264_1086, classification = ItemClassification.progression, ), + "Three Wishes": KH1ItemData("Keyblades", code = 264_1087, classification = ItemClassification.progression, ), + "Fairy Harp": KH1ItemData("Keyblades", code = 264_1088, classification = ItemClassification.progression, ), + "Pumpkinhead": KH1ItemData("Keyblades", code = 264_1089, classification = ItemClassification.progression, ), + "Crabclaw": KH1ItemData("Keyblades", code = 264_1090, classification = ItemClassification.useful, ), + "Divine Rose": KH1ItemData("Keyblades", code = 264_1091, classification = ItemClassification.progression, ), + "Spellbinder": KH1ItemData("Keyblades", code = 264_1092, classification = ItemClassification.useful, ), + "Olympia": KH1ItemData("Keyblades", code = 264_1093, classification = ItemClassification.progression, ), + "Lionheart": KH1ItemData("Keyblades", code = 264_1094, classification = ItemClassification.progression, ), + "Metal Chocobo": KH1ItemData("Keyblades", code = 264_1095, classification = ItemClassification.useful, ), + "Oathkeeper": KH1ItemData("Keyblades", code = 264_1096, classification = ItemClassification.progression, ), + "Oblivion": KH1ItemData("Keyblades", code = 264_1097, classification = ItemClassification.progression, ), + "Lady Luck": KH1ItemData("Keyblades", code = 264_1098, classification = ItemClassification.progression, ), + "Wishing Star": KH1ItemData("Keyblades", code = 264_1099, classification = ItemClassification.progression, ), + "Ultima Weapon": KH1ItemData("Keyblades", code = 264_1100, classification = ItemClassification.useful, ), + "Diamond Dust": KH1ItemData("Keyblades", code = 264_1101, classification = ItemClassification.useful, ), + "One-Winged Angel": KH1ItemData("Keyblades", code = 264_1102, classification = ItemClassification.useful, ), + #"Mage's Staff": KH1ItemData("Weapons", code = 264_1103, classification = ItemClassification.filler, ), + "Morning Star": KH1ItemData("Weapons", code = 264_1104, classification = ItemClassification.useful, ), + "Shooting Star": KH1ItemData("Weapons", code = 264_1105, classification = ItemClassification.useful, ), + "Magus Staff": KH1ItemData("Weapons", code = 264_1106, classification = ItemClassification.useful, ), + "Wisdom Staff": KH1ItemData("Weapons", code = 264_1107, classification = ItemClassification.useful, ), + "Warhammer": KH1ItemData("Weapons", code = 264_1108, classification = ItemClassification.useful, ), + "Silver Mallet": KH1ItemData("Weapons", code = 264_1109, classification = ItemClassification.useful, ), + "Grand Mallet": KH1ItemData("Weapons", code = 264_1110, classification = ItemClassification.useful, ), + "Lord Fortune": KH1ItemData("Weapons", code = 264_1111, classification = ItemClassification.useful, ), + "Violetta": KH1ItemData("Weapons", code = 264_1112, classification = ItemClassification.useful, ), + "Dream Rod (Donald)": KH1ItemData("Weapons", code = 264_1113, classification = ItemClassification.useful, ), + "Save the Queen": KH1ItemData("Weapons", code = 264_1114, classification = ItemClassification.useful, ), + "Wizard's Relic": KH1ItemData("Weapons", code = 264_1115, classification = ItemClassification.useful, ), + "Meteor Strike": KH1ItemData("Weapons", code = 264_1116, classification = ItemClassification.useful, ), + "Fantasista": KH1ItemData("Weapons", code = 264_1117, classification = ItemClassification.useful, ), + #"Unused (Donald)": KH1ItemData("Weapons", code = 264_1118, classification = ItemClassification.filler, ), + #"Knight's Shield": KH1ItemData("Weapons", code = 264_1119, classification = ItemClassification.filler, ), + "Mythril Shield": KH1ItemData("Weapons", code = 264_1120, classification = ItemClassification.useful, ), + "Onyx Shield": KH1ItemData("Weapons", code = 264_1121, classification = ItemClassification.useful, ), + "Stout Shield": KH1ItemData("Weapons", code = 264_1122, classification = ItemClassification.useful, ), + "Golem Shield": KH1ItemData("Weapons", code = 264_1123, classification = ItemClassification.useful, ), + "Adamant Shield": KH1ItemData("Weapons", code = 264_1124, classification = ItemClassification.useful, ), + "Smasher": KH1ItemData("Weapons", code = 264_1125, classification = ItemClassification.useful, ), + "Gigas Fist": KH1ItemData("Weapons", code = 264_1126, classification = ItemClassification.useful, ), + "Genji Shield": KH1ItemData("Weapons", code = 264_1127, classification = ItemClassification.useful, ), + "Herc's Shield": KH1ItemData("Weapons", code = 264_1128, classification = ItemClassification.useful, ), + "Dream Shield (Goofy)": KH1ItemData("Weapons", code = 264_1129, classification = ItemClassification.useful, ), + "Save the King": KH1ItemData("Weapons", code = 264_1130, classification = ItemClassification.useful, ), + "Defender": KH1ItemData("Weapons", code = 264_1131, classification = ItemClassification.useful, ), + "Mighty Shield": KH1ItemData("Weapons", code = 264_1132, classification = ItemClassification.useful, ), + "Seven Elements": KH1ItemData("Weapons", code = 264_1133, classification = ItemClassification.useful, ), + #"Unused (Goofy)": KH1ItemData("Weapons", code = 264_1134, classification = ItemClassification.filler, ), + #"Spear": KH1ItemData("Weapons", code = 264_1135, classification = ItemClassification.filler, ), + #"No Weapon": KH1ItemData("Weapons", code = 264_1136, classification = ItemClassification.filler, ), + #"Genie": KH1ItemData("Weapons", code = 264_1137, classification = ItemClassification.filler, ), + #"No Weapon": KH1ItemData("Weapons", code = 264_1138, classification = ItemClassification.filler, ), + #"No Weapon": KH1ItemData("Weapons", code = 264_1139, classification = ItemClassification.filler, ), + #"Tinker Bell": KH1ItemData("Weapons", code = 264_1140, classification = ItemClassification.filler, ), + #"Claws": KH1ItemData("Weapons", code = 264_1141, classification = ItemClassification.filler, ), + "Tent": KH1ItemData("Camping", code = 264_1142, classification = ItemClassification.filler, ), + "Camping Set": KH1ItemData("Camping", code = 264_1143, classification = ItemClassification.filler, ), + "Cottage": KH1ItemData("Camping", code = 264_1144, classification = ItemClassification.filler, ), + #"C04": KH1ItemData("Camping", code = 264_1145, classification = ItemClassification.filler, ), + #"C05": KH1ItemData("Camping", code = 264_1146, classification = ItemClassification.filler, ), + #"C06": KH1ItemData("Camping", code = 264_1147, classification = ItemClassification.filler, ), + #"C07": KH1ItemData("Camping", code = 264_1148, classification = ItemClassification.filler, ), + "Ansem's Report 11": KH1ItemData("Reports", code = 264_1149, classification = ItemClassification.progression, ), + "Ansem's Report 12": KH1ItemData("Reports", code = 264_1150, classification = ItemClassification.progression, ), + "Ansem's Report 13": KH1ItemData("Reports", code = 264_1151, classification = ItemClassification.progression, ), + "Power Up": KH1ItemData("Stat Ups", code = 264_1152, classification = ItemClassification.filler, ), + "Defense Up": KH1ItemData("Stat Ups", code = 264_1153, classification = ItemClassification.filler, ), + "AP Up": KH1ItemData("Stat Ups", code = 264_1154, classification = ItemClassification.filler, ), + #"Serenity Power": KH1ItemData("Synthesis", code = 264_1155, classification = ItemClassification.filler, ), + #"Dark Matter": KH1ItemData("Synthesis", code = 264_1156, classification = ItemClassification.filler, ), + #"Mythril Stone": KH1ItemData("Synthesis", code = 264_1157, classification = ItemClassification.filler, ), + "Fire Arts": KH1ItemData("Key", code = 264_1158, classification = ItemClassification.progression, ), + "Blizzard Arts": KH1ItemData("Key", code = 264_1159, classification = ItemClassification.progression, ), + "Thunder Arts": KH1ItemData("Key", code = 264_1160, classification = ItemClassification.progression, ), + "Cure Arts": KH1ItemData("Key", code = 264_1161, classification = ItemClassification.progression, ), + "Gravity Arts": KH1ItemData("Key", code = 264_1162, classification = ItemClassification.progression, ), + "Stop Arts": KH1ItemData("Key", code = 264_1163, classification = ItemClassification.progression, ), + "Aero Arts": KH1ItemData("Key", code = 264_1164, classification = ItemClassification.progression, ), + #"Shiitank Rank": KH1ItemData("Synthesis", code = 264_1165, classification = ItemClassification.filler, ), + #"Matsutake Rank": KH1ItemData("Synthesis", code = 264_1166, classification = ItemClassification.filler, ), + #"Mystery Mold": KH1ItemData("Synthesis", code = 264_1167, classification = ItemClassification.filler, ), + "Ansem's Report 1": KH1ItemData("Reports", code = 264_1168, classification = ItemClassification.progression, ), + "Ansem's Report 2": KH1ItemData("Reports", code = 264_1169, classification = ItemClassification.progression, ), + "Ansem's Report 3": KH1ItemData("Reports", code = 264_1170, classification = ItemClassification.progression, ), + "Ansem's Report 4": KH1ItemData("Reports", code = 264_1171, classification = ItemClassification.progression, ), + "Ansem's Report 5": KH1ItemData("Reports", code = 264_1172, classification = ItemClassification.progression, ), + "Ansem's Report 6": KH1ItemData("Reports", code = 264_1173, classification = ItemClassification.progression, ), + "Ansem's Report 7": KH1ItemData("Reports", code = 264_1174, classification = ItemClassification.progression, ), + "Ansem's Report 8": KH1ItemData("Reports", code = 264_1175, classification = ItemClassification.progression, ), + "Ansem's Report 9": KH1ItemData("Reports", code = 264_1176, classification = ItemClassification.progression, ), + "Ansem's Report 10": KH1ItemData("Reports", code = 264_1177, classification = ItemClassification.progression, ), + #"Khama Vol. 8": KH1ItemData("Key", code = 264_1178, classification = ItemClassification.progression, ), + #"Salegg Vol. 6": KH1ItemData("Key", code = 264_1179, classification = ItemClassification.progression, ), + #"Azal Vol. 3": KH1ItemData("Key", code = 264_1180, classification = ItemClassification.progression, ), + #"Mava Vol. 3": KH1ItemData("Key", code = 264_1181, classification = ItemClassification.progression, ), + #"Mava Vol. 6": KH1ItemData("Key", code = 264_1182, classification = ItemClassification.progression, ), + "Theon Vol. 6": KH1ItemData("Key", code = 264_1183, classification = ItemClassification.progression, ), + #"Nahara Vol. 5": KH1ItemData("Key", code = 264_1184, classification = ItemClassification.progression, ), + #"Hafet Vol. 4": KH1ItemData("Key", code = 264_1185, classification = ItemClassification.progression, ), + "Empty Bottle": KH1ItemData("Key", code = 264_1186, classification = ItemClassification.progression, max_quantity = 6 ), + #"Old Book": KH1ItemData("Key", code = 264_1187, classification = ItemClassification.progression, ), + "Emblem Piece (Flame)": KH1ItemData("Key", code = 264_1188, classification = ItemClassification.progression, ), + "Emblem Piece (Chest)": KH1ItemData("Key", code = 264_1189, classification = ItemClassification.progression, ), + "Emblem Piece (Statue)": KH1ItemData("Key", code = 264_1190, classification = ItemClassification.progression, ), + "Emblem Piece (Fountain)": KH1ItemData("Key", code = 264_1191, classification = ItemClassification.progression, ), + #"Log": KH1ItemData("Key", code = 264_1192, classification = ItemClassification.progression, ), + #"Cloth": KH1ItemData("Key", code = 264_1193, classification = ItemClassification.progression, ), + #"Rope": KH1ItemData("Key", code = 264_1194, classification = ItemClassification.progression, ), + #"Seagull Egg": KH1ItemData("Key", code = 264_1195, classification = ItemClassification.progression, ), + #"Fish": KH1ItemData("Key", code = 264_1196, classification = ItemClassification.progression, ), + #"Mushroom": KH1ItemData("Key", code = 264_1197, classification = ItemClassification.progression, ), + #"Coconut": KH1ItemData("Key", code = 264_1198, classification = ItemClassification.progression, ), + #"Drinking Water": KH1ItemData("Key", code = 264_1199, classification = ItemClassification.progression, ), + #"Navi-G Piece 1": KH1ItemData("Key", code = 264_1200, classification = ItemClassification.progression, ), + #"Navi-G Piece 2": KH1ItemData("Key", code = 264_1201, classification = ItemClassification.progression, ), + #"Navi-Gummi Unused": KH1ItemData("Key", code = 264_1202, classification = ItemClassification.progression, ), + #"Navi-G Piece 3": KH1ItemData("Key", code = 264_1203, classification = ItemClassification.progression, ), + #"Navi-G Piece 4": KH1ItemData("Key", code = 264_1204, classification = ItemClassification.progression, ), + #"Navi-Gummi": KH1ItemData("Key", code = 264_1205, classification = ItemClassification.progression, ), + #"Watergleam": KH1ItemData("Key", code = 264_1206, classification = ItemClassification.progression, ), + #"Naturespark": KH1ItemData("Key", code = 264_1207, classification = ItemClassification.progression, ), + #"Fireglow": KH1ItemData("Key", code = 264_1208, classification = ItemClassification.progression, ), + #"Earthshine": KH1ItemData("Key", code = 264_1209, classification = ItemClassification.progression, ), + "Crystal Trident": KH1ItemData("Key", code = 264_1210, classification = ItemClassification.progression, ), + "Postcard": KH1ItemData("Key", code = 264_1211, classification = ItemClassification.progression, max_quantity = 10), + "Torn Page 1": KH1ItemData("Torn Pages", code = 264_1212, classification = ItemClassification.progression, ), + "Torn Page 2": KH1ItemData("Torn Pages", code = 264_1213, classification = ItemClassification.progression, ), + "Torn Page 3": KH1ItemData("Torn Pages", code = 264_1214, classification = ItemClassification.progression, ), + "Torn Page 4": KH1ItemData("Torn Pages", code = 264_1215, classification = ItemClassification.progression, ), + "Torn Page 5": KH1ItemData("Torn Pages", code = 264_1216, classification = ItemClassification.progression, ), + "Slides": KH1ItemData("Key", code = 264_1217, classification = ItemClassification.progression, ), + #"Slide 2": KH1ItemData("Key", code = 264_1218, classification = ItemClassification.progression, ), + #"Slide 3": KH1ItemData("Key", code = 264_1219, classification = ItemClassification.progression, ), + #"Slide 4": KH1ItemData("Key", code = 264_1220, classification = ItemClassification.progression, ), + #"Slide 5": KH1ItemData("Key", code = 264_1221, classification = ItemClassification.progression, ), + #"Slide 6": KH1ItemData("Key", code = 264_1222, classification = ItemClassification.progression, ), + "Footprints": KH1ItemData("Key", code = 264_1223, classification = ItemClassification.progression, ), + #"Claw Marks": KH1ItemData("Key", code = 264_1224, classification = ItemClassification.progression, ), + #"Stench": KH1ItemData("Key", code = 264_1225, classification = ItemClassification.progression, ), + #"Antenna": KH1ItemData("Key", code = 264_1226, classification = ItemClassification.progression, ), + "Forget-Me-Not": KH1ItemData("Key", code = 264_1227, classification = ItemClassification.progression, ), + "Jack-In-The-Box": KH1ItemData("Key", code = 264_1228, classification = ItemClassification.progression, ), + "Entry Pass": KH1ItemData("Key", code = 264_1229, classification = ItemClassification.progression, ), + #"Hero License": KH1ItemData("Key", code = 264_1230, classification = ItemClassification.progression, ), + #"Pretty Stone": KH1ItemData("Synthesis", code = 264_1231, classification = ItemClassification.filler, ), + #"N41": KH1ItemData("Synthesis", code = 264_1232, classification = ItemClassification.filler, ), + #"Lucid Shard": KH1ItemData("Synthesis", code = 264_1233, classification = ItemClassification.filler, ), + #"Lucid Gem": KH1ItemData("Synthesis", code = 264_1234, classification = ItemClassification.filler, ), + #"Lucid Crystal": KH1ItemData("Synthesis", code = 264_1235, classification = ItemClassification.filler, ), + #"Spirit Shard": KH1ItemData("Synthesis", code = 264_1236, classification = ItemClassification.filler, ), + #"Spirit Gem": KH1ItemData("Synthesis", code = 264_1237, classification = ItemClassification.filler, ), + #"Power Shard": KH1ItemData("Synthesis", code = 264_1238, classification = ItemClassification.filler, ), + #"Power Gem": KH1ItemData("Synthesis", code = 264_1239, classification = ItemClassification.filler, ), + #"Power Crystal": KH1ItemData("Synthesis", code = 264_1240, classification = ItemClassification.filler, ), + #"Blaze Shard": KH1ItemData("Synthesis", code = 264_1241, classification = ItemClassification.filler, ), + #"Blaze Gem": KH1ItemData("Synthesis", code = 264_1242, classification = ItemClassification.filler, ), + #"Frost Shard": KH1ItemData("Synthesis", code = 264_1243, classification = ItemClassification.filler, ), + #"Frost Gem": KH1ItemData("Synthesis", code = 264_1244, classification = ItemClassification.filler, ), + #"Thunder Shard": KH1ItemData("Synthesis", code = 264_1245, classification = ItemClassification.filler, ), + #"Thunder Gem": KH1ItemData("Synthesis", code = 264_1246, classification = ItemClassification.filler, ), + #"Shiny Crystal": KH1ItemData("Synthesis", code = 264_1247, classification = ItemClassification.filler, ), + #"Bright Shard": KH1ItemData("Synthesis", code = 264_1248, classification = ItemClassification.filler, ), + #"Bright Gem": KH1ItemData("Synthesis", code = 264_1249, classification = ItemClassification.filler, ), + #"Bright Crystal": KH1ItemData("Synthesis", code = 264_1250, classification = ItemClassification.filler, ), + #"Mystery Goo": KH1ItemData("Synthesis", code = 264_1251, classification = ItemClassification.filler, ), + #"Gale": KH1ItemData("Synthesis", code = 264_1252, classification = ItemClassification.filler, ), + #"Mythril Shard": KH1ItemData("Synthesis", code = 264_1253, classification = ItemClassification.filler, ), + #"Mythril": KH1ItemData("Synthesis", code = 264_1254, classification = ItemClassification.filler, ), + #"Orichalcum": KH1ItemData("Synthesis", code = 264_1255, classification = ItemClassification.filler, ), + "High Jump": KH1ItemData("Shared Abilities", code = 264_2001, classification = ItemClassification.progression, ), + "Mermaid Kick": KH1ItemData("Shared Abilities", code = 264_2002, classification = ItemClassification.progression, ), + "Progressive Glide": KH1ItemData("Shared Abilities", code = 264_2003, classification = ItemClassification.progression, max_quantity = 2 ), + #"Superglide": KH1ItemData("Shared Abilities", code = 264_2004, classification = ItemClassification.progression, ), + "Puppy 01": KH1ItemData("Puppies", code = 264_2101, classification = ItemClassification.progression, ), + "Puppy 02": KH1ItemData("Puppies", code = 264_2102, classification = ItemClassification.progression, ), + "Puppy 03": KH1ItemData("Puppies", code = 264_2103, classification = ItemClassification.progression, ), + "Puppy 04": KH1ItemData("Puppies", code = 264_2104, classification = ItemClassification.progression, ), + "Puppy 05": KH1ItemData("Puppies", code = 264_2105, classification = ItemClassification.progression, ), + "Puppy 06": KH1ItemData("Puppies", code = 264_2106, classification = ItemClassification.progression, ), + "Puppy 07": KH1ItemData("Puppies", code = 264_2107, classification = ItemClassification.progression, ), + "Puppy 08": KH1ItemData("Puppies", code = 264_2108, classification = ItemClassification.progression, ), + "Puppy 09": KH1ItemData("Puppies", code = 264_2109, classification = ItemClassification.progression, ), + "Puppy 10": KH1ItemData("Puppies", code = 264_2110, classification = ItemClassification.progression, ), + "Puppy 11": KH1ItemData("Puppies", code = 264_2111, classification = ItemClassification.progression, ), + "Puppy 12": KH1ItemData("Puppies", code = 264_2112, classification = ItemClassification.progression, ), + "Puppy 13": KH1ItemData("Puppies", code = 264_2113, classification = ItemClassification.progression, ), + "Puppy 14": KH1ItemData("Puppies", code = 264_2114, classification = ItemClassification.progression, ), + "Puppy 15": KH1ItemData("Puppies", code = 264_2115, classification = ItemClassification.progression, ), + "Puppy 16": KH1ItemData("Puppies", code = 264_2116, classification = ItemClassification.progression, ), + "Puppy 17": KH1ItemData("Puppies", code = 264_2117, classification = ItemClassification.progression, ), + "Puppy 18": KH1ItemData("Puppies", code = 264_2118, classification = ItemClassification.progression, ), + "Puppy 19": KH1ItemData("Puppies", code = 264_2119, classification = ItemClassification.progression, ), + "Puppy 20": KH1ItemData("Puppies", code = 264_2120, classification = ItemClassification.progression, ), + "Puppy 21": KH1ItemData("Puppies", code = 264_2121, classification = ItemClassification.progression, ), + "Puppy 22": KH1ItemData("Puppies", code = 264_2122, classification = ItemClassification.progression, ), + "Puppy 23": KH1ItemData("Puppies", code = 264_2123, classification = ItemClassification.progression, ), + "Puppy 24": KH1ItemData("Puppies", code = 264_2124, classification = ItemClassification.progression, ), + "Puppy 25": KH1ItemData("Puppies", code = 264_2125, classification = ItemClassification.progression, ), + "Puppy 26": KH1ItemData("Puppies", code = 264_2126, classification = ItemClassification.progression, ), + "Puppy 27": KH1ItemData("Puppies", code = 264_2127, classification = ItemClassification.progression, ), + "Puppy 28": KH1ItemData("Puppies", code = 264_2128, classification = ItemClassification.progression, ), + "Puppy 29": KH1ItemData("Puppies", code = 264_2129, classification = ItemClassification.progression, ), + "Puppy 30": KH1ItemData("Puppies", code = 264_2130, classification = ItemClassification.progression, ), + "Puppy 31": KH1ItemData("Puppies", code = 264_2131, classification = ItemClassification.progression, ), + "Puppy 32": KH1ItemData("Puppies", code = 264_2132, classification = ItemClassification.progression, ), + "Puppy 33": KH1ItemData("Puppies", code = 264_2133, classification = ItemClassification.progression, ), + "Puppy 34": KH1ItemData("Puppies", code = 264_2134, classification = ItemClassification.progression, ), + "Puppy 35": KH1ItemData("Puppies", code = 264_2135, classification = ItemClassification.progression, ), + "Puppy 36": KH1ItemData("Puppies", code = 264_2136, classification = ItemClassification.progression, ), + "Puppy 37": KH1ItemData("Puppies", code = 264_2137, classification = ItemClassification.progression, ), + "Puppy 38": KH1ItemData("Puppies", code = 264_2138, classification = ItemClassification.progression, ), + "Puppy 39": KH1ItemData("Puppies", code = 264_2139, classification = ItemClassification.progression, ), + "Puppy 40": KH1ItemData("Puppies", code = 264_2140, classification = ItemClassification.progression, ), + "Puppy 41": KH1ItemData("Puppies", code = 264_2141, classification = ItemClassification.progression, ), + "Puppy 42": KH1ItemData("Puppies", code = 264_2142, classification = ItemClassification.progression, ), + "Puppy 43": KH1ItemData("Puppies", code = 264_2143, classification = ItemClassification.progression, ), + "Puppy 44": KH1ItemData("Puppies", code = 264_2144, classification = ItemClassification.progression, ), + "Puppy 45": KH1ItemData("Puppies", code = 264_2145, classification = ItemClassification.progression, ), + "Puppy 46": KH1ItemData("Puppies", code = 264_2146, classification = ItemClassification.progression, ), + "Puppy 47": KH1ItemData("Puppies", code = 264_2147, classification = ItemClassification.progression, ), + "Puppy 48": KH1ItemData("Puppies", code = 264_2148, classification = ItemClassification.progression, ), + "Puppy 49": KH1ItemData("Puppies", code = 264_2149, classification = ItemClassification.progression, ), + "Puppy 50": KH1ItemData("Puppies", code = 264_2150, classification = ItemClassification.progression, ), + "Puppy 51": KH1ItemData("Puppies", code = 264_2151, classification = ItemClassification.progression, ), + "Puppy 52": KH1ItemData("Puppies", code = 264_2152, classification = ItemClassification.progression, ), + "Puppy 53": KH1ItemData("Puppies", code = 264_2153, classification = ItemClassification.progression, ), + "Puppy 54": KH1ItemData("Puppies", code = 264_2154, classification = ItemClassification.progression, ), + "Puppy 55": KH1ItemData("Puppies", code = 264_2155, classification = ItemClassification.progression, ), + "Puppy 56": KH1ItemData("Puppies", code = 264_2156, classification = ItemClassification.progression, ), + "Puppy 57": KH1ItemData("Puppies", code = 264_2157, classification = ItemClassification.progression, ), + "Puppy 58": KH1ItemData("Puppies", code = 264_2158, classification = ItemClassification.progression, ), + "Puppy 59": KH1ItemData("Puppies", code = 264_2159, classification = ItemClassification.progression, ), + "Puppy 60": KH1ItemData("Puppies", code = 264_2160, classification = ItemClassification.progression, ), + "Puppy 61": KH1ItemData("Puppies", code = 264_2161, classification = ItemClassification.progression, ), + "Puppy 62": KH1ItemData("Puppies", code = 264_2162, classification = ItemClassification.progression, ), + "Puppy 63": KH1ItemData("Puppies", code = 264_2163, classification = ItemClassification.progression, ), + "Puppy 64": KH1ItemData("Puppies", code = 264_2164, classification = ItemClassification.progression, ), + "Puppy 65": KH1ItemData("Puppies", code = 264_2165, classification = ItemClassification.progression, ), + "Puppy 66": KH1ItemData("Puppies", code = 264_2166, classification = ItemClassification.progression, ), + "Puppy 67": KH1ItemData("Puppies", code = 264_2167, classification = ItemClassification.progression, ), + "Puppy 68": KH1ItemData("Puppies", code = 264_2168, classification = ItemClassification.progression, ), + "Puppy 69": KH1ItemData("Puppies", code = 264_2169, classification = ItemClassification.progression, ), + "Puppy 70": KH1ItemData("Puppies", code = 264_2170, classification = ItemClassification.progression, ), + "Puppy 71": KH1ItemData("Puppies", code = 264_2171, classification = ItemClassification.progression, ), + "Puppy 72": KH1ItemData("Puppies", code = 264_2172, classification = ItemClassification.progression, ), + "Puppy 73": KH1ItemData("Puppies", code = 264_2173, classification = ItemClassification.progression, ), + "Puppy 74": KH1ItemData("Puppies", code = 264_2174, classification = ItemClassification.progression, ), + "Puppy 75": KH1ItemData("Puppies", code = 264_2175, classification = ItemClassification.progression, ), + "Puppy 76": KH1ItemData("Puppies", code = 264_2176, classification = ItemClassification.progression, ), + "Puppy 77": KH1ItemData("Puppies", code = 264_2177, classification = ItemClassification.progression, ), + "Puppy 78": KH1ItemData("Puppies", code = 264_2178, classification = ItemClassification.progression, ), + "Puppy 79": KH1ItemData("Puppies", code = 264_2179, classification = ItemClassification.progression, ), + "Puppy 80": KH1ItemData("Puppies", code = 264_2180, classification = ItemClassification.progression, ), + "Puppy 81": KH1ItemData("Puppies", code = 264_2181, classification = ItemClassification.progression, ), + "Puppy 82": KH1ItemData("Puppies", code = 264_2182, classification = ItemClassification.progression, ), + "Puppy 83": KH1ItemData("Puppies", code = 264_2183, classification = ItemClassification.progression, ), + "Puppy 84": KH1ItemData("Puppies", code = 264_2184, classification = ItemClassification.progression, ), + "Puppy 85": KH1ItemData("Puppies", code = 264_2185, classification = ItemClassification.progression, ), + "Puppy 86": KH1ItemData("Puppies", code = 264_2186, classification = ItemClassification.progression, ), + "Puppy 87": KH1ItemData("Puppies", code = 264_2187, classification = ItemClassification.progression, ), + "Puppy 88": KH1ItemData("Puppies", code = 264_2188, classification = ItemClassification.progression, ), + "Puppy 89": KH1ItemData("Puppies", code = 264_2189, classification = ItemClassification.progression, ), + "Puppy 90": KH1ItemData("Puppies", code = 264_2190, classification = ItemClassification.progression, ), + "Puppy 91": KH1ItemData("Puppies", code = 264_2191, classification = ItemClassification.progression, ), + "Puppy 92": KH1ItemData("Puppies", code = 264_2192, classification = ItemClassification.progression, ), + "Puppy 93": KH1ItemData("Puppies", code = 264_2193, classification = ItemClassification.progression, ), + "Puppy 94": KH1ItemData("Puppies", code = 264_2194, classification = ItemClassification.progression, ), + "Puppy 95": KH1ItemData("Puppies", code = 264_2195, classification = ItemClassification.progression, ), + "Puppy 96": KH1ItemData("Puppies", code = 264_2196, classification = ItemClassification.progression, ), + "Puppy 97": KH1ItemData("Puppies", code = 264_2197, classification = ItemClassification.progression, ), + "Puppy 98": KH1ItemData("Puppies", code = 264_2198, classification = ItemClassification.progression, ), + "Puppy 99": KH1ItemData("Puppies", code = 264_2199, classification = ItemClassification.progression, ), + "Puppies 01-03": KH1ItemData("Puppies", code = 264_2201, classification = ItemClassification.progression, ), + "Puppies 04-06": KH1ItemData("Puppies", code = 264_2202, classification = ItemClassification.progression, ), + "Puppies 07-09": KH1ItemData("Puppies", code = 264_2203, classification = ItemClassification.progression, ), + "Puppies 10-12": KH1ItemData("Puppies", code = 264_2204, classification = ItemClassification.progression, ), + "Puppies 13-15": KH1ItemData("Puppies", code = 264_2205, classification = ItemClassification.progression, ), + "Puppies 16-18": KH1ItemData("Puppies", code = 264_2206, classification = ItemClassification.progression, ), + "Puppies 19-21": KH1ItemData("Puppies", code = 264_2207, classification = ItemClassification.progression, ), + "Puppies 22-24": KH1ItemData("Puppies", code = 264_2208, classification = ItemClassification.progression, ), + "Puppies 25-27": KH1ItemData("Puppies", code = 264_2209, classification = ItemClassification.progression, ), + "Puppies 28-30": KH1ItemData("Puppies", code = 264_2210, classification = ItemClassification.progression, ), + "Puppies 31-33": KH1ItemData("Puppies", code = 264_2211, classification = ItemClassification.progression, ), + "Puppies 34-36": KH1ItemData("Puppies", code = 264_2212, classification = ItemClassification.progression, ), + "Puppies 37-39": KH1ItemData("Puppies", code = 264_2213, classification = ItemClassification.progression, ), + "Puppies 40-42": KH1ItemData("Puppies", code = 264_2214, classification = ItemClassification.progression, ), + "Puppies 43-45": KH1ItemData("Puppies", code = 264_2215, classification = ItemClassification.progression, ), + "Puppies 46-48": KH1ItemData("Puppies", code = 264_2216, classification = ItemClassification.progression, ), + "Puppies 49-51": KH1ItemData("Puppies", code = 264_2217, classification = ItemClassification.progression, ), + "Puppies 52-54": KH1ItemData("Puppies", code = 264_2218, classification = ItemClassification.progression, ), + "Puppies 55-57": KH1ItemData("Puppies", code = 264_2219, classification = ItemClassification.progression, ), + "Puppies 58-60": KH1ItemData("Puppies", code = 264_2220, classification = ItemClassification.progression, ), + "Puppies 61-63": KH1ItemData("Puppies", code = 264_2221, classification = ItemClassification.progression, ), + "Puppies 64-66": KH1ItemData("Puppies", code = 264_2222, classification = ItemClassification.progression, ), + "Puppies 67-69": KH1ItemData("Puppies", code = 264_2223, classification = ItemClassification.progression, ), + "Puppies 70-72": KH1ItemData("Puppies", code = 264_2224, classification = ItemClassification.progression, ), + "Puppies 73-75": KH1ItemData("Puppies", code = 264_2225, classification = ItemClassification.progression, ), + "Puppies 76-78": KH1ItemData("Puppies", code = 264_2226, classification = ItemClassification.progression, ), + "Puppies 79-81": KH1ItemData("Puppies", code = 264_2227, classification = ItemClassification.progression, ), + "Puppies 82-84": KH1ItemData("Puppies", code = 264_2228, classification = ItemClassification.progression, ), + "Puppies 85-87": KH1ItemData("Puppies", code = 264_2229, classification = ItemClassification.progression, ), + "Puppies 88-90": KH1ItemData("Puppies", code = 264_2230, classification = ItemClassification.progression, ), + "Puppies 91-93": KH1ItemData("Puppies", code = 264_2231, classification = ItemClassification.progression, ), + "Puppies 94-96": KH1ItemData("Puppies", code = 264_2232, classification = ItemClassification.progression, ), + "Puppies 97-99": KH1ItemData("Puppies", code = 264_2233, classification = ItemClassification.progression, ), + "All Puppies": KH1ItemData("Puppies", code = 264_2240, classification = ItemClassification.progression, ), + "Treasure Magnet": KH1ItemData("Abilities", code = 264_3005, classification = ItemClassification.useful, max_quantity = 2 ), + "Combo Plus": KH1ItemData("Abilities", code = 264_3006, classification = ItemClassification.useful, max_quantity = 4 ), + "Air Combo Plus": KH1ItemData("Abilities", code = 264_3007, classification = ItemClassification.useful, max_quantity = 2 ), + "Critical Plus": KH1ItemData("Abilities", code = 264_3008, classification = ItemClassification.useful, max_quantity = 3 ), + #"Second Wind": KH1ItemData("Abilities", code = 264_3009, classification = ItemClassification.useful, ), + "Scan": KH1ItemData("Abilities", code = 264_3010, classification = ItemClassification.useful, ), + "Sonic Blade": KH1ItemData("Abilities", code = 264_3011, classification = ItemClassification.useful, ), + "Ars Arcanum": KH1ItemData("Abilities", code = 264_3012, classification = ItemClassification.useful, ), + "Strike Raid": KH1ItemData("Abilities", code = 264_3013, classification = ItemClassification.useful, ), + "Ragnarok": KH1ItemData("Abilities", code = 264_3014, classification = ItemClassification.useful, ), + "Trinity Limit": KH1ItemData("Abilities", code = 264_3015, classification = ItemClassification.useful, ), + "Cheer": KH1ItemData("Abilities", code = 264_3016, classification = ItemClassification.useful, ), + "Vortex": KH1ItemData("Abilities", code = 264_3017, classification = ItemClassification.useful, ), + "Aerial Sweep": KH1ItemData("Abilities", code = 264_3018, classification = ItemClassification.useful, ), + "Counterattack": KH1ItemData("Abilities", code = 264_3019, classification = ItemClassification.useful, ), + "Blitz": KH1ItemData("Abilities", code = 264_3020, classification = ItemClassification.useful, ), + "Guard": KH1ItemData("Abilities", code = 264_3021, classification = ItemClassification.progression, ), + "Dodge Roll": KH1ItemData("Abilities", code = 264_3022, classification = ItemClassification.progression, ), + "MP Haste": KH1ItemData("Abilities", code = 264_3023, classification = ItemClassification.useful, ), + "MP Rage": KH1ItemData("Abilities", code = 264_3024, classification = ItemClassification.progression, ), + "Second Chance": KH1ItemData("Abilities", code = 264_3025, classification = ItemClassification.progression, ), + "Berserk": KH1ItemData("Abilities", code = 264_3026, classification = ItemClassification.useful, ), + "Jackpot": KH1ItemData("Abilities", code = 264_3027, classification = ItemClassification.useful, ), + "Lucky Strike": KH1ItemData("Abilities", code = 264_3028, classification = ItemClassification.useful, ), + #"Charge": KH1ItemData("Abilities", code = 264_3029, classification = ItemClassification.useful, ), + #"Rocket": KH1ItemData("Abilities", code = 264_3030, classification = ItemClassification.useful, ), + #"Tornado": KH1ItemData("Abilities", code = 264_3031, classification = ItemClassification.useful, ), + #"MP Gift": KH1ItemData("Abilities", code = 264_3032, classification = ItemClassification.useful, ), + #"Raging Boar": KH1ItemData("Abilities", code = 264_3033, classification = ItemClassification.useful, ), + #"Asp's Bite": KH1ItemData("Abilities", code = 264_3034, classification = ItemClassification.useful, ), + #"Healing Herb": KH1ItemData("Abilities", code = 264_3035, classification = ItemClassification.useful, ), + #"Wind Armor": KH1ItemData("Abilities", code = 264_3036, classification = ItemClassification.useful, ), + #"Crescent": KH1ItemData("Abilities", code = 264_3037, classification = ItemClassification.useful, ), + #"Sandstorm": KH1ItemData("Abilities", code = 264_3038, classification = ItemClassification.useful, ), + #"Applause!": KH1ItemData("Abilities", code = 264_3039, classification = ItemClassification.useful, ), + #"Blazing Fury": KH1ItemData("Abilities", code = 264_3040, classification = ItemClassification.useful, ), + #"Icy Terror": KH1ItemData("Abilities", code = 264_3041, classification = ItemClassification.useful, ), + #"Bolts of Sorrow": KH1ItemData("Abilities", code = 264_3042, classification = ItemClassification.useful, ), + #"Ghostly Scream": KH1ItemData("Abilities", code = 264_3043, classification = ItemClassification.useful, ), + #"Humming Bird": KH1ItemData("Abilities", code = 264_3044, classification = ItemClassification.useful, ), + #"Time-Out": KH1ItemData("Abilities", code = 264_3045, classification = ItemClassification.useful, ), + #"Storm's Eye": KH1ItemData("Abilities", code = 264_3046, classification = ItemClassification.useful, ), + #"Ferocious Lunge": KH1ItemData("Abilities", code = 264_3047, classification = ItemClassification.useful, ), + #"Furious Bellow": KH1ItemData("Abilities", code = 264_3048, classification = ItemClassification.useful, ), + #"Spiral Wave": KH1ItemData("Abilities", code = 264_3049, classification = ItemClassification.useful, ), + #"Thunder Potion": KH1ItemData("Abilities", code = 264_3050, classification = ItemClassification.useful, ), + #"Cure Potion": KH1ItemData("Abilities", code = 264_3051, classification = ItemClassification.useful, ), + #"Aero Potion": KH1ItemData("Abilities", code = 264_3052, classification = ItemClassification.useful, ), + "Slapshot": KH1ItemData("Abilities", code = 264_3053, classification = ItemClassification.useful, ), + "Sliding Dash": KH1ItemData("Abilities", code = 264_3054, classification = ItemClassification.useful, ), + "Hurricane Blast": KH1ItemData("Abilities", code = 264_3055, classification = ItemClassification.useful, ), + "Ripple Drive": KH1ItemData("Abilities", code = 264_3056, classification = ItemClassification.useful, ), + "Stun Impact": KH1ItemData("Abilities", code = 264_3057, classification = ItemClassification.useful, ), + "Gravity Break": KH1ItemData("Abilities", code = 264_3058, classification = ItemClassification.useful, ), + "Zantetsuken": KH1ItemData("Abilities", code = 264_3059, classification = ItemClassification.useful, ), + "Tech Boost": KH1ItemData("Abilities", code = 264_3060, classification = ItemClassification.useful, max_quantity = 4 ), + "Encounter Plus": KH1ItemData("Abilities", code = 264_3061, classification = ItemClassification.useful, ), + "Leaf Bracer": KH1ItemData("Abilities", code = 264_3062, classification = ItemClassification.progression, ), + #"Evolution": KH1ItemData("Abilities", code = 264_3063, classification = ItemClassification.useful, ), + "EXP Zero": KH1ItemData("Abilities", code = 264_3064, classification = ItemClassification.useful, ), + "Combo Master": KH1ItemData("Abilities", code = 264_3065, classification = ItemClassification.progression, ), + "Max HP Increase": KH1ItemData("Level Up", code = 264_4001, classification = ItemClassification.useful, max_quantity = 15), + "Max MP Increase": KH1ItemData("Level Up", code = 264_4002, classification = ItemClassification.useful, max_quantity = 15), + "Max AP Increase": KH1ItemData("Level Up", code = 264_4003, classification = ItemClassification.useful, max_quantity = 15), + "Strength Increase": KH1ItemData("Level Up", code = 264_4004, classification = ItemClassification.useful, max_quantity = 15), + "Defense Increase": KH1ItemData("Level Up", code = 264_4005, classification = ItemClassification.useful, max_quantity = 15), + "Accessory Slot Increase": KH1ItemData("Limited Level Up", code = 264_4006, classification = ItemClassification.useful, max_quantity = 15), + "Item Slot Increase": KH1ItemData("Limited Level Up", code = 264_4007, classification = ItemClassification.useful, max_quantity = 15), + "Dumbo": KH1ItemData("Summons", code = 264_5000, classification = ItemClassification.progression, ), + "Bambi": KH1ItemData("Summons", code = 264_5001, classification = ItemClassification.progression, ), + "Genie": KH1ItemData("Summons", code = 264_5002, classification = ItemClassification.progression, ), + "Tinker Bell": KH1ItemData("Summons", code = 264_5003, classification = ItemClassification.progression, ), + "Mushu": KH1ItemData("Summons", code = 264_5004, classification = ItemClassification.progression, ), + "Simba": KH1ItemData("Summons", code = 264_5005, classification = ItemClassification.progression, ), + "Progressive Fire": KH1ItemData("Magic", code = 264_6001, classification = ItemClassification.progression, max_quantity = 3 ), + "Progressive Blizzard": KH1ItemData("Magic", code = 264_6002, classification = ItemClassification.progression, max_quantity = 3 ), + "Progressive Thunder": KH1ItemData("Magic", code = 264_6003, classification = ItemClassification.progression, max_quantity = 3 ), + "Progressive Cure": KH1ItemData("Magic", code = 264_6004, classification = ItemClassification.progression, max_quantity = 3 ), + "Progressive Gravity": KH1ItemData("Magic", code = 264_6005, classification = ItemClassification.progression, max_quantity = 3 ), + "Progressive Stop": KH1ItemData("Magic", code = 264_6006, classification = ItemClassification.progression, max_quantity = 3 ), + "Progressive Aero": KH1ItemData("Magic", code = 264_6007, classification = ItemClassification.progression, max_quantity = 3 ), + #"Traverse Town": KH1ItemData("Worlds", code = 264_7001, classification = ItemClassification.progression, ), + "Wonderland": KH1ItemData("Worlds", code = 264_7002, classification = ItemClassification.progression, ), + "Olympus Coliseum": KH1ItemData("Worlds", code = 264_7003, classification = ItemClassification.progression, ), + "Deep Jungle": KH1ItemData("Worlds", code = 264_7004, classification = ItemClassification.progression, ), + "Agrabah": KH1ItemData("Worlds", code = 264_7005, classification = ItemClassification.progression, ), + "Halloween Town": KH1ItemData("Worlds", code = 264_7006, classification = ItemClassification.progression, ), + "Atlantica": KH1ItemData("Worlds", code = 264_7007, classification = ItemClassification.progression, ), + "Neverland": KH1ItemData("Worlds", code = 264_7008, classification = ItemClassification.progression, ), + "Hollow Bastion": KH1ItemData("Worlds", code = 264_7009, classification = ItemClassification.progression, ), + "End of the World": KH1ItemData("Worlds", code = 264_7010, classification = ItemClassification.progression, ), + "Monstro": KH1ItemData("Worlds", code = 264_7011, classification = ItemClassification.progression, ), + "Blue Trinity": KH1ItemData("Trinities", code = 264_8001, classification = ItemClassification.progression, ), + "Red Trinity": KH1ItemData("Trinities", code = 264_8002, classification = ItemClassification.progression, ), + "Green Trinity": KH1ItemData("Trinities", code = 264_8003, classification = ItemClassification.progression, ), + "Yellow Trinity": KH1ItemData("Trinities", code = 264_8004, classification = ItemClassification.progression, ), + "White Trinity": KH1ItemData("Trinities", code = 264_8005, classification = ItemClassification.progression, ), + "Phil Cup": KH1ItemData("Cups", code = 264_9001, classification = ItemClassification.progression, ), + "Pegasus Cup": KH1ItemData("Cups", code = 264_9002, classification = ItemClassification.progression, ), + "Hercules Cup": KH1ItemData("Cups", code = 264_9003, classification = ItemClassification.progression, ), + #"Hades Cup": KH1ItemData("Cups", code = 264_9004, classification = ItemClassification.progression, ), +} + +event_item_table: Dict[str, KH1ItemData] = {} + +#Make item categories +item_name_groups: Dict[str, Set[str]] = {} +for item in item_table.keys(): + category = item_table[item].category + if category not in item_name_groups.keys(): + item_name_groups[category] = set() + item_name_groups[category].add(item) diff --git a/worlds/kh1/Locations.py b/worlds/kh1/Locations.py new file mode 100644 index 000000000000..a82be70f090b --- /dev/null +++ b/worlds/kh1/Locations.py @@ -0,0 +1,590 @@ +from typing import Dict, NamedTuple, Optional, Set +import typing + + +from BaseClasses import Location + + +class KH1Location(Location): + game: str = "Kingdom Hearts" + + +class KH1LocationData(NamedTuple): + category: str + code: int + + +def get_locations_by_category(category: str) -> Dict[str, KH1LocationData]: + location_dict: Dict[str, KH1LocationData] = {} + for name, data in location_table.items(): + if data.category == category: + location_dict.setdefault(name, data) + + return location_dict + + +location_table: Dict[str, KH1LocationData] = { + #"Destiny Islands Chest": KH1LocationData("Destiny Islands", 265_0011), missable + "Traverse Town 1st District Candle Puzzle Chest": KH1LocationData("Traverse Town", 265_0211), + "Traverse Town 1st District Accessory Shop Roof Chest": KH1LocationData("Traverse Town", 265_0212), + "Traverse Town 2nd District Boots and Shoes Awning Chest": KH1LocationData("Traverse Town", 265_0213), + "Traverse Town 2nd District Rooftop Chest": KH1LocationData("Traverse Town", 265_0214), + "Traverse Town 2nd District Gizmo Shop Facade Chest": KH1LocationData("Traverse Town", 265_0251), + "Traverse Town Alleyway Balcony Chest": KH1LocationData("Traverse Town", 265_0252), + "Traverse Town Alleyway Blue Room Awning Chest": KH1LocationData("Traverse Town", 265_0253), + "Traverse Town Alleyway Corner Chest": KH1LocationData("Traverse Town", 265_0254), + "Traverse Town Green Room Clock Puzzle Chest": KH1LocationData("Traverse Town", 265_0292), + "Traverse Town Green Room Table Chest": KH1LocationData("Traverse Town", 265_0293), + "Traverse Town Red Room Chest": KH1LocationData("Traverse Town", 265_0294), + "Traverse Town Mystical House Yellow Trinity Chest": KH1LocationData("Traverse Town", 265_0331), + "Traverse Town Accessory Shop Chest": KH1LocationData("Traverse Town", 265_0332), + "Traverse Town Secret Waterway White Trinity Chest": KH1LocationData("Traverse Town", 265_0333), + "Traverse Town Geppetto's House Chest": KH1LocationData("Traverse Town", 265_0334), + "Traverse Town Item Workshop Right Chest": KH1LocationData("Traverse Town", 265_0371), + "Traverse Town 1st District Blue Trinity Balcony Chest": KH1LocationData("Traverse Town", 265_0411), + "Traverse Town Mystical House Glide Chest": KH1LocationData("Traverse Town", 265_0891), + "Traverse Town Alleyway Behind Crates Chest": KH1LocationData("Traverse Town", 265_0892), + "Traverse Town Item Workshop Left Chest": KH1LocationData("Traverse Town", 265_0893), + "Traverse Town Secret Waterway Near Stairs Chest": KH1LocationData("Traverse Town", 265_0894), + "Wonderland Rabbit Hole Green Trinity Chest": KH1LocationData("Wonderland", 265_0931), + "Wonderland Rabbit Hole Defeat Heartless 1 Chest": KH1LocationData("Wonderland", 265_0932), + "Wonderland Rabbit Hole Defeat Heartless 2 Chest": KH1LocationData("Wonderland", 265_0933), + "Wonderland Rabbit Hole Defeat Heartless 3 Chest": KH1LocationData("Wonderland", 265_0934), + "Wonderland Bizarre Room Green Trinity Chest": KH1LocationData("Wonderland", 265_0971), + "Wonderland Queen's Castle Hedge Left Red Chest": KH1LocationData("Wonderland", 265_1011), + "Wonderland Queen's Castle Hedge Right Blue Chest": KH1LocationData("Wonderland", 265_1012), + "Wonderland Queen's Castle Hedge Right Red Chest": KH1LocationData("Wonderland", 265_1013), + "Wonderland Lotus Forest Thunder Plant Chest": KH1LocationData("Wonderland", 265_1014), + "Wonderland Lotus Forest Through the Painting Thunder Plant Chest": KH1LocationData("Wonderland", 265_1051), + "Wonderland Lotus Forest Glide Chest": KH1LocationData("Wonderland", 265_1052), + "Wonderland Lotus Forest Nut Chest": KH1LocationData("Wonderland", 265_1053), + "Wonderland Lotus Forest Corner Chest": KH1LocationData("Wonderland", 265_1054), + "Wonderland Bizarre Room Lamp Chest": KH1LocationData("Wonderland", 265_1091), + "Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest": KH1LocationData("Wonderland", 265_1093), + "Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest": KH1LocationData("Wonderland", 265_1094), + "Wonderland Tea Party Garden Bear and Clock Puzzle Chest": KH1LocationData("Wonderland", 265_1131), + "Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest": KH1LocationData("Wonderland", 265_1132), + "Wonderland Lotus Forest Through the Painting White Trinity Chest": KH1LocationData("Wonderland", 265_1133), + "Deep Jungle Tree House Beneath Tree House Chest": KH1LocationData("Deep Jungle", 265_1213), + "Deep Jungle Tree House Rooftop Chest": KH1LocationData("Deep Jungle", 265_1214), + "Deep Jungle Hippo's Lagoon Center Chest": KH1LocationData("Deep Jungle", 265_1251), + "Deep Jungle Hippo's Lagoon Left Chest": KH1LocationData("Deep Jungle", 265_1252), + "Deep Jungle Hippo's Lagoon Right Chest": KH1LocationData("Deep Jungle", 265_1253), + "Deep Jungle Vines Chest": KH1LocationData("Deep Jungle", 265_1291), + "Deep Jungle Vines 2 Chest": KH1LocationData("Deep Jungle", 265_1292), + "Deep Jungle Climbing Trees Blue Trinity Chest": KH1LocationData("Deep Jungle", 265_1293), + "Deep Jungle Tunnel Chest": KH1LocationData("Deep Jungle", 265_1331), + "Deep Jungle Cavern of Hearts White Trinity Chest": KH1LocationData("Deep Jungle", 265_1332), + "Deep Jungle Camp Blue Trinity Chest": KH1LocationData("Deep Jungle", 265_1333), + "Deep Jungle Tent Chest": KH1LocationData("Deep Jungle", 265_1334), + "Deep Jungle Waterfall Cavern Low Chest": KH1LocationData("Deep Jungle", 265_1371), + "Deep Jungle Waterfall Cavern Middle Chest": KH1LocationData("Deep Jungle", 265_1372), + "Deep Jungle Waterfall Cavern High Wall Chest": KH1LocationData("Deep Jungle", 265_1373), + "Deep Jungle Waterfall Cavern High Middle Chest": KH1LocationData("Deep Jungle", 265_1374), + "Deep Jungle Cliff Right Cliff Left Chest": KH1LocationData("Deep Jungle", 265_1411), + "Deep Jungle Cliff Right Cliff Right Chest": KH1LocationData("Deep Jungle", 265_1412), + "Deep Jungle Tree House Suspended Boat Chest": KH1LocationData("Deep Jungle", 265_1413), + "100 Acre Wood Meadow Inside Log Chest": KH1LocationData("100 Acre Wood", 265_1654), + "100 Acre Wood Bouncing Spot Left Cliff Chest": KH1LocationData("100 Acre Wood", 265_1691), + "100 Acre Wood Bouncing Spot Right Tree Alcove Chest": KH1LocationData("100 Acre Wood", 265_1692), + "100 Acre Wood Bouncing Spot Under Giant Pot Chest": KH1LocationData("100 Acre Wood", 265_1693), + "Agrabah Plaza By Storage Chest": KH1LocationData("Agrabah", 265_1972), + "Agrabah Plaza Raised Terrace Chest": KH1LocationData("Agrabah", 265_1973), + "Agrabah Plaza Top Corner Chest": KH1LocationData("Agrabah", 265_1974), + "Agrabah Alley Chest": KH1LocationData("Agrabah", 265_2011), + "Agrabah Bazaar Across Windows Chest": KH1LocationData("Agrabah", 265_2012), + "Agrabah Bazaar High Corner Chest": KH1LocationData("Agrabah", 265_2013), + "Agrabah Main Street Right Palace Entrance Chest": KH1LocationData("Agrabah", 265_2014), + "Agrabah Main Street High Above Alley Entrance Chest": KH1LocationData("Agrabah", 265_2051), + "Agrabah Main Street High Above Palace Gates Entrance Chest": KH1LocationData("Agrabah", 265_2052), + "Agrabah Palace Gates Low Chest": KH1LocationData("Agrabah", 265_2053), + "Agrabah Palace Gates High Opposite Palace Chest": KH1LocationData("Agrabah", 265_2054), + "Agrabah Palace Gates High Close to Palace Chest": KH1LocationData("Agrabah", 265_2091), + "Agrabah Storage Green Trinity Chest": KH1LocationData("Agrabah", 265_2092), + "Agrabah Storage Behind Barrel Chest": KH1LocationData("Agrabah", 265_2093), + "Agrabah Cave of Wonders Entrance Left Chest": KH1LocationData("Agrabah", 265_2094), + "Agrabah Cave of Wonders Entrance Tall Tower Chest": KH1LocationData("Agrabah", 265_2131), + "Agrabah Cave of Wonders Hall High Left Chest": KH1LocationData("Agrabah", 265_2132), + "Agrabah Cave of Wonders Hall Near Bottomless Hall Chest": KH1LocationData("Agrabah", 265_2133), + "Agrabah Cave of Wonders Bottomless Hall Raised Platform Chest": KH1LocationData("Agrabah", 265_2134), + "Agrabah Cave of Wonders Bottomless Hall Pillar Chest": KH1LocationData("Agrabah", 265_2171), + "Agrabah Cave of Wonders Bottomless Hall Across Chasm Chest": KH1LocationData("Agrabah", 265_2172), + "Agrabah Cave of Wonders Treasure Room Across Platforms Chest": KH1LocationData("Agrabah", 265_2173), + "Agrabah Cave of Wonders Treasure Room Small Treasure Pile Chest": KH1LocationData("Agrabah", 265_2174), + "Agrabah Cave of Wonders Treasure Room Large Treasure Pile Chest": KH1LocationData("Agrabah", 265_2211), + "Agrabah Cave of Wonders Treasure Room Above Fire Chest": KH1LocationData("Agrabah", 265_2212), + "Agrabah Cave of Wonders Relic Chamber Jump from Stairs Chest": KH1LocationData("Agrabah", 265_2213), + "Agrabah Cave of Wonders Relic Chamber Stairs Chest": KH1LocationData("Agrabah", 265_2214), + "Agrabah Cave of Wonders Dark Chamber Abu Gem Chest": KH1LocationData("Agrabah", 265_2251), + "Agrabah Cave of Wonders Dark Chamber Across from Relic Chamber Entrance Chest": KH1LocationData("Agrabah", 265_2252), + "Agrabah Cave of Wonders Dark Chamber Bridge Chest": KH1LocationData("Agrabah", 265_2253), + "Agrabah Cave of Wonders Dark Chamber Near Save Chest": KH1LocationData("Agrabah", 265_2254), + "Agrabah Cave of Wonders Silent Chamber Blue Trinity Chest": KH1LocationData("Agrabah", 265_2291), + "Agrabah Cave of Wonders Hidden Room Right Chest": KH1LocationData("Agrabah", 265_2292), + "Agrabah Cave of Wonders Hidden Room Left Chest": KH1LocationData("Agrabah", 265_2293), + "Agrabah Aladdin's House Main Street Entrance Chest": KH1LocationData("Agrabah", 265_2294), + "Agrabah Aladdin's House Plaza Entrance Chest": KH1LocationData("Agrabah", 265_2331), + "Agrabah Cave of Wonders Entrance White Trinity Chest": KH1LocationData("Agrabah", 265_2332), + "Monstro Chamber 6 Other Platform Chest": KH1LocationData("Monstro", 265_2413), + "Monstro Chamber 6 Platform Near Chamber 5 Entrance Chest": KH1LocationData("Monstro", 265_2414), + "Monstro Chamber 6 Raised Area Near Chamber 1 Entrance Chest": KH1LocationData("Monstro", 265_2451), + "Monstro Chamber 6 Low Chest": KH1LocationData("Monstro", 265_2452), + "Atlantica Sunken Ship In Flipped Boat Chest": KH1LocationData("Atlantica", 265_2531), + "Atlantica Sunken Ship Seabed Chest": KH1LocationData("Atlantica", 265_2532), + "Atlantica Sunken Ship Inside Ship Chest": KH1LocationData("Atlantica", 265_2533), + "Atlantica Ariel's Grotto High Chest": KH1LocationData("Atlantica", 265_2534), + "Atlantica Ariel's Grotto Middle Chest": KH1LocationData("Atlantica", 265_2571), + "Atlantica Ariel's Grotto Low Chest": KH1LocationData("Atlantica", 265_2572), + "Atlantica Ursula's Lair Use Fire on Urchin Chest": KH1LocationData("Atlantica", 265_2573), + "Atlantica Undersea Gorge Jammed by Ariel's Grotto Chest": KH1LocationData("Atlantica", 265_2574), + "Atlantica Triton's Palace White Trinity Chest": KH1LocationData("Atlantica", 265_2611), + "Halloween Town Moonlight Hill White Trinity Chest": KH1LocationData("Halloween Town", 265_3014), + "Halloween Town Bridge Under Bridge": KH1LocationData("Halloween Town", 265_3051), + "Halloween Town Boneyard Tombstone Puzzle Chest": KH1LocationData("Halloween Town", 265_3052), + "Halloween Town Bridge Right of Gate Chest": KH1LocationData("Halloween Town", 265_3053), + "Halloween Town Cemetery Behind Grave Chest": KH1LocationData("Halloween Town", 265_3054), + "Halloween Town Cemetery By Cat Shape Chest": KH1LocationData("Halloween Town", 265_3091), + "Halloween Town Cemetery Between Graves Chest": KH1LocationData("Halloween Town", 265_3092), + "Halloween Town Oogie's Manor Lower Iron Cage Chest": KH1LocationData("Halloween Town", 265_3093), + "Halloween Town Oogie's Manor Upper Iron Cage Chest": KH1LocationData("Halloween Town", 265_3094), + "Halloween Town Oogie's Manor Hollow Chest": KH1LocationData("Halloween Town", 265_3131), + "Halloween Town Oogie's Manor Grounds Red Trinity Chest": KH1LocationData("Halloween Town", 265_3132), + "Halloween Town Guillotine Square High Tower Chest": KH1LocationData("Halloween Town", 265_3133), + "Halloween Town Guillotine Square Pumpkin Structure Left Chest": KH1LocationData("Halloween Town", 265_3134), + "Halloween Town Oogie's Manor Entrance Steps Chest": KH1LocationData("Halloween Town", 265_3171), + "Halloween Town Oogie's Manor Inside Entrance Chest": KH1LocationData("Halloween Town", 265_3172), + "Halloween Town Bridge Left of Gate Chest": KH1LocationData("Halloween Town", 265_3291), + "Halloween Town Cemetery By Striped Grave Chest": KH1LocationData("Halloween Town", 265_3292), + "Halloween Town Guillotine Square Under Jack's House Stairs Chest": KH1LocationData("Halloween Town", 265_3293), + "Halloween Town Guillotine Square Pumpkin Structure Right Chest": KH1LocationData("Halloween Town", 265_3294), + "Olympus Coliseum Coliseum Gates Left Behind Columns Chest": KH1LocationData("Olympus Coliseum", 265_3332), + "Olympus Coliseum Coliseum Gates Right Blue Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3333), + "Olympus Coliseum Coliseum Gates Left Blue Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3334), + "Olympus Coliseum Coliseum Gates White Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3371), + "Olympus Coliseum Coliseum Gates Blizzara Chest": KH1LocationData("Olympus Coliseum", 265_3372), + "Olympus Coliseum Coliseum Gates Blizzaga Chest": KH1LocationData("Olympus Coliseum", 265_3373), + "Monstro Mouth Boat Deck Chest": KH1LocationData("Monstro", 265_3454), + "Monstro Mouth High Platform Boat Side Chest": KH1LocationData("Monstro", 265_3491), + "Monstro Mouth High Platform Across from Boat Chest": KH1LocationData("Monstro", 265_3492), + "Monstro Mouth Near Ship Chest": KH1LocationData("Monstro", 265_3493), + "Monstro Mouth Green Trinity Top of Boat Chest": KH1LocationData("Monstro", 265_3494), + "Monstro Chamber 2 Ground Chest": KH1LocationData("Monstro", 265_3534), + "Monstro Chamber 2 Platform Chest": KH1LocationData("Monstro", 265_3571), + "Monstro Chamber 5 Platform Chest": KH1LocationData("Monstro", 265_3613), + "Monstro Chamber 3 Ground Chest": KH1LocationData("Monstro", 265_3614), + "Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest": KH1LocationData("Monstro", 265_3651), + "Monstro Chamber 3 Near Chamber 6 Entrance Chest": KH1LocationData("Monstro", 265_3652), + "Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest": KH1LocationData("Monstro", 265_3653), + "Monstro Mouth High Platform Near Teeth Chest": KH1LocationData("Monstro", 265_3732), + "Monstro Chamber 5 Atop Barrel Chest": KH1LocationData("Monstro", 265_3733), + "Monstro Chamber 5 Low 2nd Chest": KH1LocationData("Monstro", 265_3734), + "Monstro Chamber 5 Low 1st Chest": KH1LocationData("Monstro", 265_3771), + "Neverland Pirate Ship Deck White Trinity Chest": KH1LocationData("Neverland", 265_3772), + "Neverland Pirate Ship Crows Nest Chest": KH1LocationData("Neverland", 265_3773), + "Neverland Hold Yellow Trinity Right Blue Chest": KH1LocationData("Neverland", 265_3774), + "Neverland Hold Yellow Trinity Left Blue Chest": KH1LocationData("Neverland", 265_3811), + "Neverland Galley Chest": KH1LocationData("Neverland", 265_3812), + "Neverland Cabin Chest": KH1LocationData("Neverland", 265_3813), + "Neverland Hold Flight 1st Chest": KH1LocationData("Neverland", 265_3814), + "Neverland Clock Tower Chest": KH1LocationData("Neverland", 265_4014), + "Neverland Hold Flight 2nd Chest": KH1LocationData("Neverland", 265_4051), + "Neverland Hold Yellow Trinity Green Chest": KH1LocationData("Neverland", 265_4052), + "Neverland Captain's Cabin Chest": KH1LocationData("Neverland", 265_4053), + "Hollow Bastion Rising Falls Water's Surface Chest": KH1LocationData("Hollow Bastion", 265_4054), + "Hollow Bastion Rising Falls Under Water 1st Chest": KH1LocationData("Hollow Bastion", 265_4091), + "Hollow Bastion Rising Falls Under Water 2nd Chest": KH1LocationData("Hollow Bastion", 265_4092), + "Hollow Bastion Rising Falls Floating Platform Near Save Chest": KH1LocationData("Hollow Bastion", 265_4093), + "Hollow Bastion Rising Falls Floating Platform Near Bubble Chest": KH1LocationData("Hollow Bastion", 265_4094), + "Hollow Bastion Rising Falls High Platform Chest": KH1LocationData("Hollow Bastion", 265_4131), + "Hollow Bastion Castle Gates Gravity Chest": KH1LocationData("Hollow Bastion", 265_4132), + "Hollow Bastion Castle Gates Freestanding Pillar Chest": KH1LocationData("Hollow Bastion", 265_4133), + "Hollow Bastion Castle Gates High Pillar Chest": KH1LocationData("Hollow Bastion", 265_4134), + "Hollow Bastion Great Crest Lower Chest": KH1LocationData("Hollow Bastion", 265_4171), + "Hollow Bastion Great Crest After Battle Platform Chest": KH1LocationData("Hollow Bastion", 265_4172), + "Hollow Bastion High Tower 2nd Gravity Chest": KH1LocationData("Hollow Bastion", 265_4173), + "Hollow Bastion High Tower 1st Gravity Chest": KH1LocationData("Hollow Bastion", 265_4174), + "Hollow Bastion High Tower Above Sliding Blocks Chest": KH1LocationData("Hollow Bastion", 265_4211), + "Hollow Bastion Library Top of Bookshelf Chest": KH1LocationData("Hollow Bastion", 265_4213), + "Hollow Bastion Library 1st Floor Turn the Carousel Chest": KH1LocationData("Hollow Bastion", 265_4214), + "Hollow Bastion Library Top of Bookshelf Turn the Carousel Chest": KH1LocationData("Hollow Bastion", 265_4251), + "Hollow Bastion Library 2nd Floor Turn the Carousel 1st Chest": KH1LocationData("Hollow Bastion", 265_4252), + "Hollow Bastion Library 2nd Floor Turn the Carousel 2nd Chest": KH1LocationData("Hollow Bastion", 265_4253), + "Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest": KH1LocationData("Hollow Bastion", 265_4254), + "Hollow Bastion Lift Stop Library Node Gravity Chest": KH1LocationData("Hollow Bastion", 265_4291), + "Hollow Bastion Lift Stop Under High Tower Sliding Blocks Chest": KH1LocationData("Hollow Bastion", 265_4292), + "Hollow Bastion Lift Stop Outside Library Gravity Chest": KH1LocationData("Hollow Bastion", 265_4293), + "Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest": KH1LocationData("Hollow Bastion", 265_4294), + "Hollow Bastion Base Level Bubble Under the Wall Platform Chest": KH1LocationData("Hollow Bastion", 265_4331), + "Hollow Bastion Base Level Platform Near Entrance Chest": KH1LocationData("Hollow Bastion", 265_4332), + "Hollow Bastion Base Level Near Crystal Switch Chest": KH1LocationData("Hollow Bastion", 265_4333), + "Hollow Bastion Waterway Near Save Chest": KH1LocationData("Hollow Bastion", 265_4334), + "Hollow Bastion Waterway Blizzard on Bubble Chest": KH1LocationData("Hollow Bastion", 265_4371), + "Hollow Bastion Waterway Unlock Passage from Base Level Chest": KH1LocationData("Hollow Bastion", 265_4372), + "Hollow Bastion Dungeon By Candles Chest": KH1LocationData("Hollow Bastion", 265_4373), + "Hollow Bastion Dungeon Corner Chest": KH1LocationData("Hollow Bastion", 265_4374), + "Hollow Bastion Grand Hall Steps Right Side Chest": KH1LocationData("Hollow Bastion", 265_4454), + "Hollow Bastion Grand Hall Oblivion Chest": KH1LocationData("Hollow Bastion", 265_4491), + "Hollow Bastion Grand Hall Left of Gate Chest": KH1LocationData("Hollow Bastion", 265_4492), + #"Hollow Bastion Entrance Hall Push the Statue Chest": KH1LocationData("Hollow Bastion", 265_4493), --handled later + "Hollow Bastion Entrance Hall Left of Emblem Door Chest": KH1LocationData("Hollow Bastion", 265_4212), + "Hollow Bastion Rising Falls White Trinity Chest": KH1LocationData("Hollow Bastion", 265_4494), + "End of the World Final Dimension 1st Chest": KH1LocationData("End of the World", 265_4531), + "End of the World Final Dimension 2nd Chest": KH1LocationData("End of the World", 265_4532), + "End of the World Final Dimension 3rd Chest": KH1LocationData("End of the World", 265_4533), + "End of the World Final Dimension 4th Chest": KH1LocationData("End of the World", 265_4534), + "End of the World Final Dimension 5th Chest": KH1LocationData("End of the World", 265_4571), + "End of the World Final Dimension 6th Chest": KH1LocationData("End of the World", 265_4572), + "End of the World Final Dimension 10th Chest": KH1LocationData("End of the World", 265_4573), + "End of the World Final Dimension 9th Chest": KH1LocationData("End of the World", 265_4574), + "End of the World Final Dimension 8th Chest": KH1LocationData("End of the World", 265_4611), + "End of the World Final Dimension 7th Chest": KH1LocationData("End of the World", 265_4612), + "End of the World Giant Crevasse 3rd Chest": KH1LocationData("End of the World", 265_4613), + "End of the World Giant Crevasse 5th Chest": KH1LocationData("End of the World", 265_4614), + "End of the World Giant Crevasse 1st Chest": KH1LocationData("End of the World", 265_4651), + "End of the World Giant Crevasse 4th Chest": KH1LocationData("End of the World", 265_4652), + "End of the World Giant Crevasse 2nd Chest": KH1LocationData("End of the World", 265_4653), + "End of the World World Terminus Traverse Town Chest": KH1LocationData("End of the World", 265_4654), + "End of the World World Terminus Wonderland Chest": KH1LocationData("End of the World", 265_4691), + "End of the World World Terminus Olympus Coliseum Chest": KH1LocationData("End of the World", 265_4692), + "End of the World World Terminus Deep Jungle Chest": KH1LocationData("End of the World", 265_4693), + "End of the World World Terminus Agrabah Chest": KH1LocationData("End of the World", 265_4694), + "End of the World World Terminus Atlantica Chest": KH1LocationData("End of the World", 265_4731), + "End of the World World Terminus Halloween Town Chest": KH1LocationData("End of the World", 265_4732), + "End of the World World Terminus Neverland Chest": KH1LocationData("End of the World", 265_4733), + "End of the World World Terminus 100 Acre Wood Chest": KH1LocationData("End of the World", 265_4734), + #"End of the World World Terminus Hollow Bastion Chest": KH1LocationData("End of the World", 265_4771), + "End of the World Final Rest Chest": KH1LocationData("End of the World", 265_4772), + "Monstro Chamber 6 White Trinity Chest": KH1LocationData("End of the World", 265_5092), + #"Awakening Chest": KH1LocationData("Awakening", 265_5093), missable + + "Traverse Town Defeat Guard Armor Dodge Roll Event": KH1LocationData("Traverse Town", 265_6011), + "Traverse Town Defeat Guard Armor Fire Event": KH1LocationData("Traverse Town", 265_6012), + "Traverse Town Defeat Guard Armor Blue Trinity Event": KH1LocationData("Traverse Town", 265_6013), + "Traverse Town Leon Secret Waterway Earthshine Event": KH1LocationData("Traverse Town", 265_6014), + "Traverse Town Kairi Secret Waterway Oathkeeper Event": KH1LocationData("Traverse Town", 265_6015), + "Traverse Town Defeat Guard Armor Brave Warrior Event": KH1LocationData("Traverse Town", 265_6016), + "Deep Jungle Defeat Sabor White Fang Event": KH1LocationData("Deep Jungle", 265_6021), + "Deep Jungle Defeat Clayton Cure Event": KH1LocationData("Deep Jungle", 265_6022), + "Deep Jungle Seal Keyhole Jungle King Event": KH1LocationData("Deep Jungle", 265_6023), + "Deep Jungle Seal Keyhole Red Trinity Event": KH1LocationData("Deep Jungle", 265_6024), + "Olympus Coliseum Clear Phil's Training Thunder Event": KH1LocationData("Olympus Coliseum", 265_6031), + "Olympus Coliseum Defeat Cerberus Inferno Band Event": KH1LocationData("Olympus Coliseum", 265_6033), + "Wonderland Defeat Trickmaster Blizzard Event": KH1LocationData("Wonderland", 265_6041), + "Wonderland Defeat Trickmaster Ifrit's Horn Event": KH1LocationData("Wonderland", 265_6042), + "Agrabah Defeat Pot Centipede Ray of Light Event": KH1LocationData("Agrabah", 265_6051), + "Agrabah Defeat Jafar Blizzard Event": KH1LocationData("Agrabah", 265_6052), + "Agrabah Defeat Jafar Genie Fire Event": KH1LocationData("Agrabah", 265_6053), + "Agrabah Seal Keyhole Genie Event": KH1LocationData("Agrabah", 265_6054), + "Agrabah Seal Keyhole Three Wishes Event": KH1LocationData("Agrabah", 265_6055), + "Agrabah Seal Keyhole Green Trinity Event": KH1LocationData("Agrabah", 265_6056), + "Monstro Defeat Parasite Cage I Goofy Cheer Event": KH1LocationData("Monstro", 265_6061), + "Monstro Defeat Parasite Cage II Stop Event": KH1LocationData("Monstro", 265_6062), + "Atlantica Defeat Ursula I Mermaid Kick Event": KH1LocationData("Atlantica", 265_6071), + "Atlantica Defeat Ursula II Thunder Event": KH1LocationData("Atlantica", 265_6072), + "Atlantica Seal Keyhole Crabclaw Event": KH1LocationData("Atlantica", 265_6073), + "Halloween Town Defeat Oogie Boogie Holy Circlet Event": KH1LocationData("Halloween Town", 265_6081), + "Halloween Town Defeat Oogie's Manor Gravity Event": KH1LocationData("Halloween Town", 265_6082), + "Halloween Town Seal Keyhole Pumpkinhead Event": KH1LocationData("Halloween Town", 265_6083), + "Neverland Defeat Anti Sora Raven's Claw Event": KH1LocationData("Neverland", 265_6091), + "Neverland Encounter Hook Cure Event": KH1LocationData("Neverland", 265_6092), + "Neverland Seal Keyhole Fairy Harp Event": KH1LocationData("Neverland", 265_6093), + "Neverland Seal Keyhole Tinker Bell Event": KH1LocationData("Neverland", 265_6094), + "Neverland Seal Keyhole Glide Event": KH1LocationData("Neverland", 265_6095), + "Neverland Defeat Phantom Stop Event": KH1LocationData("Neverland", 265_6096), + "Neverland Defeat Captain Hook Ars Arcanum Event": KH1LocationData("Neverland", 265_6097), + "Hollow Bastion Defeat Riku I White Trinity Event": KH1LocationData("Hollow Bastion", 265_6101), + "Hollow Bastion Defeat Maleficent Donald Cheer Event": KH1LocationData("Hollow Bastion", 265_6102), + "Hollow Bastion Defeat Dragon Maleficent Fireglow Event": KH1LocationData("Hollow Bastion", 265_6103), + "Hollow Bastion Defeat Riku II Ragnarok Event": KH1LocationData("Hollow Bastion", 265_6104), + "Hollow Bastion Defeat Behemoth Omega Arts Event": KH1LocationData("Hollow Bastion", 265_6105), + "Hollow Bastion Speak to Princesses Fire Event": KH1LocationData("Hollow Bastion", 265_6106), + "End of the World Defeat Chernabog Superglide Event": KH1LocationData("End of the World", 265_6111), + + "Traverse Town Mail Postcard 01 Event": KH1LocationData("Traverse Town", 265_6120), + "Traverse Town Mail Postcard 02 Event": KH1LocationData("Traverse Town", 265_6121), + "Traverse Town Mail Postcard 03 Event": KH1LocationData("Traverse Town", 265_6122), + "Traverse Town Mail Postcard 04 Event": KH1LocationData("Traverse Town", 265_6123), + "Traverse Town Mail Postcard 05 Event": KH1LocationData("Traverse Town", 265_6124), + "Traverse Town Mail Postcard 06 Event": KH1LocationData("Traverse Town", 265_6125), + "Traverse Town Mail Postcard 07 Event": KH1LocationData("Traverse Town", 265_6126), + "Traverse Town Mail Postcard 08 Event": KH1LocationData("Traverse Town", 265_6127), + "Traverse Town Mail Postcard 09 Event": KH1LocationData("Traverse Town", 265_6128), + "Traverse Town Mail Postcard 10 Event": KH1LocationData("Traverse Town", 265_6129), + + "Traverse Town Defeat Opposite Armor Aero Event": KH1LocationData("Traverse Town", 265_6131), + + "Atlantica Undersea Gorge Blizzard Clam": KH1LocationData("Atlantica", 265_6201), + "Atlantica Undersea Gorge Ocean Floor Clam": KH1LocationData("Atlantica", 265_6202), + "Atlantica Undersea Valley Higher Cave Clam": KH1LocationData("Atlantica", 265_6203), + "Atlantica Undersea Valley Lower Cave Clam": KH1LocationData("Atlantica", 265_6204), + "Atlantica Undersea Valley Fire Clam": KH1LocationData("Atlantica", 265_6205), + "Atlantica Undersea Valley Wall Clam": KH1LocationData("Atlantica", 265_6206), + "Atlantica Undersea Valley Pillar Clam": KH1LocationData("Atlantica", 265_6207), + "Atlantica Undersea Valley Ocean Floor Clam": KH1LocationData("Atlantica", 265_6208), + "Atlantica Triton's Palace Thunder Clam": KH1LocationData("Atlantica", 265_6209), + "Atlantica Triton's Palace Wall Right Clam": KH1LocationData("Atlantica", 265_6210), + "Atlantica Triton's Palace Near Path Clam": KH1LocationData("Atlantica", 265_6211), + "Atlantica Triton's Palace Wall Left Clam": KH1LocationData("Atlantica", 265_6212), + "Atlantica Cavern Nook Clam": KH1LocationData("Atlantica", 265_6213), + "Atlantica Below Deck Clam": KH1LocationData("Atlantica", 265_6214), + "Atlantica Undersea Garden Clam": KH1LocationData("Atlantica", 265_6215), + "Atlantica Undersea Cave Clam": KH1LocationData("Atlantica", 265_6216), + + #"Traverse Town Magician's Study Turn in Naturespark": KH1LocationData("Traverse Town", 265_6300), + #"Traverse Town Magician's Study Turn in Watergleam": KH1LocationData("Traverse Town", 265_6301), + #"Traverse Town Magician's Study Turn in Fireglow": KH1LocationData("Traverse Town", 265_6302), + #"Traverse Town Magician's Study Turn in all Summon Gems": KH1LocationData("Traverse Town", 265_6303), + "Traverse Town Geppetto's House Geppetto Reward 1": KH1LocationData("Traverse Town", 265_6304), + "Traverse Town Geppetto's House Geppetto Reward 2": KH1LocationData("Traverse Town", 265_6305), + "Traverse Town Geppetto's House Geppetto Reward 3": KH1LocationData("Traverse Town", 265_6306), + "Traverse Town Geppetto's House Geppetto Reward 4": KH1LocationData("Traverse Town", 265_6307), + "Traverse Town Geppetto's House Geppetto Reward 5": KH1LocationData("Traverse Town", 265_6308), + "Traverse Town Geppetto's House Geppetto All Summons Reward": KH1LocationData("Traverse Town", 265_6309), + "Traverse Town Geppetto's House Talk to Pinocchio": KH1LocationData("Traverse Town", 265_6310), + "Traverse Town Magician's Study Obtained All Arts Items": KH1LocationData("Traverse Town", 265_6311), + "Traverse Town Magician's Study Obtained All LV1 Magic": KH1LocationData("Traverse Town", 265_6312), + "Traverse Town Magician's Study Obtained All LV3 Magic": KH1LocationData("Traverse Town", 265_6313), + "Traverse Town Piano Room Return 10 Puppies": KH1LocationData("Traverse Town", 265_6314), + "Traverse Town Piano Room Return 20 Puppies": KH1LocationData("Traverse Town", 265_6315), + "Traverse Town Piano Room Return 30 Puppies": KH1LocationData("Traverse Town", 265_6316), + "Traverse Town Piano Room Return 40 Puppies": KH1LocationData("Traverse Town", 265_6317), + "Traverse Town Piano Room Return 50 Puppies Reward 1": KH1LocationData("Traverse Town", 265_6318), + "Traverse Town Piano Room Return 50 Puppies Reward 2": KH1LocationData("Traverse Town", 265_6319), + "Traverse Town Piano Room Return 60 Puppies": KH1LocationData("Traverse Town", 265_6320), + "Traverse Town Piano Room Return 70 Puppies": KH1LocationData("Traverse Town", 265_6321), + "Traverse Town Piano Room Return 80 Puppies": KH1LocationData("Traverse Town", 265_6322), + "Traverse Town Piano Room Return 90 Puppies": KH1LocationData("Traverse Town", 265_6324), + "Traverse Town Piano Room Return 99 Puppies Reward 1": KH1LocationData("Traverse Town", 265_6326), + "Traverse Town Piano Room Return 99 Puppies Reward 2": KH1LocationData("Traverse Town", 265_6327), + "Olympus Coliseum Cloud Sonic Blade Event": KH1LocationData("Olympus Coliseum", 265_6032), #Had to change the way we send this check, not changing location_id + "Olympus Coliseum Defeat Sephiroth One-Winged Angel Event": KH1LocationData("Olympus Coliseum", 265_6328), + "Olympus Coliseum Defeat Ice Titan Diamond Dust Event": KH1LocationData("Olympus Coliseum", 265_6329), + "Olympus Coliseum Gates Purple Jar After Defeating Hades": KH1LocationData("Olympus Coliseum", 265_6330), + "Halloween Town Guillotine Square Ring Jack's Doorbell 3 Times": KH1LocationData("Halloween Town", 265_6331), + #"Neverland Clock Tower 01:00 Door": KH1LocationData("Neverland", 265_6332), + #"Neverland Clock Tower 02:00 Door": KH1LocationData("Neverland", 265_6333), + #"Neverland Clock Tower 03:00 Door": KH1LocationData("Neverland", 265_6334), + #"Neverland Clock Tower 04:00 Door": KH1LocationData("Neverland", 265_6335), + #"Neverland Clock Tower 05:00 Door": KH1LocationData("Neverland", 265_6336), + #"Neverland Clock Tower 06:00 Door": KH1LocationData("Neverland", 265_6337), + #"Neverland Clock Tower 07:00 Door": KH1LocationData("Neverland", 265_6338), + #"Neverland Clock Tower 08:00 Door": KH1LocationData("Neverland", 265_6339), + #"Neverland Clock Tower 09:00 Door": KH1LocationData("Neverland", 265_6340), + #"Neverland Clock Tower 10:00 Door": KH1LocationData("Neverland", 265_6341), + #"Neverland Clock Tower 11:00 Door": KH1LocationData("Neverland", 265_6342), + #"Neverland Clock Tower 12:00 Door": KH1LocationData("Neverland", 265_6343), + "Neverland Hold Aero Chest": KH1LocationData("Neverland", 265_6344), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 1": KH1LocationData("100 Acre Wood", 265_6345), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 2": KH1LocationData("100 Acre Wood", 265_6346), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 3": KH1LocationData("100 Acre Wood", 265_6347), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 4": KH1LocationData("100 Acre Wood", 265_6348), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 5": KH1LocationData("100 Acre Wood", 265_6349), + "100 Acre Wood Pooh's House Owl Cheer": KH1LocationData("100 Acre Wood", 265_6350), + "100 Acre Wood Convert Torn Page 1": KH1LocationData("100 Acre Wood", 265_6351), + "100 Acre Wood Convert Torn Page 2": KH1LocationData("100 Acre Wood", 265_6352), + "100 Acre Wood Convert Torn Page 3": KH1LocationData("100 Acre Wood", 265_6353), + "100 Acre Wood Convert Torn Page 4": KH1LocationData("100 Acre Wood", 265_6354), + "100 Acre Wood Convert Torn Page 5": KH1LocationData("100 Acre Wood", 265_6355), + "100 Acre Wood Pooh's House Start Fire": KH1LocationData("100 Acre Wood", 265_6356), + "100 Acre Wood Pooh's Room Cabinet": KH1LocationData("100 Acre Wood", 265_6357), + "100 Acre Wood Pooh's Room Chimney": KH1LocationData("100 Acre Wood", 265_6358), + "100 Acre Wood Bouncing Spot Break Log": KH1LocationData("100 Acre Wood", 265_6359), + "100 Acre Wood Bouncing Spot Fall Through Top of Tree Next to Pooh": KH1LocationData("100 Acre Wood", 265_6360), + "Deep Jungle Camp Hi-Potion Experiment": KH1LocationData("Deep Jungle", 265_6361), + "Deep Jungle Camp Ether Experiment": KH1LocationData("Deep Jungle", 265_6362), + "Deep Jungle Camp Replication Experiment": KH1LocationData("Deep Jungle", 265_6363), + "Deep Jungle Cliff Save Gorillas": KH1LocationData("Deep Jungle", 265_6364), + "Deep Jungle Tree House Save Gorillas": KH1LocationData("Deep Jungle", 265_6365), + "Deep Jungle Camp Save Gorillas": KH1LocationData("Deep Jungle", 265_6366), + "Deep Jungle Bamboo Thicket Save Gorillas": KH1LocationData("Deep Jungle", 265_6367), + "Deep Jungle Climbing Trees Save Gorillas": KH1LocationData("Deep Jungle", 265_6368), + "Olympus Coliseum Olympia Chest": KH1LocationData("Olympus Coliseum", 265_6369), + "Deep Jungle Jungle Slider 10 Fruits": KH1LocationData("Deep Jungle", 265_6370), + "Deep Jungle Jungle Slider 20 Fruits": KH1LocationData("Deep Jungle", 265_6371), + "Deep Jungle Jungle Slider 30 Fruits": KH1LocationData("Deep Jungle", 265_6372), + "Deep Jungle Jungle Slider 40 Fruits": KH1LocationData("Deep Jungle", 265_6373), + "Deep Jungle Jungle Slider 50 Fruits": KH1LocationData("Deep Jungle", 265_6374), + "Traverse Town 1st District Speak with Cid Event": KH1LocationData("Traverse Town", 265_6375), + "Wonderland Bizarre Room Read Book": KH1LocationData("Wonderland", 265_6376), + "Olympus Coliseum Coliseum Gates Green Trinity": KH1LocationData("Olympus Coliseum", 265_6377), + "Agrabah Defeat Kurt Zisa Zantetsuken Event": KH1LocationData("Agrabah", 265_6378), + "Hollow Bastion Defeat Unknown EXP Necklace Event": KH1LocationData("Hollow Bastion", 265_6379), + "Olympus Coliseum Coliseum Gates Hero's License Event": KH1LocationData("Olympus Coliseum", 265_6380), + "Atlantica Sunken Ship Crystal Trident Event": KH1LocationData("Atlantica", 265_6381), + "Halloween Town Graveyard Forget-Me-Not Event": KH1LocationData("Halloween Town", 265_6382), + "Deep Jungle Tent Protect-G Event": KH1LocationData("Deep Jungle", 265_6383), + "Deep Jungle Cavern of Hearts Navi-G Piece Event": KH1LocationData("Deep Jungle", 265_6384), + "Wonderland Bizarre Room Navi-G Piece Event": KH1LocationData("Wonderland", 265_6385), + "Olympus Coliseum Coliseum Gates Entry Pass Event": KH1LocationData("Olympus Coliseum", 265_6386), + + "Traverse Town Synth Log": KH1LocationData("Traverse Town", 265_6401), + "Traverse Town Synth Cloth": KH1LocationData("Traverse Town", 265_6402), + "Traverse Town Synth Rope": KH1LocationData("Traverse Town", 265_6403), + "Traverse Town Synth Seagull Egg": KH1LocationData("Traverse Town", 265_6404), + "Traverse Town Synth Fish": KH1LocationData("Traverse Town", 265_6405), + "Traverse Town Synth Mushroom": KH1LocationData("Traverse Town", 265_6406), + + "Traverse Town Item Shop Postcard": KH1LocationData("Traverse Town", 265_6500), + "Traverse Town 1st District Safe Postcard": KH1LocationData("Traverse Town", 265_6501), + "Traverse Town Gizmo Shop Postcard 1": KH1LocationData("Traverse Town", 265_6502), + "Traverse Town Gizmo Shop Postcard 2": KH1LocationData("Traverse Town", 265_6503), + "Traverse Town Item Workshop Postcard": KH1LocationData("Traverse Town", 265_6504), + "Traverse Town 3rd District Balcony Postcard": KH1LocationData("Traverse Town", 265_6505), + "Traverse Town Geppetto's House Postcard": KH1LocationData("Traverse Town", 265_6506), + "Halloween Town Lab Torn Page": KH1LocationData("Halloween Town", 265_6508), + "Hollow Bastion Entrance Hall Emblem Piece (Flame)": KH1LocationData("Hollow Bastion", 265_6516), + "Hollow Bastion Entrance Hall Emblem Piece (Chest)": KH1LocationData("Hollow Bastion", 265_6517), + "Hollow Bastion Entrance Hall Emblem Piece (Statue)": KH1LocationData("Hollow Bastion", 265_6518), + "Hollow Bastion Entrance Hall Emblem Piece (Fountain)": KH1LocationData("Hollow Bastion", 265_6519), + #"Traverse Town 1st District Leon Gift": KH1LocationData("Traverse Town", 265_6520), + #"Traverse Town 1st District Aerith Gift": KH1LocationData("Traverse Town", 265_6521), + "Hollow Bastion Library Speak to Belle Divine Rose": KH1LocationData("Hollow Bastion", 265_6522), + "Hollow Bastion Library Speak to Aerith Cure": KH1LocationData("Hollow Bastion", 265_6523), + + "Agrabah Defeat Jafar Genie Ansem's Report 1": KH1LocationData("Agrabah", 265_7018), + "Hollow Bastion Speak with Aerith Ansem's Report 2": KH1LocationData("Hollow Bastion", 265_7017), + "Atlantica Defeat Ursula II Ansem's Report 3": KH1LocationData("Atlantica", 265_7016), + "Hollow Bastion Speak with Aerith Ansem's Report 4": KH1LocationData("Hollow Bastion", 265_7015), + "Hollow Bastion Defeat Maleficent Ansem's Report 5": KH1LocationData("Hollow Bastion", 265_7014), + "Hollow Bastion Speak with Aerith Ansem's Report 6": KH1LocationData("Hollow Bastion", 265_7013), + "Halloween Town Defeat Oogie Boogie Ansem's Report 7": KH1LocationData("Halloween Town", 265_7012), + "Olympus Coliseum Defeat Hades Ansem's Report 8": KH1LocationData("Olympus Coliseum", 265_7011), + "Neverland Defeat Hook Ansem's Report 9": KH1LocationData("Neverland", 265_7028), + "Hollow Bastion Speak with Aerith Ansem's Report 10": KH1LocationData("Hollow Bastion", 265_7027), + "Agrabah Defeat Kurt Zisa Ansem's Report 11": KH1LocationData("Agrabah", 265_7026), + "Olympus Coliseum Defeat Sephiroth Ansem's Report 12": KH1LocationData("Olympus Coliseum", 265_7025), + "Hollow Bastion Defeat Unknown Ansem's Report 13": KH1LocationData("Hollow Bastion", 265_7024), + "Level 001": KH1LocationData("Levels", 265_8001), + "Level 002": KH1LocationData("Levels", 265_8002), + "Level 003": KH1LocationData("Levels", 265_8003), + "Level 004": KH1LocationData("Levels", 265_8004), + "Level 005": KH1LocationData("Levels", 265_8005), + "Level 006": KH1LocationData("Levels", 265_8006), + "Level 007": KH1LocationData("Levels", 265_8007), + "Level 008": KH1LocationData("Levels", 265_8008), + "Level 009": KH1LocationData("Levels", 265_8009), + "Level 010": KH1LocationData("Levels", 265_8010), + "Level 011": KH1LocationData("Levels", 265_8011), + "Level 012": KH1LocationData("Levels", 265_8012), + "Level 013": KH1LocationData("Levels", 265_8013), + "Level 014": KH1LocationData("Levels", 265_8014), + "Level 015": KH1LocationData("Levels", 265_8015), + "Level 016": KH1LocationData("Levels", 265_8016), + "Level 017": KH1LocationData("Levels", 265_8017), + "Level 018": KH1LocationData("Levels", 265_8018), + "Level 019": KH1LocationData("Levels", 265_8019), + "Level 020": KH1LocationData("Levels", 265_8020), + "Level 021": KH1LocationData("Levels", 265_8021), + "Level 022": KH1LocationData("Levels", 265_8022), + "Level 023": KH1LocationData("Levels", 265_8023), + "Level 024": KH1LocationData("Levels", 265_8024), + "Level 025": KH1LocationData("Levels", 265_8025), + "Level 026": KH1LocationData("Levels", 265_8026), + "Level 027": KH1LocationData("Levels", 265_8027), + "Level 028": KH1LocationData("Levels", 265_8028), + "Level 029": KH1LocationData("Levels", 265_8029), + "Level 030": KH1LocationData("Levels", 265_8030), + "Level 031": KH1LocationData("Levels", 265_8031), + "Level 032": KH1LocationData("Levels", 265_8032), + "Level 033": KH1LocationData("Levels", 265_8033), + "Level 034": KH1LocationData("Levels", 265_8034), + "Level 035": KH1LocationData("Levels", 265_8035), + "Level 036": KH1LocationData("Levels", 265_8036), + "Level 037": KH1LocationData("Levels", 265_8037), + "Level 038": KH1LocationData("Levels", 265_8038), + "Level 039": KH1LocationData("Levels", 265_8039), + "Level 040": KH1LocationData("Levels", 265_8040), + "Level 041": KH1LocationData("Levels", 265_8041), + "Level 042": KH1LocationData("Levels", 265_8042), + "Level 043": KH1LocationData("Levels", 265_8043), + "Level 044": KH1LocationData("Levels", 265_8044), + "Level 045": KH1LocationData("Levels", 265_8045), + "Level 046": KH1LocationData("Levels", 265_8046), + "Level 047": KH1LocationData("Levels", 265_8047), + "Level 048": KH1LocationData("Levels", 265_8048), + "Level 049": KH1LocationData("Levels", 265_8049), + "Level 050": KH1LocationData("Levels", 265_8050), + "Level 051": KH1LocationData("Levels", 265_8051), + "Level 052": KH1LocationData("Levels", 265_8052), + "Level 053": KH1LocationData("Levels", 265_8053), + "Level 054": KH1LocationData("Levels", 265_8054), + "Level 055": KH1LocationData("Levels", 265_8055), + "Level 056": KH1LocationData("Levels", 265_8056), + "Level 057": KH1LocationData("Levels", 265_8057), + "Level 058": KH1LocationData("Levels", 265_8058), + "Level 059": KH1LocationData("Levels", 265_8059), + "Level 060": KH1LocationData("Levels", 265_8060), + "Level 061": KH1LocationData("Levels", 265_8061), + "Level 062": KH1LocationData("Levels", 265_8062), + "Level 063": KH1LocationData("Levels", 265_8063), + "Level 064": KH1LocationData("Levels", 265_8064), + "Level 065": KH1LocationData("Levels", 265_8065), + "Level 066": KH1LocationData("Levels", 265_8066), + "Level 067": KH1LocationData("Levels", 265_8067), + "Level 068": KH1LocationData("Levels", 265_8068), + "Level 069": KH1LocationData("Levels", 265_8069), + "Level 070": KH1LocationData("Levels", 265_8070), + "Level 071": KH1LocationData("Levels", 265_8071), + "Level 072": KH1LocationData("Levels", 265_8072), + "Level 073": KH1LocationData("Levels", 265_8073), + "Level 074": KH1LocationData("Levels", 265_8074), + "Level 075": KH1LocationData("Levels", 265_8075), + "Level 076": KH1LocationData("Levels", 265_8076), + "Level 077": KH1LocationData("Levels", 265_8077), + "Level 078": KH1LocationData("Levels", 265_8078), + "Level 079": KH1LocationData("Levels", 265_8079), + "Level 080": KH1LocationData("Levels", 265_8080), + "Level 081": KH1LocationData("Levels", 265_8081), + "Level 082": KH1LocationData("Levels", 265_8082), + "Level 083": KH1LocationData("Levels", 265_8083), + "Level 084": KH1LocationData("Levels", 265_8084), + "Level 085": KH1LocationData("Levels", 265_8085), + "Level 086": KH1LocationData("Levels", 265_8086), + "Level 087": KH1LocationData("Levels", 265_8087), + "Level 088": KH1LocationData("Levels", 265_8088), + "Level 089": KH1LocationData("Levels", 265_8089), + "Level 090": KH1LocationData("Levels", 265_8090), + "Level 091": KH1LocationData("Levels", 265_8091), + "Level 092": KH1LocationData("Levels", 265_8092), + "Level 093": KH1LocationData("Levels", 265_8093), + "Level 094": KH1LocationData("Levels", 265_8094), + "Level 095": KH1LocationData("Levels", 265_8095), + "Level 096": KH1LocationData("Levels", 265_8096), + "Level 097": KH1LocationData("Levels", 265_8097), + "Level 098": KH1LocationData("Levels", 265_8098), + "Level 099": KH1LocationData("Levels", 265_8099), + "Level 100": KH1LocationData("Levels", 265_8100), + "Complete Phil Cup": KH1LocationData("Olympus Coliseum", 265_9001), + "Complete Phil Cup Solo": KH1LocationData("Olympus Coliseum", 265_9002), + "Complete Phil Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9003), + "Complete Pegasus Cup": KH1LocationData("Olympus Coliseum", 265_9004), + "Complete Pegasus Cup Solo": KH1LocationData("Olympus Coliseum", 265_9005), + "Complete Pegasus Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9006), + "Complete Hercules Cup": KH1LocationData("Olympus Coliseum", 265_9007), + "Complete Hercules Cup Solo": KH1LocationData("Olympus Coliseum", 265_9008), + "Complete Hercules Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9009), + "Complete Hades Cup": KH1LocationData("Olympus Coliseum", 265_9010), + "Complete Hades Cup Solo": KH1LocationData("Olympus Coliseum", 265_9011), + "Complete Hades Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9012), + "Hades Cup Defeat Cloud and Leon Event": KH1LocationData("Olympus Coliseum", 265_9013), + "Hades Cup Defeat Yuffie Event": KH1LocationData("Olympus Coliseum", 265_9014), + "Hades Cup Defeat Cerberus Event": KH1LocationData("Olympus Coliseum", 265_9015), + "Hades Cup Defeat Behemoth Event": KH1LocationData("Olympus Coliseum", 265_9016), + "Hades Cup Defeat Hades Event": KH1LocationData("Olympus Coliseum", 265_9017), + "Hercules Cup Defeat Cloud Event": KH1LocationData("Olympus Coliseum", 265_9018), + "Hercules Cup Yellow Trinity Event": KH1LocationData("Olympus Coliseum", 265_9019), + "Final Ansem": KH1LocationData("Final", 265_9999) +} + +event_location_table: Dict[str, KH1LocationData] = {} + +lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in location_table.items() if data.code} + + +#Make location categories +location_name_groups: Dict[str, Set[str]] = {} +for location in location_table.keys(): + category = location_table[location].category + if category not in location_name_groups.keys(): + location_name_groups[category] = set() + location_name_groups[category].add(location) diff --git a/worlds/kh1/Options.py b/worlds/kh1/Options.py new file mode 100644 index 000000000000..63732f61b2d0 --- /dev/null +++ b/worlds/kh1/Options.py @@ -0,0 +1,445 @@ +from dataclasses import dataclass + +from Options import NamedRange, Choice, Range, Toggle, DefaultOnToggle, PerGameCommonOptions, StartInventoryPool, OptionGroup + +class StrengthIncrease(Range): + """ + Determines the number of Strength Increases to add to the multiworld. + + The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + """ + display_name = "STR Increases" + range_start = 0 + range_end = 100 + default = 24 + +class DefenseIncrease(Range): + """ + Determines the number of Defense Increases to add to the multiworld. + + The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + """ + display_name = "DEF Increases" + range_start = 0 + range_end = 100 + default = 24 + +class HPIncrease(Range): + """ + Determines the number of HP Increases to add to the multiworld. + + The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + """ + display_name = "HP Increases" + range_start = 0 + range_end = 100 + default = 23 + +class APIncrease(Range): + """ + Determines the number of AP Increases to add to the multiworld. + + The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + """ + display_name = "AP Increases" + range_start = 0 + range_end = 100 + default = 18 + +class MPIncrease(Range): + """ + Determines the number of MP Increases to add to the multiworld. + + The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + """ + display_name = "MP Increases" + range_start = 0 + range_end = 20 + default = 7 + +class AccessorySlotIncrease(Range): + """ + Determines the number of Accessory Slot Increases to add to the multiworld. + + The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + """ + display_name = "Accessory Slot Increases" + range_start = 0 + range_end = 6 + default = 1 + +class ItemSlotIncrease(Range): + """ + Determines the number of Item Slot Increases to add to the multiworld. + + The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + """ + display_name = "Item Slot Increases" + range_start = 0 + range_end = 5 + default = 3 + +class Atlantica(Toggle): + """ + Toggle whether to include checks in Atlantica. + """ + display_name = "Atlantica" + +class HundredAcreWood(Toggle): + """ + Toggle whether to include checks in the 100 Acre Wood. + """ + display_name = "100 Acre Wood" + +class SuperBosses(Toggle): + """ + Toggle whether to include checks behind Super Bosses. + """ + display_name = "Super Bosses" + +class Cups(Toggle): + """ + Toggle whether to include checks behind completing Phil, Pegasus, Hercules, or Hades cups. + Please note that the cup items will still appear in the multiworld even if toggled off, as they are required to challenge Sephiroth. + """ + display_name = "Cups" + +class Goal(Choice): + """ + Determines when victory is achieved in your playthrough. + + Sephiroth: Defeat Sephiroth + Unknown: Defeat Unknown + Postcards: Turn in all 10 postcards in Traverse Town + Final Ansem: Enter End of the World and defeat Ansem as normal + Puppies: Rescue and return all 99 puppies in Traverse Town + Final Rest: Open the chest in End of the World Final Rest + """ + display_name = "Goal" + option_sephiroth = 0 + option_unknown = 1 + option_postcards = 2 + option_final_ansem = 3 + option_puppies = 4 + option_final_rest = 5 + default = 3 + +class EndoftheWorldUnlock(Choice): + """Determines how End of the World is unlocked. + + Item: You can receive an item called "End of the World" which unlocks the world + Reports: A certain amount of reports are required to unlock End of the World, which is defined in your options""" + display_name = "End of the World Unlock" + option_item = 0 + option_reports = 1 + default = 1 + +class FinalRestDoor(Choice): + """Determines what conditions need to be met to manifest the door in Final Rest, allowing the player to challenge Ansem. + + Reports: A certain number of Ansem's Reports are required, determined by the "Reports to Open Final Rest Door" option + Puppies: Having all 99 puppies is required + Postcards: Turning in all 10 postcards is required + Superbosses: Defeating Sephiroth, Unknown, Kurt Zisa, and Phantom are required + """ + display_name = "Final Rest Door" + option_reports = 0 + option_puppies = 1 + option_postcards = 2 + option_superbosses = 3 + +class Puppies(Choice): + """ + Determines how dalmatian puppies are shuffled into the pool. + Full: All puppies are in one location + Triplets: Puppies are found in triplets just as they are in the base game + Individual: One puppy can be found per location + """ + display_name = "Puppies" + option_full = 0 + option_triplets = 1 + option_individual = 2 + default = 1 + +class EXPMultiplier(NamedRange): + """ + Determines the multiplier to apply to EXP gained. + """ + display_name = "EXP Multiplier" + default = 16 + range_start = default // 4 + range_end = 128 + special_range_names = { + "0.25x": int(default // 4), + "0.5x": int(default // 2), + "1x": default, + "2x": default * 2, + "3x": default * 3, + "4x": default * 4, + "8x": default * 8, + } + +class RequiredReportsEotW(Range): + """ + If End of the World Unlock is set to "Reports", determines the number of Ansem's Reports required to open End of the World. + """ + display_name = "Reports to Open End of the World" + default = 4 + range_start = 0 + range_end = 13 + +class RequiredReportsDoor(Range): + """ + If Final Rest Door is set to "Reports", determines the number of Ansem's Reports required to manifest the door in Final Rest to challenge Ansem. + """ + display_name = "Reports to Open Final Rest Door" + default = 4 + range_start = 0 + range_end = 13 + +class ReportsInPool(Range): + """ + Determines the number of Ansem's Reports in the item pool. + """ + display_name = "Reports in Pool" + default = 4 + range_start = 0 + range_end = 13 + +class RandomizeKeybladeStats(DefaultOnToggle): + """ + Determines whether Keyblade stats should be randomized. + """ + display_name = "Randomize Keyblade Stats" + +class KeybladeMinStrength(Range): + """ + Determines the minimum STR bonus a keyblade can have. + """ + display_name = "Keyblade Minimum STR Bonus" + default = 3 + range_start = 0 + range_end = 20 + +class KeybladeMaxStrength(Range): + """ + Determines the maximum STR bonus a keyblade can have. + """ + display_name = "Keyblade Maximum STR Bonus" + default = 14 + range_start = 0 + range_end = 20 + +class KeybladeMinMP(Range): + """ + Determines the minimum MP bonus a keyblade can have. + """ + display_name = "Keyblade Minimum MP Bonus" + default = -2 + range_start = -2 + range_end = 5 + +class KeybladeMaxMP(Range): + """ + Determines the maximum MP bonus a keyblade can have. + """ + display_name = "Keyblade Maximum MP Bonus" + default = 3 + range_start = -2 + range_end = 5 + +class LevelChecks(Range): + """ + Determines the maximum level for which checks can be obtained. + """ + display_name = "Level Checks" + default = 100 + range_start = 0 + range_end = 100 + +class ForceStatsOnLevels(NamedRange): + """ + If this value is less than the value for Level Checks, this determines the minimum level from which only stat ups are obtained at level up locations. + For example, if you want to be able to find any multiworld item from levels 1-50, then just stat ups for levels 51-100, set this value to 51. + """ + display_name = "Force Stats on Level Starting From" + default = 1 + range_start = 1 + range_end = 101 + special_range_names = { + "none": 101, + "multiworld-to-level-50": 51, + "all": 1 + } + +class BadStartingWeapons(Toggle): + """ + Forces Kingdom Key, Dream Sword, Dream Shield, and Dream Staff to have bad stats. + """ + display_name = "Bad Starting Weapons" + +class DonaldDeathLink(Toggle): + """ + If Donald is KO'ed, so is Sora. If Death Link is toggled on in your client, this will send a death to everyone. + """ + display_name = "Donald Death Link" + +class GoofyDeathLink(Toggle): + """ + If Goofy is KO'ed, so is Sora. If Death Link is toggled on in your client, this will send a death to everyone. + """ + display_name = "Goofy Death Link" + +class KeybladesUnlockChests(Toggle): + """ + If toggled on, the player is required to have a certain keyblade to open chests in certain worlds. + TT - Lionheart + WL - Lady Luck + OC - Olympia + DJ - Jungle King + AG - Three Wishes + MS - Wishing Star + HT - Pumpkinhead + NL - Fairy Harp + HB - Divine Rose + EotW - Oblivion + HAW - Oathkeeper + + Note: Does not apply to Atlantica, the emblem and carousel chests in Hollow Bastion, or the Aero chest in Neverland currently. + """ + display_name = "Keyblades Unlock Chests" + +class InteractInBattle(Toggle): + """ + Allow Sora to talk to people, examine objects, and open chests in battle. + """ + display_name = "Interact in Battle" + +class AdvancedLogic(Toggle): + """ + If on, logic may expect you to do advanced skips like using Combo Master, Dumbo, and other unusual methods to reach locations. + """ + display_name = "Advanced Logic" + +class ExtraSharedAbilities(Toggle): + """ + If on, adds extra shared abilities to the pool. These can stack, so multiple high jumps make you jump higher and multiple glides make you superglide faster. + """ + display_name = "Extra Shared Abilities" + +class EXPZeroInPool(Toggle): + """ + If on, adds EXP Zero ability to the item pool. This is redundant if you are planning on playing on Proud. + """ + display_name = "EXP Zero in Pool" + +class VanillaEmblemPieces(DefaultOnToggle): + """ + If on, the Hollow Bastion emblem pieces are in their vanilla locations. + """ + display_name = "Vanilla Emblem Pieces" + +class StartingWorlds(Range): + """ + Number of random worlds to start with in addition to Traverse Town, which is always available. Will only consider Atlantica if toggled, and will only consider End of the World if its unlock is set to "Item". + """ + display_name = "Starting Worlds" + default = 0 + range_start = 0 + range_end = 10 + +@dataclass +class KH1Options(PerGameCommonOptions): + goal: Goal + end_of_the_world_unlock: EndoftheWorldUnlock + final_rest_door: FinalRestDoor + required_reports_eotw: RequiredReportsEotW + required_reports_door: RequiredReportsDoor + reports_in_pool: ReportsInPool + super_bosses: SuperBosses + atlantica: Atlantica + hundred_acre_wood: HundredAcreWood + cups: Cups + puppies: Puppies + starting_worlds: StartingWorlds + keyblades_unlock_chests: KeybladesUnlockChests + interact_in_battle: InteractInBattle + exp_multiplier: EXPMultiplier + advanced_logic: AdvancedLogic + extra_shared_abilities: ExtraSharedAbilities + exp_zero_in_pool: EXPZeroInPool + vanilla_emblem_pieces: VanillaEmblemPieces + donald_death_link: DonaldDeathLink + goofy_death_link: GoofyDeathLink + randomize_keyblade_stats: RandomizeKeybladeStats + bad_starting_weapons: BadStartingWeapons + keyblade_min_str: KeybladeMinStrength + keyblade_max_str: KeybladeMaxStrength + keyblade_min_mp: KeybladeMinMP + keyblade_max_mp: KeybladeMaxMP + level_checks: LevelChecks + force_stats_on_levels: ForceStatsOnLevels + strength_increase: StrengthIncrease + defense_increase: DefenseIncrease + hp_increase: HPIncrease + ap_increase: APIncrease + mp_increase: MPIncrease + accessory_slot_increase: AccessorySlotIncrease + item_slot_increase: ItemSlotIncrease + start_inventory_from_pool: StartInventoryPool + +kh1_option_groups = [ + OptionGroup("Goal", [ + Goal, + EndoftheWorldUnlock, + FinalRestDoor, + RequiredReportsDoor, + RequiredReportsEotW, + ReportsInPool, + ]), + OptionGroup("Locations", [ + SuperBosses, + Atlantica, + Cups, + HundredAcreWood, + VanillaEmblemPieces, + ]), + OptionGroup("Levels", [ + EXPMultiplier, + LevelChecks, + ForceStatsOnLevels, + StrengthIncrease, + DefenseIncrease, + HPIncrease, + APIncrease, + MPIncrease, + AccessorySlotIncrease, + ItemSlotIncrease, + ]), + OptionGroup("Keyblades", [ + KeybladesUnlockChests, + RandomizeKeybladeStats, + BadStartingWeapons, + KeybladeMaxStrength, + KeybladeMinStrength, + KeybladeMaxMP, + KeybladeMinMP, + ]), + OptionGroup("Misc", [ + StartingWorlds, + Puppies, + InteractInBattle, + AdvancedLogic, + ExtraSharedAbilities, + EXPZeroInPool, + DonaldDeathLink, + GoofyDeathLink, + ]) +] diff --git a/worlds/kh1/Presets.py b/worlds/kh1/Presets.py new file mode 100644 index 000000000000..77b43b7624b9 --- /dev/null +++ b/worlds/kh1/Presets.py @@ -0,0 +1,177 @@ +from typing import Any, Dict + +from .Options import * + +kh1_option_presets: Dict[str, Dict[str, Any]] = { + # Standard playthrough where your goal is to defeat Ansem, reaching him by acquiring enough reports. + "Final Ansem": { + "goal": Goal.option_final_ansem, + "end_of_the_world_unlock": EndoftheWorldUnlock.option_reports, + "final_rest_door": FinalRestDoor.option_reports, + "required_reports_eotw": 7, + "required_reports_door": 10, + "reports_in_pool": 13, + + "super_bosses": False, + "atlantica": False, + "hundred_acre_wood": False, + "cups": False, + "vanilla_emblem_pieces": True, + + "exp_multiplier": 48, + "level_checks": 100, + "force_stats_on_levels": 1, + "strength_increase": 24, + "defense_increase": 24, + "hp_increase": 23, + "ap_increase": 18, + "mp_increase": 7, + "accessory_slot_increase": 1, + "item_slot_increase": 3, + + "keyblades_unlock_chests": False, + "randomize_keyblade_stats": True, + "bad_starting_weapons": False, + "keyblade_max_str": 14, + "keyblade_min_str": 3, + "keyblade_max_mp": 3, + "keyblade_min_mp": -2, + + "puppies": Puppies.option_triplets, + "starting_worlds": 0, + "interact_in_battle": False, + "advanced_logic": False, + "extra_shared_abilities": False, + "exp_zero_in_pool": False, + "donald_death_link": False, + "goofy_death_link": False + }, + # Puppies are found individually, and the goal is to return them all. + "Puppy Hunt": { + "goal": Goal.option_puppies, + "end_of_the_world_unlock": EndoftheWorldUnlock.option_item, + "final_rest_door": FinalRestDoor.option_puppies, + "required_reports_eotw": 13, + "required_reports_door": 13, + "reports_in_pool": 13, + + "super_bosses": False, + "atlantica": False, + "hundred_acre_wood": False, + "cups": False, + "vanilla_emblem_pieces": True, + + "exp_multiplier": 48, + "level_checks": 100, + "force_stats_on_levels": 1, + "strength_increase": 24, + "defense_increase": 24, + "hp_increase": 23, + "ap_increase": 18, + "mp_increase": 7, + "accessory_slot_increase": 1, + "item_slot_increase": 3, + + "keyblades_unlock_chests": False, + "randomize_keyblade_stats": True, + "bad_starting_weapons": False, + "keyblade_max_str": 14, + "keyblade_min_str": 3, + "keyblade_max_mp": 3, + "keyblade_min_mp": -2, + + "puppies": Puppies.option_individual, + "starting_worlds": 0, + "interact_in_battle": False, + "advanced_logic": False, + "extra_shared_abilities": False, + "exp_zero_in_pool": False, + "donald_death_link": False, + "goofy_death_link": False + }, + # Advanced playthrough with most settings on. + "Advanced": { + "goal": Goal.option_final_ansem, + "end_of_the_world_unlock": EndoftheWorldUnlock.option_reports, + "final_rest_door": FinalRestDoor.option_reports, + "required_reports_eotw": 7, + "required_reports_door": 10, + "reports_in_pool": 13, + + "super_bosses": True, + "atlantica": True, + "hundred_acre_wood": True, + "cups": True, + "vanilla_emblem_pieces": False, + + "exp_multiplier": 48, + "level_checks": 100, + "force_stats_on_levels": 1, + "strength_increase": 24, + "defense_increase": 24, + "hp_increase": 23, + "ap_increase": 18, + "mp_increase": 7, + "accessory_slot_increase": 1, + "item_slot_increase": 3, + + "keyblades_unlock_chests": True, + "randomize_keyblade_stats": True, + "bad_starting_weapons": True, + "keyblade_max_str": 14, + "keyblade_min_str": 3, + "keyblade_max_mp": 3, + "keyblade_min_mp": -2, + + "puppies": Puppies.option_triplets, + "starting_worlds": 0, + "interact_in_battle": True, + "advanced_logic": True, + "extra_shared_abilities": True, + "exp_zero_in_pool": True, + "donald_death_link": False, + "goofy_death_link": False + }, + # Playthrough meant to enhance the level 1 experience. + "Level 1": { + "goal": Goal.option_final_ansem, + "end_of_the_world_unlock": EndoftheWorldUnlock.option_reports, + "final_rest_door": FinalRestDoor.option_reports, + "required_reports_eotw": 7, + "required_reports_door": 10, + "reports_in_pool": 13, + + "super_bosses": False, + "atlantica": False, + "hundred_acre_wood": False, + "cups": False, + "vanilla_emblem_pieces": True, + + "exp_multiplier": 16, + "level_checks": 0, + "force_stats_on_levels": 101, + "strength_increase": 0, + "defense_increase": 0, + "hp_increase": 0, + "mp_increase": 0, + "accessory_slot_increase": 6, + "item_slot_increase": 5, + + "keyblades_unlock_chests": False, + "randomize_keyblade_stats": True, + "bad_starting_weapons": False, + "keyblade_max_str": 14, + "keyblade_min_str": 3, + "keyblade_max_mp": 3, + "keyblade_min_mp": -2, + + "puppies": Puppies.option_triplets, + "starting_worlds": 0, + "interact_in_battle": False, + "advanced_logic": False, + "extra_shared_abilities": False, + "exp_zero_in_pool": False, + "donald_death_link": False, + "goofy_death_link": False + } +} diff --git a/worlds/kh1/Regions.py b/worlds/kh1/Regions.py new file mode 100644 index 000000000000..a6f85fe617cb --- /dev/null +++ b/worlds/kh1/Regions.py @@ -0,0 +1,516 @@ +from typing import Dict, List, NamedTuple, Optional + +from BaseClasses import MultiWorld, Region, Entrance +from .Locations import KH1Location, location_table + + +class KH1RegionData(NamedTuple): + locations: List[str] + region_exits: Optional[List[str]] + + +def create_regions(multiworld: MultiWorld, player: int, options): + regions: Dict[str, KH1RegionData] = { + "Menu": KH1RegionData([], ["Awakening", "Levels"]), + "Awakening": KH1RegionData([], ["Destiny Islands"]), + "Destiny Islands": KH1RegionData([], ["Traverse Town"]), + "Traverse Town": KH1RegionData([], ["World Map"]), + "Wonderland": KH1RegionData([], []), + "Olympus Coliseum": KH1RegionData([], []), + "Deep Jungle": KH1RegionData([], []), + "Agrabah": KH1RegionData([], []), + "Monstro": KH1RegionData([], []), + "Atlantica": KH1RegionData([], []), + "Halloween Town": KH1RegionData([], []), + "Neverland": KH1RegionData([], []), + "Hollow Bastion": KH1RegionData([], []), + "End of the World": KH1RegionData([], []), + "100 Acre Wood": KH1RegionData([], []), + "Levels": KH1RegionData([], []), + "World Map": KH1RegionData([], ["Wonderland", "Olympus Coliseum", "Deep Jungle", + "Agrabah", "Monstro", "Atlantica", + "Halloween Town", "Neverland", "Hollow Bastion", + "End of the World", "100 Acre Wood"]) + } + + # Set up locations + regions["Agrabah"].locations.append("Agrabah Aladdin's House Main Street Entrance Chest") + regions["Agrabah"].locations.append("Agrabah Aladdin's House Plaza Entrance Chest") + regions["Agrabah"].locations.append("Agrabah Alley Chest") + regions["Agrabah"].locations.append("Agrabah Bazaar Across Windows Chest") + regions["Agrabah"].locations.append("Agrabah Bazaar High Corner Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Bottomless Hall Across Chasm Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Bottomless Hall Pillar Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Bottomless Hall Raised Platform Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Dark Chamber Abu Gem Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Dark Chamber Across from Relic Chamber Entrance Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Dark Chamber Bridge Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Dark Chamber Near Save Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Entrance Left Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Entrance Tall Tower Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Entrance White Trinity Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Hall High Left Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Hall Near Bottomless Hall Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Hidden Room Left Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Hidden Room Right Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Relic Chamber Jump from Stairs Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Relic Chamber Stairs Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Silent Chamber Blue Trinity Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Above Fire Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Across Platforms Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Large Treasure Pile Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Small Treasure Pile Chest") + regions["Agrabah"].locations.append("Agrabah Defeat Jafar Blizzard Event") + regions["Agrabah"].locations.append("Agrabah Defeat Jafar Genie Ansem's Report 1") + regions["Agrabah"].locations.append("Agrabah Defeat Jafar Genie Fire Event") + regions["Agrabah"].locations.append("Agrabah Defeat Pot Centipede Ray of Light Event") + regions["Agrabah"].locations.append("Agrabah Main Street High Above Alley Entrance Chest") + regions["Agrabah"].locations.append("Agrabah Main Street High Above Palace Gates Entrance Chest") + regions["Agrabah"].locations.append("Agrabah Main Street Right Palace Entrance Chest") + regions["Agrabah"].locations.append("Agrabah Palace Gates High Close to Palace Chest") + regions["Agrabah"].locations.append("Agrabah Palace Gates High Opposite Palace Chest") + regions["Agrabah"].locations.append("Agrabah Palace Gates Low Chest") + regions["Agrabah"].locations.append("Agrabah Plaza By Storage Chest") + regions["Agrabah"].locations.append("Agrabah Plaza Raised Terrace Chest") + regions["Agrabah"].locations.append("Agrabah Plaza Top Corner Chest") + regions["Agrabah"].locations.append("Agrabah Seal Keyhole Genie Event") + regions["Agrabah"].locations.append("Agrabah Seal Keyhole Green Trinity Event") + regions["Agrabah"].locations.append("Agrabah Seal Keyhole Three Wishes Event") + regions["Agrabah"].locations.append("Agrabah Storage Behind Barrel Chest") + regions["Agrabah"].locations.append("Agrabah Storage Green Trinity Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Bamboo Thicket Save Gorillas") + regions["Deep Jungle"].locations.append("Deep Jungle Camp Blue Trinity Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Camp Ether Experiment") + regions["Deep Jungle"].locations.append("Deep Jungle Camp Hi-Potion Experiment") + regions["Deep Jungle"].locations.append("Deep Jungle Camp Replication Experiment") + regions["Deep Jungle"].locations.append("Deep Jungle Camp Save Gorillas") + regions["Deep Jungle"].locations.append("Deep Jungle Cavern of Hearts Navi-G Piece Event") + regions["Deep Jungle"].locations.append("Deep Jungle Cavern of Hearts White Trinity Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Cliff Right Cliff Left Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Cliff Right Cliff Right Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Cliff Save Gorillas") + regions["Deep Jungle"].locations.append("Deep Jungle Climbing Trees Blue Trinity Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Climbing Trees Save Gorillas") + regions["Deep Jungle"].locations.append("Deep Jungle Defeat Clayton Cure Event") + regions["Deep Jungle"].locations.append("Deep Jungle Defeat Sabor White Fang Event") + regions["Deep Jungle"].locations.append("Deep Jungle Hippo's Lagoon Center Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Hippo's Lagoon Left Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Hippo's Lagoon Right Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 10 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 20 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 30 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 40 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 50 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Seal Keyhole Jungle King Event") + regions["Deep Jungle"].locations.append("Deep Jungle Seal Keyhole Red Trinity Event") + regions["Deep Jungle"].locations.append("Deep Jungle Tent Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Tent Protect-G Event") + regions["Deep Jungle"].locations.append("Deep Jungle Tree House Beneath Tree House Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Tree House Rooftop Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Tree House Save Gorillas") + regions["Deep Jungle"].locations.append("Deep Jungle Tree House Suspended Boat Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Tunnel Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Vines 2 Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Vines Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Waterfall Cavern High Middle Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Waterfall Cavern High Wall Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Waterfall Cavern Low Chest") + regions["Deep Jungle"].locations.append("Deep Jungle Waterfall Cavern Middle Chest") + regions["End of the World"].locations.append("End of the World Defeat Chernabog Superglide Event") + regions["End of the World"].locations.append("End of the World Final Dimension 10th Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 1st Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 2nd Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 3rd Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 4th Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 5th Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 6th Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 7th Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 8th Chest") + regions["End of the World"].locations.append("End of the World Final Dimension 9th Chest") + regions["End of the World"].locations.append("End of the World Final Rest Chest") + regions["End of the World"].locations.append("End of the World Giant Crevasse 1st Chest") + regions["End of the World"].locations.append("End of the World Giant Crevasse 2nd Chest") + regions["End of the World"].locations.append("End of the World Giant Crevasse 3rd Chest") + regions["End of the World"].locations.append("End of the World Giant Crevasse 4th Chest") + regions["End of the World"].locations.append("End of the World Giant Crevasse 5th Chest") + regions["End of the World"].locations.append("End of the World World Terminus 100 Acre Wood Chest") + regions["End of the World"].locations.append("End of the World World Terminus Agrabah Chest") + regions["End of the World"].locations.append("End of the World World Terminus Atlantica Chest") + regions["End of the World"].locations.append("End of the World World Terminus Deep Jungle Chest") + regions["End of the World"].locations.append("End of the World World Terminus Halloween Town Chest") + #regions["End of the World"].locations.append("End of the World World Terminus Hollow Bastion Chest") + regions["End of the World"].locations.append("End of the World World Terminus Neverland Chest") + regions["End of the World"].locations.append("End of the World World Terminus Olympus Coliseum Chest") + regions["End of the World"].locations.append("End of the World World Terminus Traverse Town Chest") + regions["End of the World"].locations.append("End of the World World Terminus Wonderland Chest") + regions["Halloween Town"].locations.append("Halloween Town Boneyard Tombstone Puzzle Chest") + regions["Halloween Town"].locations.append("Halloween Town Bridge Left of Gate Chest") + regions["Halloween Town"].locations.append("Halloween Town Bridge Right of Gate Chest") + regions["Halloween Town"].locations.append("Halloween Town Bridge Under Bridge") + regions["Halloween Town"].locations.append("Halloween Town Cemetery Behind Grave Chest") + regions["Halloween Town"].locations.append("Halloween Town Cemetery Between Graves Chest") + regions["Halloween Town"].locations.append("Halloween Town Cemetery By Cat Shape Chest") + regions["Halloween Town"].locations.append("Halloween Town Cemetery By Striped Grave Chest") + regions["Halloween Town"].locations.append("Halloween Town Defeat Oogie Boogie Ansem's Report 7") + regions["Halloween Town"].locations.append("Halloween Town Defeat Oogie Boogie Holy Circlet Event") + regions["Halloween Town"].locations.append("Halloween Town Defeat Oogie's Manor Gravity Event") + regions["Halloween Town"].locations.append("Halloween Town Graveyard Forget-Me-Not Event") + regions["Halloween Town"].locations.append("Halloween Town Guillotine Square High Tower Chest") + regions["Halloween Town"].locations.append("Halloween Town Guillotine Square Pumpkin Structure Left Chest") + regions["Halloween Town"].locations.append("Halloween Town Guillotine Square Pumpkin Structure Right Chest") + regions["Halloween Town"].locations.append("Halloween Town Guillotine Square Ring Jack's Doorbell 3 Times") + regions["Halloween Town"].locations.append("Halloween Town Guillotine Square Under Jack's House Stairs Chest") + regions["Halloween Town"].locations.append("Halloween Town Lab Torn Page") + regions["Halloween Town"].locations.append("Halloween Town Moonlight Hill White Trinity Chest") + regions["Halloween Town"].locations.append("Halloween Town Oogie's Manor Entrance Steps Chest") + regions["Halloween Town"].locations.append("Halloween Town Oogie's Manor Grounds Red Trinity Chest") + regions["Halloween Town"].locations.append("Halloween Town Oogie's Manor Hollow Chest") + regions["Halloween Town"].locations.append("Halloween Town Oogie's Manor Inside Entrance Chest") + regions["Halloween Town"].locations.append("Halloween Town Oogie's Manor Lower Iron Cage Chest") + regions["Halloween Town"].locations.append("Halloween Town Oogie's Manor Upper Iron Cage Chest") + regions["Halloween Town"].locations.append("Halloween Town Seal Keyhole Pumpkinhead Event") + regions["Hollow Bastion"].locations.append("Hollow Bastion Base Level Bubble Under the Wall Platform Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Base Level Near Crystal Switch Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Base Level Platform Near Entrance Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Castle Gates Freestanding Pillar Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Castle Gates Gravity Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Castle Gates High Pillar Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Behemoth Omega Arts Event") + regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Dragon Maleficent Fireglow Event") + regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Maleficent Ansem's Report 5") + regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Maleficent Donald Cheer Event") + regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Riku I White Trinity Event") + regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Riku II Ragnarok Event") + regions["Hollow Bastion"].locations.append("Hollow Bastion Dungeon By Candles Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Dungeon Corner Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Entrance Hall Emblem Piece (Chest)") + regions["Hollow Bastion"].locations.append("Hollow Bastion Entrance Hall Emblem Piece (Flame)") + regions["Hollow Bastion"].locations.append("Hollow Bastion Entrance Hall Emblem Piece (Fountain)") + regions["Hollow Bastion"].locations.append("Hollow Bastion Entrance Hall Emblem Piece (Statue)") + regions["Hollow Bastion"].locations.append("Hollow Bastion Entrance Hall Left of Emblem Door Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Grand Hall Left of Gate Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Grand Hall Oblivion Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Grand Hall Steps Right Side Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Great Crest After Battle Platform Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Great Crest Lower Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion High Tower 1st Gravity Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion High Tower 2nd Gravity Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion High Tower Above Sliding Blocks Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Library 1st Floor Turn the Carousel Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Library 2nd Floor Turn the Carousel 1st Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Library 2nd Floor Turn the Carousel 2nd Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Library Speak to Aerith Cure") + regions["Hollow Bastion"].locations.append("Hollow Bastion Library Speak to Belle Divine Rose") + regions["Hollow Bastion"].locations.append("Hollow Bastion Library Top of Bookshelf Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Library Top of Bookshelf Turn the Carousel Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop Library Node Gravity Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop Outside Library Gravity Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop Under High Tower Sliding Blocks Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Rising Falls Floating Platform Near Bubble Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Rising Falls Floating Platform Near Save Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Rising Falls High Platform Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Rising Falls Under Water 1st Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Rising Falls Under Water 2nd Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Rising Falls Water's Surface Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Rising Falls White Trinity Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Speak to Princesses Fire Event") + regions["Hollow Bastion"].locations.append("Hollow Bastion Speak with Aerith Ansem's Report 10") + regions["Hollow Bastion"].locations.append("Hollow Bastion Speak with Aerith Ansem's Report 2") + regions["Hollow Bastion"].locations.append("Hollow Bastion Speak with Aerith Ansem's Report 4") + regions["Hollow Bastion"].locations.append("Hollow Bastion Speak with Aerith Ansem's Report 6") + regions["Hollow Bastion"].locations.append("Hollow Bastion Waterway Blizzard on Bubble Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Waterway Near Save Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Waterway Unlock Passage from Base Level Chest") + regions["Monstro"].locations.append("Monstro Chamber 2 Ground Chest") + regions["Monstro"].locations.append("Monstro Chamber 2 Platform Chest") + regions["Monstro"].locations.append("Monstro Chamber 3 Ground Chest") + regions["Monstro"].locations.append("Monstro Chamber 3 Near Chamber 6 Entrance Chest") + regions["Monstro"].locations.append("Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest") + regions["Monstro"].locations.append("Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest") + regions["Monstro"].locations.append("Monstro Chamber 5 Atop Barrel Chest") + regions["Monstro"].locations.append("Monstro Chamber 5 Low 1st Chest") + regions["Monstro"].locations.append("Monstro Chamber 5 Low 2nd Chest") + regions["Monstro"].locations.append("Monstro Chamber 5 Platform Chest") + regions["Monstro"].locations.append("Monstro Chamber 6 Low Chest") + regions["Monstro"].locations.append("Monstro Chamber 6 Other Platform Chest") + regions["Monstro"].locations.append("Monstro Chamber 6 Platform Near Chamber 5 Entrance Chest") + regions["Monstro"].locations.append("Monstro Chamber 6 Raised Area Near Chamber 1 Entrance Chest") + regions["Monstro"].locations.append("Monstro Chamber 6 White Trinity Chest") + regions["Monstro"].locations.append("Monstro Defeat Parasite Cage I Goofy Cheer Event") + regions["Monstro"].locations.append("Monstro Defeat Parasite Cage II Stop Event") + regions["Monstro"].locations.append("Monstro Mouth Boat Deck Chest") + regions["Monstro"].locations.append("Monstro Mouth Green Trinity Top of Boat Chest") + regions["Monstro"].locations.append("Monstro Mouth High Platform Across from Boat Chest") + regions["Monstro"].locations.append("Monstro Mouth High Platform Boat Side Chest") + regions["Monstro"].locations.append("Monstro Mouth High Platform Near Teeth Chest") + regions["Monstro"].locations.append("Monstro Mouth Near Ship Chest") + regions["Neverland"].locations.append("Neverland Cabin Chest") + regions["Neverland"].locations.append("Neverland Captain's Cabin Chest") + #regions["Neverland"].locations.append("Neverland Clock Tower 01:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 02:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 03:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 04:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 05:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 06:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 07:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 08:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 09:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 10:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 11:00 Door") + #regions["Neverland"].locations.append("Neverland Clock Tower 12:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower Chest") + regions["Neverland"].locations.append("Neverland Defeat Anti Sora Raven's Claw Event") + regions["Neverland"].locations.append("Neverland Defeat Captain Hook Ars Arcanum Event") + regions["Neverland"].locations.append("Neverland Defeat Hook Ansem's Report 9") + regions["Neverland"].locations.append("Neverland Encounter Hook Cure Event") + regions["Neverland"].locations.append("Neverland Galley Chest") + regions["Neverland"].locations.append("Neverland Hold Aero Chest") + regions["Neverland"].locations.append("Neverland Hold Flight 1st Chest") + regions["Neverland"].locations.append("Neverland Hold Flight 2nd Chest") + regions["Neverland"].locations.append("Neverland Hold Yellow Trinity Green Chest") + regions["Neverland"].locations.append("Neverland Hold Yellow Trinity Left Blue Chest") + regions["Neverland"].locations.append("Neverland Hold Yellow Trinity Right Blue Chest") + regions["Neverland"].locations.append("Neverland Pirate Ship Crows Nest Chest") + regions["Neverland"].locations.append("Neverland Pirate Ship Deck White Trinity Chest") + regions["Neverland"].locations.append("Neverland Seal Keyhole Fairy Harp Event") + regions["Neverland"].locations.append("Neverland Seal Keyhole Glide Event") + regions["Neverland"].locations.append("Neverland Seal Keyhole Tinker Bell Event") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Clear Phil's Training Thunder Event") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Cloud Sonic Blade Event") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates Blizzaga Chest") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates Blizzara Chest") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates Entry Pass Event") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates Green Trinity") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates Hero's License Event") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates Left Behind Columns Chest") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates Left Blue Trinity Chest") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates Right Blue Trinity Chest") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Coliseum Gates White Trinity Chest") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Cerberus Inferno Band Event") + regions["Traverse Town"].locations.append("Traverse Town 1st District Accessory Shop Roof Chest") + #regions["Traverse Town"].locations.append("Traverse Town 1st District Aerith Gift") + regions["Traverse Town"].locations.append("Traverse Town 1st District Blue Trinity Balcony Chest") + regions["Traverse Town"].locations.append("Traverse Town 1st District Candle Puzzle Chest") + #regions["Traverse Town"].locations.append("Traverse Town 1st District Leon Gift") + regions["Traverse Town"].locations.append("Traverse Town 1st District Safe Postcard") + regions["Traverse Town"].locations.append("Traverse Town 1st District Speak with Cid Event") + regions["Traverse Town"].locations.append("Traverse Town 2nd District Boots and Shoes Awning Chest") + regions["Traverse Town"].locations.append("Traverse Town 2nd District Gizmo Shop Facade Chest") + regions["Traverse Town"].locations.append("Traverse Town 2nd District Rooftop Chest") + regions["Traverse Town"].locations.append("Traverse Town 3rd District Balcony Postcard") + regions["Traverse Town"].locations.append("Traverse Town Accessory Shop Chest") + regions["Traverse Town"].locations.append("Traverse Town Alleyway Balcony Chest") + regions["Traverse Town"].locations.append("Traverse Town Alleyway Behind Crates Chest") + regions["Traverse Town"].locations.append("Traverse Town Alleyway Blue Room Awning Chest") + regions["Traverse Town"].locations.append("Traverse Town Alleyway Corner Chest") + regions["Traverse Town"].locations.append("Traverse Town Defeat Guard Armor Blue Trinity Event") + regions["Traverse Town"].locations.append("Traverse Town Defeat Guard Armor Brave Warrior Event") + regions["Traverse Town"].locations.append("Traverse Town Defeat Guard Armor Dodge Roll Event") + regions["Traverse Town"].locations.append("Traverse Town Defeat Guard Armor Fire Event") + regions["Traverse Town"].locations.append("Traverse Town Defeat Opposite Armor Aero Event") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Chest") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Geppetto All Summons Reward") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Geppetto Reward 1") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Geppetto Reward 2") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Geppetto Reward 3") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Geppetto Reward 4") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Geppetto Reward 5") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Postcard") + regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Talk to Pinocchio") + regions["Traverse Town"].locations.append("Traverse Town Gizmo Shop Postcard 1") + regions["Traverse Town"].locations.append("Traverse Town Gizmo Shop Postcard 2") + regions["Traverse Town"].locations.append("Traverse Town Green Room Clock Puzzle Chest") + regions["Traverse Town"].locations.append("Traverse Town Green Room Table Chest") + regions["Traverse Town"].locations.append("Traverse Town Item Shop Postcard") + regions["Traverse Town"].locations.append("Traverse Town Item Workshop Left Chest") + regions["Traverse Town"].locations.append("Traverse Town Item Workshop Postcard") + regions["Traverse Town"].locations.append("Traverse Town Item Workshop Right Chest") + regions["Traverse Town"].locations.append("Traverse Town Kairi Secret Waterway Oathkeeper Event") + regions["Traverse Town"].locations.append("Traverse Town Leon Secret Waterway Earthshine Event") + regions["Traverse Town"].locations.append("Traverse Town Magician's Study Obtained All Arts Items") + regions["Traverse Town"].locations.append("Traverse Town Magician's Study Obtained All LV1 Magic") + regions["Traverse Town"].locations.append("Traverse Town Magician's Study Obtained All LV3 Magic") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 01 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 02 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 03 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 04 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 05 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 06 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 07 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 08 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 09 Event") + regions["Traverse Town"].locations.append("Traverse Town Mail Postcard 10 Event") + regions["Traverse Town"].locations.append("Traverse Town Mystical House Glide Chest") + regions["Traverse Town"].locations.append("Traverse Town Mystical House Yellow Trinity Chest") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 10 Puppies") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 20 Puppies") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 30 Puppies") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 40 Puppies") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 50 Puppies Reward 1") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 50 Puppies Reward 2") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 60 Puppies") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 70 Puppies") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 80 Puppies") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 90 Puppies") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 99 Puppies Reward 1") + regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 99 Puppies Reward 2") + regions["Traverse Town"].locations.append("Traverse Town Red Room Chest") + regions["Traverse Town"].locations.append("Traverse Town Secret Waterway Near Stairs Chest") + regions["Traverse Town"].locations.append("Traverse Town Secret Waterway White Trinity Chest") + regions["Traverse Town"].locations.append("Traverse Town Synth Cloth") + regions["Traverse Town"].locations.append("Traverse Town Synth Fish") + regions["Traverse Town"].locations.append("Traverse Town Synth Log") + regions["Traverse Town"].locations.append("Traverse Town Synth Mushroom") + regions["Traverse Town"].locations.append("Traverse Town Synth Rope") + regions["Traverse Town"].locations.append("Traverse Town Synth Seagull Egg") + regions["Wonderland"].locations.append("Wonderland Bizarre Room Green Trinity Chest") + regions["Wonderland"].locations.append("Wonderland Bizarre Room Lamp Chest") + regions["Wonderland"].locations.append("Wonderland Bizarre Room Navi-G Piece Event") + regions["Wonderland"].locations.append("Wonderland Bizarre Room Read Book") + regions["Wonderland"].locations.append("Wonderland Defeat Trickmaster Blizzard Event") + regions["Wonderland"].locations.append("Wonderland Defeat Trickmaster Ifrit's Horn Event") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Corner Chest") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Glide Chest") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Nut Chest") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Through the Painting Thunder Plant Chest") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Through the Painting White Trinity Chest") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Thunder Plant Chest") + regions["Wonderland"].locations.append("Wonderland Queen's Castle Hedge Left Red Chest") + regions["Wonderland"].locations.append("Wonderland Queen's Castle Hedge Right Blue Chest") + regions["Wonderland"].locations.append("Wonderland Queen's Castle Hedge Right Red Chest") + regions["Wonderland"].locations.append("Wonderland Rabbit Hole Defeat Heartless 1 Chest") + regions["Wonderland"].locations.append("Wonderland Rabbit Hole Defeat Heartless 2 Chest") + regions["Wonderland"].locations.append("Wonderland Rabbit Hole Defeat Heartless 3 Chest") + regions["Wonderland"].locations.append("Wonderland Rabbit Hole Green Trinity Chest") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Bear and Clock Puzzle Chest") + if options.hundred_acre_wood: + regions["100 Acre Wood"].locations.append("100 Acre Wood Meadow Inside Log Chest") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Left Cliff Chest") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Right Tree Alcove Chest") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Under Giant Pot Chest") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Turn in Rare Nut 1") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Turn in Rare Nut 2") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Turn in Rare Nut 3") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Turn in Rare Nut 4") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Turn in Rare Nut 5") + regions["100 Acre Wood"].locations.append("100 Acre Wood Pooh's House Owl Cheer") + regions["100 Acre Wood"].locations.append("100 Acre Wood Convert Torn Page 1") + regions["100 Acre Wood"].locations.append("100 Acre Wood Convert Torn Page 2") + regions["100 Acre Wood"].locations.append("100 Acre Wood Convert Torn Page 3") + regions["100 Acre Wood"].locations.append("100 Acre Wood Convert Torn Page 4") + regions["100 Acre Wood"].locations.append("100 Acre Wood Convert Torn Page 5") + regions["100 Acre Wood"].locations.append("100 Acre Wood Pooh's House Start Fire") + regions["100 Acre Wood"].locations.append("100 Acre Wood Pooh's Room Cabinet") + regions["100 Acre Wood"].locations.append("100 Acre Wood Pooh's Room Chimney") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Break Log") + regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Fall Through Top of Tree Next to Pooh") + if options.atlantica: + regions["Atlantica"].locations.append("Atlantica Sunken Ship In Flipped Boat Chest") + regions["Atlantica"].locations.append("Atlantica Sunken Ship Seabed Chest") + regions["Atlantica"].locations.append("Atlantica Sunken Ship Inside Ship Chest") + regions["Atlantica"].locations.append("Atlantica Ariel's Grotto High Chest") + regions["Atlantica"].locations.append("Atlantica Ariel's Grotto Middle Chest") + regions["Atlantica"].locations.append("Atlantica Ariel's Grotto Low Chest") + regions["Atlantica"].locations.append("Atlantica Ursula's Lair Use Fire on Urchin Chest") + regions["Atlantica"].locations.append("Atlantica Undersea Gorge Jammed by Ariel's Grotto Chest") + regions["Atlantica"].locations.append("Atlantica Triton's Palace White Trinity Chest") + regions["Atlantica"].locations.append("Atlantica Defeat Ursula I Mermaid Kick Event") + regions["Atlantica"].locations.append("Atlantica Defeat Ursula II Thunder Event") + regions["Atlantica"].locations.append("Atlantica Seal Keyhole Crabclaw Event") + regions["Atlantica"].locations.append("Atlantica Undersea Gorge Blizzard Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Gorge Ocean Floor Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Valley Higher Cave Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Valley Lower Cave Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Valley Fire Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Valley Wall Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Valley Pillar Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Valley Ocean Floor Clam") + regions["Atlantica"].locations.append("Atlantica Triton's Palace Thunder Clam") + regions["Atlantica"].locations.append("Atlantica Triton's Palace Wall Right Clam") + regions["Atlantica"].locations.append("Atlantica Triton's Palace Near Path Clam") + regions["Atlantica"].locations.append("Atlantica Triton's Palace Wall Left Clam") + regions["Atlantica"].locations.append("Atlantica Cavern Nook Clam") + regions["Atlantica"].locations.append("Atlantica Below Deck Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Garden Clam") + regions["Atlantica"].locations.append("Atlantica Undersea Cave Clam") + regions["Atlantica"].locations.append("Atlantica Sunken Ship Crystal Trident Event") + regions["Atlantica"].locations.append("Atlantica Defeat Ursula II Ansem's Report 3") + if options.cups: + regions["Olympus Coliseum"].locations.append("Complete Phil Cup") + regions["Olympus Coliseum"].locations.append("Complete Phil Cup Solo") + regions["Olympus Coliseum"].locations.append("Complete Phil Cup Time Trial") + regions["Olympus Coliseum"].locations.append("Complete Pegasus Cup") + regions["Olympus Coliseum"].locations.append("Complete Pegasus Cup Solo") + regions["Olympus Coliseum"].locations.append("Complete Pegasus Cup Time Trial") + regions["Olympus Coliseum"].locations.append("Complete Hercules Cup") + regions["Olympus Coliseum"].locations.append("Complete Hercules Cup Solo") + regions["Olympus Coliseum"].locations.append("Complete Hercules Cup Time Trial") + regions["Olympus Coliseum"].locations.append("Complete Hades Cup") + regions["Olympus Coliseum"].locations.append("Complete Hades Cup Solo") + regions["Olympus Coliseum"].locations.append("Complete Hades Cup Time Trial") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Cloud and Leon Event") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Yuffie Event") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Cerberus Event") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Behemoth Event") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Hades Event") + regions["Olympus Coliseum"].locations.append("Hercules Cup Defeat Cloud Event") + regions["Olympus Coliseum"].locations.append("Hercules Cup Yellow Trinity Event") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Hades Ansem's Report 8") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Olympia Chest") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Ice Titan Diamond Dust Event") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Gates Purple Jar After Defeating Hades") + if options.super_bosses: + regions["Neverland"].locations.append("Neverland Defeat Phantom Stop Event") + regions["Agrabah"].locations.append("Agrabah Defeat Kurt Zisa Zantetsuken Event") + regions["Agrabah"].locations.append("Agrabah Defeat Kurt Zisa Ansem's Report 11") + if options.super_bosses or options.goal.current_key == "sephiroth": + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Sephiroth Ansem's Report 12") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Sephiroth One-Winged Angel Event") + if options.super_bosses or options.goal.current_key == "unknown": + regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Unknown Ansem's Report 13") + regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Unknown EXP Necklace Event") + for i in range(options.level_checks): + regions["Levels"].locations.append("Level " + str(i+1).rjust(3, '0')) + if options.goal.current_key == "final_ansem": + regions["End of the World"].locations.append("Final Ansem") + + # Set up the regions correctly. + for name, data in regions.items(): + multiworld.regions.append(create_region(multiworld, player, name, data)) + + multiworld.get_entrance("Awakening", player).connect(multiworld.get_region("Awakening", player)) + multiworld.get_entrance("Destiny Islands", player).connect(multiworld.get_region("Destiny Islands", player)) + multiworld.get_entrance("Traverse Town", player).connect(multiworld.get_region("Traverse Town", player)) + multiworld.get_entrance("Wonderland", player).connect(multiworld.get_region("Wonderland", player)) + multiworld.get_entrance("Olympus Coliseum", player).connect(multiworld.get_region("Olympus Coliseum", player)) + multiworld.get_entrance("Deep Jungle", player).connect(multiworld.get_region("Deep Jungle", player)) + multiworld.get_entrance("Agrabah", player).connect(multiworld.get_region("Agrabah", player)) + multiworld.get_entrance("Monstro", player).connect(multiworld.get_region("Monstro", player)) + multiworld.get_entrance("Atlantica", player).connect(multiworld.get_region("Atlantica", player)) + multiworld.get_entrance("Halloween Town", player).connect(multiworld.get_region("Halloween Town", player)) + multiworld.get_entrance("Neverland", player).connect(multiworld.get_region("Neverland", player)) + multiworld.get_entrance("Hollow Bastion", player).connect(multiworld.get_region("Hollow Bastion", player)) + multiworld.get_entrance("End of the World", player).connect(multiworld.get_region("End of the World", player)) + multiworld.get_entrance("100 Acre Wood", player).connect(multiworld.get_region("100 Acre Wood", player)) + multiworld.get_entrance("World Map", player).connect(multiworld.get_region("World Map", player)) + multiworld.get_entrance("Levels", player).connect(multiworld.get_region("Levels", player)) + +def create_region(multiworld: MultiWorld, player: int, name: str, data: KH1RegionData): + region = Region(name, player, multiworld) + if data.locations: + for loc_name in data.locations: + loc_data = location_table.get(loc_name) + location = KH1Location(player, loc_name, loc_data.code if loc_data else None, region) + region.locations.append(location) + + if data.region_exits: + for exit in data.region_exits: + entrance = Entrance(player, exit, region) + region.exits.append(entrance) + + return region diff --git a/worlds/kh1/Rules.py b/worlds/kh1/Rules.py new file mode 100644 index 000000000000..c8cb71ffd636 --- /dev/null +++ b/worlds/kh1/Rules.py @@ -0,0 +1,1947 @@ +from BaseClasses import CollectionState +from worlds.generic.Rules import add_rule + +SINGLE_PUPPIES = ["Puppy " + str(i).rjust(2,"0") for i in range(1,100)] +TRIPLE_PUPPIES = ["Puppies " + str(3*(i-1)+1).rjust(2, "0") + "-" + str(3*(i-1)+3).rjust(2, "0") for i in range(1,34)] +TORN_PAGES = ["Torn Page " + str(i) for i in range(1,6)] +WORLDS = ["Wonderland", "Olympus Coliseum", "Deep Jungle", "Agrabah", "Monstro", "Atlantica", "Halloween Town", "Neverland", "Hollow Bastion", "End of the World"] +KEYBLADES = ["Lady Luck", "Olympia", "Jungle King", "Three Wishes", "Wishing Star", "Crabclaw", "Pumpkinhead", "Fairy Harp", "Divine Rose", "Oblivion"] + +def has_x_worlds(state: CollectionState, player: int, num_of_worlds: int, keyblades_unlock_chests: bool) -> bool: + worlds_acquired = 0.0 + for i in range(len(WORLDS)): + if state.has(WORLDS[i], player): + worlds_acquired = worlds_acquired + 0.5 + if (state.has(WORLDS[i], player) and (not keyblades_unlock_chests or state.has(KEYBLADES[i], player))) or (state.has(WORLDS[i], player) and WORLDS[i] == "Atlantica"): + worlds_acquired = worlds_acquired + 0.5 + return worlds_acquired >= num_of_worlds + +def has_emblems(state: CollectionState, player: int, keyblades_unlock_chests: bool) -> bool: + return state.has_all({ + "Emblem Piece (Flame)", + "Emblem Piece (Chest)", + "Emblem Piece (Statue)", + "Emblem Piece (Fountain)", + "Hollow Bastion"}, player) and has_x_worlds(state, player, 5, keyblades_unlock_chests) + +def has_puppies_all(state: CollectionState, player: int, puppies_required: int) -> bool: + return state.has("All Puppies", player) + +def has_puppies_triplets(state: CollectionState, player: int, puppies_required: int) -> bool: + return state.has_from_list_unique(TRIPLE_PUPPIES, player, -(puppies_required / -3)) + +def has_puppies_individual(state: CollectionState, player: int, puppies_required: int) -> bool: + return state.has_from_list_unique(SINGLE_PUPPIES, player, puppies_required) + +def has_torn_pages(state: CollectionState, player: int, pages_required: int) -> bool: + return state.count_from_list_unique(TORN_PAGES, player) >= pages_required + +def has_all_arts(state: CollectionState, player: int) -> bool: + return state.has_all({"Fire Arts", "Blizzard Arts", "Thunder Arts", "Cure Arts", "Gravity Arts", "Stop Arts", "Aero Arts"}, player) + +def has_all_summons(state: CollectionState, player: int) -> bool: + return state.has_all({"Simba", "Bambi", "Genie", "Dumbo", "Mushu", "Tinker Bell"}, player) + +def has_all_magic_lvx(state: CollectionState, player: int, level) -> bool: + return state.has_all_counts({ + "Progressive Fire": level, + "Progressive Blizzard": level, + "Progressive Thunder": level, + "Progressive Cure": level, + "Progressive Gravity": level, + "Progressive Aero": level, + "Progressive Stop": level}, player) + +def has_offensive_magic(state: CollectionState, player: int) -> bool: + return state.has_any({"Progressive Fire", "Progressive Blizzard", "Progressive Thunder", "Progressive Gravity", "Progressive Stop"}, player) + +def has_reports(state: CollectionState, player: int, eotw_required_reports: int) -> bool: + return state.has_group_unique("Reports", player, eotw_required_reports) + +def has_final_rest_door(state: CollectionState, player: int, final_rest_door_requirement: str, final_rest_door_required_reports: int, keyblades_unlock_chests: bool, puppies_choice: str): + if final_rest_door_requirement == "reports": + return state.has_group_unique("Reports", player, final_rest_door_required_reports) + if final_rest_door_requirement == "puppies": + if puppies_choice == "individual": + return has_puppies_individual(state, player, 99) + if puppies_choice == "triplets": + return has_puppies_triplets(state, player, 99) + return has_puppies_all(state, player, 99) + if final_rest_door_requirement == "postcards": + return state.has("Postcard", player, 10) + if final_rest_door_requirement == "superbosses": + return ( + state.has_all({"Olympus Coliseum", "Neverland", "Agrabah", "Hollow Bastion", "Green Trinity", "Phil Cup", "Pegasus Cup", "Hercules Cup", "Entry Pass"}, player) + and has_emblems(state, player, keyblades_unlock_chests) + and has_all_magic_lvx(state, player, 2) + and has_defensive_tools(state, player) + and has_x_worlds(state, player, 7, keyblades_unlock_chests) + ) + +def has_defensive_tools(state: CollectionState, player: int) -> bool: + return ( + state.has_all_counts({"Progressive Cure": 2, "Leaf Bracer": 1, "Dodge Roll": 1}, player) + and state.has_any_count({"Second Chance": 1, "MP Rage": 1, "Progressive Aero": 2}, player) + ) + +def can_dumbo_skip(state: CollectionState, player: int) -> bool: + return ( + state.has("Dumbo", player) + and state.has_group("Magic", player) + ) + +def has_oogie_manor(state: CollectionState, player: int, advanced_logic: bool) -> bool: + return ( + state.has("Progressive Fire", player) + or (advanced_logic and state.has("High Jump", player, 2)) + or (advanced_logic and state.has("High Jump", player) and state.has("Progressive Glide", player)) + ) + +def set_rules(kh1world): + multiworld = kh1world.multiworld + player = kh1world.player + options = kh1world.options + eotw_required_reports = kh1world.determine_reports_required_to_open_end_of_the_world() + final_rest_door_required_reports = kh1world.determine_reports_required_to_open_final_rest_door() + final_rest_door_requirement = kh1world.options.final_rest_door.current_key + + has_puppies = has_puppies_individual + if kh1world.options.puppies == "triplets": + has_puppies = has_puppies_triplets + elif kh1world.options.puppies == "full": + has_puppies = has_puppies_all + + add_rule(kh1world.get_location("Traverse Town 1st District Candle Puzzle Chest"), + lambda state: state.has("Progressive Blizzard", player)) + add_rule(kh1world.get_location("Traverse Town Mystical House Yellow Trinity Chest"), + lambda state: ( + state.has("Progressive Fire", player) + and + ( + state.has("Yellow Trinity", player) + or (options.advanced_logic and state.has("High Jump", player)) + or state.has("High Jump", player, 2) + ) + )) + add_rule(kh1world.get_location("Traverse Town Secret Waterway White Trinity Chest"), + lambda state: state.has("White Trinity", player)) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Chest"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Item Workshop Right Chest"), + lambda state: ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + )) + add_rule(kh1world.get_location("Traverse Town 1st District Blue Trinity Balcony Chest"), + lambda state: ( + (state.has("Blue Trinity", player) and state.has("Progressive Glide", player)) + or (options.advanced_logic and state.has("Progressive Glide", player)) + )) + add_rule(kh1world.get_location("Traverse Town Mystical House Glide Chest"), + lambda state: ( + ( + state.has("Progressive Glide", player) + or + ( + options.advanced_logic + and + ( + (state.has("High Jump", player) and state.has("Yellow Trinity", player)) + or state.has("High Jump", player, 2) + ) + and state.has("Combo Master", player) + ) + or + ( + options.advanced_logic + and state.has("Mermaid Kick", player) + ) + ) + and state.has("Progressive Fire", player) + )) + add_rule(kh1world.get_location("Traverse Town Alleyway Behind Crates Chest"), + lambda state: state.has("Red Trinity", player)) + add_rule(kh1world.get_location("Traverse Town Item Workshop Left Chest"), + lambda state: ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + )) + add_rule(kh1world.get_location("Wonderland Rabbit Hole Green Trinity Chest"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Wonderland Rabbit Hole Defeat Heartless 3 Chest"), + lambda state: has_x_worlds(state, player, 5, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Wonderland Bizarre Room Green Trinity Chest"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Left Red Chest"), + lambda state: ( + state.has("Footprints", player) + or state.has("High Jump", player) + or state.has("Progressive Glide", player) + )) + add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Right Blue Chest"), + lambda state: ( + state.has("Footprints", player) + or state.has("High Jump", player) + or state.has("Progressive Glide", player) + )) + add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Right Red Chest"), + lambda state: ( + state.has("Footprints", player) + or state.has("High Jump", player) + or state.has("Progressive Glide", player) + )) + add_rule(kh1world.get_location("Wonderland Lotus Forest Thunder Plant Chest"), + lambda state: ( + state.has_all({ + "Progressive Thunder", + "Footprints"}, player) + )) + add_rule(kh1world.get_location("Wonderland Lotus Forest Through the Painting Thunder Plant Chest"), + lambda state: ( + state.has_all({ + "Progressive Thunder", + "Footprints"}, player) + )) + add_rule(kh1world.get_location("Wonderland Lotus Forest Glide Chest"), + lambda state: ( + state.has("Progressive Glide", player) + or + ( + options.advanced_logic + and (state.has("High Jump", player) or can_dumbo_skip(state, player)) + and state.has("Footprints", player) + ) + )) + add_rule(kh1world.get_location("Wonderland Lotus Forest Corner Chest"), + lambda state: ( + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Wonderland Bizarre Room Lamp Chest"), + lambda state: state.has("Footprints", player)) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest"), + lambda state: ( + state.has("Progressive Glide", player) + or + ( + options.advanced_logic + and state.has_all({ + "High Jump", + "Footprints"}, player) + ) + )) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest"), + lambda state: ( + state.has("Progressive Glide", player) + or + ( + options.advanced_logic + and state.has_all({ + "High Jump", + "Footprints"}, player) + ) + )) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Bear and Clock Puzzle Chest"), + lambda state: ( + + state.has("Footprints", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + or state.has("High Jump", player, 2) + )) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest"), + lambda state: ( + state.has("Progressive Glide", player) + or + ( + state.has("High Jump", player, 3) + and state.has("Footprints", player) + ) + or + ( + options.advanced_logic + and state.has_all({ + "High Jump", + "Footprints", + "Combo Master"}, player) + ) + )) + add_rule(kh1world.get_location("Wonderland Lotus Forest Through the Painting White Trinity Chest"), + lambda state: ( + state.has_all({ + "White Trinity", + "Footprints"}, player) + )) + add_rule(kh1world.get_location("Deep Jungle Hippo's Lagoon Right Chest"), + lambda state: ( + + state.has("High Jump", player) + or state.has("Progressive Glide", player) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Deep Jungle Climbing Trees Blue Trinity Chest"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Deep Jungle Cavern of Hearts White Trinity Chest"), + lambda state: ( + state.has_all({ + "White Trinity", + "Slides"}, player) + )) + add_rule(kh1world.get_location("Deep Jungle Camp Blue Trinity Chest"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern Low Chest"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern Middle Chest"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern High Wall Chest"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern High Middle Chest"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Tree House Suspended Boat Chest"), + lambda state: ( + state.has("Progressive Glide", player) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Agrabah Main Street High Above Palace Gates Entrance Chest"), + lambda state: ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + or (options.advanced_logic and can_dumbo_skip(state, player)) + )) + add_rule(kh1world.get_location("Agrabah Palace Gates High Opposite Palace Chest"), + lambda state: ( + state.has("High Jump", player) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Agrabah Palace Gates High Close to Palace Chest"), + lambda state: ( + ( + state.has_all({ + "High Jump", + "Progressive Glide"}, player) + or + ( + options.advanced_logic + and + ( + state.has("Combo Master", player) + or can_dumbo_skip(state, player) + ) + ) + ) + or state.has("High Jump", player, 3) + or (options.advanced_logic and state.has("Progressive Glide", player)) + )) + add_rule(kh1world.get_location("Agrabah Storage Green Trinity Chest"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance Tall Tower Chest"), + lambda state: ( + state.has("Progressive Glide", player) + or (options.advanced_logic and state.has("Combo Master", player)) + or (options.advanced_logic and can_dumbo_skip(state, player)) + or state.has("High Jump", player, 2) + )) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Bottomless Hall Pillar Chest"), + lambda state: ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Silent Chamber Blue Trinity Chest"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Hidden Room Right Chest"), + lambda state: ( + state.has("Yellow Trinity", player) + or state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + )) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Hidden Room Left Chest"), + lambda state: ( + state.has("Yellow Trinity", player) + or state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + )) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance White Trinity Chest"), + lambda state: state.has("White Trinity", player)) + add_rule(kh1world.get_location("Monstro Chamber 6 Other Platform Chest"), + lambda state: ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Combo Master", player)) + )) + add_rule(kh1world.get_location("Monstro Chamber 6 Platform Near Chamber 5 Entrance Chest"), + lambda state: ( + state.has("High Jump", player) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Monstro Chamber 6 Raised Area Near Chamber 1 Entrance Chest"), + lambda state: ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Combo Master", player)) + )) + add_rule(kh1world.get_location("Halloween Town Moonlight Hill White Trinity Chest"), + lambda state: ( + state.has_all({ + "White Trinity", + "Forget-Me-Not"}, player) + )) + add_rule(kh1world.get_location("Halloween Town Bridge Under Bridge"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + )) + add_rule(kh1world.get_location("Halloween Town Boneyard Tombstone Puzzle Chest"), + lambda state: state.has("Forget-Me-Not", player)) + add_rule(kh1world.get_location("Halloween Town Bridge Right of Gate Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and + ( + state.has("Progressive Glide", player) + or options.advanced_logic + ) + )) + add_rule(kh1world.get_location("Halloween Town Cemetery Behind Grave Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Cemetery By Cat Shape Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Cemetery Between Graves Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Lower Iron Cage Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Upper Iron Cage Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Hollow Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Grounds Red Trinity Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not", + "Red Trinity"}, player) + )) + add_rule(kh1world.get_location("Halloween Town Guillotine Square High Tower Chest"), + lambda state: ( + state.has("High Jump", player) + or (options.advanced_logic and can_dumbo_skip(state, player)) + or (options.advanced_logic and state.has("Progressive Glide", player)) + )) + add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Left Chest"), + lambda state: ( + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and + ( + state.has("Progressive Glide", player) + or (options.advanced_logic and state.has("Combo Master", player)) + or state.has("High Jump", player, 2) + ) + )) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Entrance Steps Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + )) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Inside Entrance Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + )) + add_rule(kh1world.get_location("Halloween Town Bridge Left of Gate Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and + ( + state.has("Progressive Glide", player) + or state.has("High Jump", player) + or options.advanced_logic + ) + )) + add_rule(kh1world.get_location("Halloween Town Cemetery By Striped Grave Chest"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Right Chest"), + lambda state: ( + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and + ( + state.has("Progressive Glide", player) + or (options.advanced_logic and state.has("Combo Master", player)) + or state.has("High Jump", player, 2) + ) + )) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Right Blue Trinity Chest"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Left Blue Trinity Chest"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates White Trinity Chest"), + lambda state: state.has("White Trinity", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Blizzara Chest"), + lambda state: state.has("Progressive Blizzard", player, 2)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Blizzaga Chest"), + lambda state: state.has("Progressive Blizzard", player, 3)) + add_rule(kh1world.get_location("Monstro Mouth High Platform Boat Side Chest"), + lambda state: ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + )) + add_rule(kh1world.get_location("Monstro Mouth High Platform Across from Boat Chest"), + lambda state: ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + )) + add_rule(kh1world.get_location("Monstro Mouth Green Trinity Top of Boat Chest"), + lambda state: ( + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + and state.has("Green Trinity", player) + )) + add_rule(kh1world.get_location("Monstro Chamber 5 Platform Chest"), + lambda state: state.has("High Jump", player)) + add_rule(kh1world.get_location("Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest"), + lambda state: ( + state.has("High Jump", player) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest"), + lambda state: ( + state.has("High Jump", player) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Monstro Chamber 5 Atop Barrel Chest"), + lambda state: ( + state.has("High Jump", player) + or options.advanced_logic + )) + add_rule(kh1world.get_location("Neverland Pirate Ship Deck White Trinity Chest"), + lambda state: ( + state.has_all({ + "White Trinity", + "Green Trinity"}, player) + )) + add_rule(kh1world.get_location("Neverland Pirate Ship Crows Nest Chest"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Right Blue Chest"), + lambda state: state.has("Yellow Trinity", player)) + add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Left Blue Chest"), + lambda state: state.has("Yellow Trinity", player)) + add_rule(kh1world.get_location("Neverland Cabin Chest"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Neverland Hold Flight 1st Chest"), + lambda state: ( + state.has("Green Trinity", player) + or state.has("Progressive Glide", player) + or state.has("High Jump", player, 3) + )) + add_rule(kh1world.get_location("Neverland Clock Tower Chest"), + lambda state: ( + state.has("Green Trinity", player) + and has_all_magic_lvx(state, player, 2) + )) + add_rule(kh1world.get_location("Neverland Hold Flight 2nd Chest"), + lambda state: ( + state.has("Green Trinity", player) + or state.has("Progressive Glide", player) + or state.has("High Jump", player, 3) + )) + add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Green Chest"), + lambda state: state.has("Yellow Trinity", player)) + add_rule(kh1world.get_location("Neverland Captain's Cabin Chest"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Under Water 2nd Chest"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Floating Platform Near Save Chest"), + lambda state: ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + or state.has("Progressive Blizzard", player) + )) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Floating Platform Near Bubble Chest"), + lambda state: ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + or state.has("Progressive Blizzard", player) + )) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls High Platform Chest"), + lambda state: ( + state.has("Progressive Glide", player) + or (state.has("Progressive Blizzard", player) and has_emblems(state, player, options.keyblades_unlock_chests)) + or (options.advanced_logic and state.has("Combo Master", player)) + )) + add_rule(kh1world.get_location("Hollow Bastion Castle Gates Gravity Chest"), + lambda state: ( + state.has("Progressive Gravity", player) + and + ( + has_emblems(state, player, options.keyblades_unlock_chests) + or (options.advanced_logic and state.has("High Jump", player, 2) and state.has("Progressive Glide", player)) + or (options.advanced_logic and can_dumbo_skip(state, player) and state.has("Progressive Glide", player)) + ) + )) + add_rule(kh1world.get_location("Hollow Bastion Castle Gates Freestanding Pillar Chest"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests) + or state.has("High Jump", player, 2) + or (options.advanced_logic and can_dumbo_skip(state, player)) + )) + add_rule(kh1world.get_location("Hollow Bastion Castle Gates High Pillar Chest"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests) + or state.has("High Jump", player, 2) + or (options.advanced_logic and can_dumbo_skip(state, player)) + )) + add_rule(kh1world.get_location("Hollow Bastion Great Crest Lower Chest"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Great Crest After Battle Platform Chest"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion High Tower 2nd Gravity Chest"), + lambda state: ( + state.has("Progressive Gravity", player) + and has_emblems(state, player, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Hollow Bastion High Tower 1st Gravity Chest"), + lambda state: ( + state.has("Progressive Gravity", player) + and has_emblems(state, player, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Hollow Bastion High Tower Above Sliding Blocks Chest"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest"), + lambda state: ( + state.has("Progressive Gravity", player) + and has_emblems(state, player, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Library Node Gravity Chest"), + lambda state: state.has("Progressive Gravity", player)) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Under High Tower Sliding Blocks Chest"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests) + and state.has_all({ + "Progressive Glide", + "Progressive Gravity"}, player) + )) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Outside Library Gravity Chest"), + lambda state: state.has("Progressive Gravity", player)) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest"), + lambda state: ( + state.has("Progressive Gravity", player) + and has_emblems(state, player, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Hollow Bastion Waterway Blizzard on Bubble Chest"), + lambda state: ( + (state.has("Progressive Blizzard", player) and state.has("High Jump", player)) + or state.has("High Jump", player, 3) + )) + add_rule(kh1world.get_location("Hollow Bastion Grand Hall Steps Right Side Chest"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Grand Hall Oblivion Chest"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Grand Hall Left of Gate Chest"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Left of Emblem Door Chest"), + lambda state: ( + state.has("High Jump", player) + or + ( + options.advanced_logic + and can_dumbo_skip(state, player) + and has_emblems(state, player, options.keyblades_unlock_chests) + ) + )) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls White Trinity Chest"), + lambda state: state.has("White Trinity", player)) + add_rule(kh1world.get_location("End of the World Giant Crevasse 5th Chest"), + lambda state: ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + )) + add_rule(kh1world.get_location("End of the World Giant Crevasse 1st Chest"), + lambda state: ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + )) + add_rule(kh1world.get_location("End of the World Giant Crevasse 4th Chest"), + lambda state: ( + ( + options.advanced_logic + and state.has("High Jump", player) + and state.has("Combo Master", player) + ) + or state.has("Progressive Glide", player) + )) + add_rule(kh1world.get_location("End of the World World Terminus Agrabah Chest"), + lambda state: ( + state.has("High Jump", player) + or + ( + options.advanced_logic + and can_dumbo_skip(state, player) + and state.has("Progressive Glide", player) + ) + )) + add_rule(kh1world.get_location("Monstro Chamber 6 White Trinity Chest"), + lambda state: state.has("White Trinity", player)) + add_rule(kh1world.get_location("Traverse Town Kairi Secret Waterway Oathkeeper Event"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests) + and state.has("Hollow Bastion", player) + and has_x_worlds(state, player, 5, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Deep Jungle Defeat Sabor White Fang Event"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Defeat Clayton Cure Event"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Seal Keyhole Jungle King Event"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Seal Keyhole Red Trinity Event"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Olympus Coliseum Defeat Cerberus Inferno Band Event"), + lambda state: state.has("Entry Pass", player)) + add_rule(kh1world.get_location("Olympus Coliseum Cloud Sonic Blade Event"), + lambda state: state.has("Entry Pass", player)) + add_rule(kh1world.get_location("Wonderland Defeat Trickmaster Blizzard Event"), + lambda state: state.has("Footprints", player)) + add_rule(kh1world.get_location("Wonderland Defeat Trickmaster Ifrit's Horn Event"), + lambda state: state.has("Footprints", player)) + add_rule(kh1world.get_location("Monstro Defeat Parasite Cage II Stop Event"), + lambda state: ( + state.has("High Jump", player) + or + ( + options.advanced_logic + and state.has("Progressive Glide", player) + ) + )) + add_rule(kh1world.get_location("Halloween Town Defeat Oogie Boogie Holy Circlet Event"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Defeat Oogie's Manor Gravity Event"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Halloween Town Seal Keyhole Pumpkinhead Event"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not"}, player) + and has_oogie_manor(state, player, options.advanced_logic) + )) + add_rule(kh1world.get_location("Neverland Defeat Anti Sora Raven's Claw Event"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Neverland Encounter Hook Cure Event"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Neverland Seal Keyhole Fairy Harp Event"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Neverland Seal Keyhole Tinker Bell Event"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Neverland Seal Keyhole Glide Event"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Neverland Defeat Captain Hook Ars Arcanum Event"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Hollow Bastion Defeat Maleficent Donald Cheer Event"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Defeat Dragon Maleficent Fireglow Event"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Defeat Riku II Ragnarok Event"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Defeat Behemoth Omega Arts Event"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Speak to Princesses Fire Event"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 01 Event"), + lambda state: state.has("Postcard", player)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 02 Event"), + lambda state: state.has("Postcard", player, 2)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 03 Event"), + lambda state: state.has("Postcard", player, 3)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 04 Event"), + lambda state: state.has("Postcard", player, 4)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 05 Event"), + lambda state: state.has("Postcard", player, 5)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 06 Event"), + lambda state: state.has("Postcard", player, 6)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 07 Event"), + lambda state: state.has("Postcard", player, 7)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 08 Event"), + lambda state: state.has("Postcard", player, 8)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 09 Event"), + lambda state: state.has("Postcard", player, 9)) + add_rule(kh1world.get_location("Traverse Town Mail Postcard 10 Event"), + lambda state: state.has("Postcard", player, 10)) + add_rule(kh1world.get_location("Traverse Town Defeat Opposite Armor Aero Event"), + lambda state: state.has("Red Trinity", player)) + add_rule(kh1world.get_location("Hollow Bastion Speak with Aerith Ansem's Report 2"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Speak with Aerith Ansem's Report 4"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Defeat Maleficent Ansem's Report 5"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Speak with Aerith Ansem's Report 6"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Halloween Town Defeat Oogie Boogie Ansem's Report 7"), + lambda state: ( + state.has_all({ + "Jack-In-The-Box", + "Forget-Me-Not", + "Progressive Fire"}, player) + )) + add_rule(kh1world.get_location("Neverland Defeat Hook Ansem's Report 9"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Hollow Bastion Speak with Aerith Ansem's Report 10"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 1"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 2"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 3"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 4"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 5"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto All Summons Reward"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_all_summons(state, player) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Talk to Pinocchio"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Magician's Study Obtained All Arts Items"), + lambda state: ( + has_all_magic_lvx(state, player, 1) + and has_all_arts(state, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Traverse Town Magician's Study Obtained All LV1 Magic"), + lambda state: has_all_magic_lvx(state, player, 1)) + add_rule(kh1world.get_location("Traverse Town Magician's Study Obtained All LV3 Magic"), + lambda state: has_all_magic_lvx(state, player, 3)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 10 Puppies"), + lambda state: has_puppies(state, player, 10)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 20 Puppies"), + lambda state: has_puppies(state, player, 20)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 30 Puppies"), + lambda state: has_puppies(state, player, 30)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 40 Puppies"), + lambda state: has_puppies(state, player, 40)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 50 Puppies Reward 1"), + lambda state: has_puppies(state, player, 50)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 50 Puppies Reward 2"), + lambda state: has_puppies(state, player, 50)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 60 Puppies"), + lambda state: has_puppies(state, player, 60)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 70 Puppies"), + lambda state: has_puppies(state, player, 70)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 80 Puppies"), + lambda state: has_puppies(state, player, 80)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 90 Puppies"), + lambda state: has_puppies(state, player, 90)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 99 Puppies Reward 1"), + lambda state: has_puppies(state, player, 99)) + add_rule(kh1world.get_location("Traverse Town Piano Room Return 99 Puppies Reward 2"), + lambda state: has_puppies(state, player, 99)) + add_rule(kh1world.get_location("Neverland Hold Aero Chest"), + lambda state: state.has("Yellow Trinity", player)) + add_rule(kh1world.get_location("Deep Jungle Camp Hi-Potion Experiment"), + lambda state: state.has("Progressive Fire", player)) + add_rule(kh1world.get_location("Deep Jungle Camp Ether Experiment"), + lambda state: state.has("Progressive Blizzard", player)) + add_rule(kh1world.get_location("Deep Jungle Camp Replication Experiment"), + lambda state: state.has("Progressive Blizzard", player)) + add_rule(kh1world.get_location("Deep Jungle Cliff Save Gorillas"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Tree House Save Gorillas"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Camp Save Gorillas"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Bamboo Thicket Save Gorillas"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Climbing Trees Save Gorillas"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 10 Fruits"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 20 Fruits"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 30 Fruits"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 40 Fruits"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 50 Fruits"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Wonderland Bizarre Room Read Book"), + lambda state: state.has("Footprints", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Green Trinity"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Hero's License Event"), + lambda state: state.has("Entry Pass", player)) + add_rule(kh1world.get_location("Deep Jungle Cavern of Hearts Navi-G Piece Event"), + lambda state: state.has("Slides", player)) + add_rule(kh1world.get_location("Wonderland Bizarre Room Navi-G Piece Event"), + lambda state: state.has("Footprints", player)) + add_rule(kh1world.get_location("Traverse Town Synth Log"), + lambda state: ( + state.has("Empty Bottle", player, 6) + and + ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + ) + )) + add_rule(kh1world.get_location("Traverse Town Synth Cloth"), + lambda state: ( + state.has("Empty Bottle", player, 6) + and + ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + ) + )) + add_rule(kh1world.get_location("Traverse Town Synth Rope"), + lambda state: ( + state.has("Empty Bottle", player, 6) + and + ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + ) + )) + add_rule(kh1world.get_location("Traverse Town Synth Seagull Egg"), + lambda state: ( + state.has("Empty Bottle", player, 6) + and + ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + ) + )) + add_rule(kh1world.get_location("Traverse Town Synth Fish"), + lambda state: ( + state.has("Empty Bottle", player, 6) + and + ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + ) + )) + add_rule(kh1world.get_location("Traverse Town Synth Mushroom"), + lambda state: ( + state.has("Empty Bottle", player, 6) + and + ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + ) + )) + add_rule(kh1world.get_location("Traverse Town Gizmo Shop Postcard 1"), + lambda state: state.has("Progressive Thunder", player)) + add_rule(kh1world.get_location("Traverse Town Gizmo Shop Postcard 2"), + lambda state: state.has("Progressive Thunder", player)) + add_rule(kh1world.get_location("Traverse Town Item Workshop Postcard"), + lambda state: ( + state.has("Green Trinity", player) + or state.has("High Jump", player, 3) + )) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Postcard"), + lambda state: ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (options.advanced_logic and state.has("Progressive Glide", player)) + ) + and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Flame)"), + lambda state: ( + ( + state.has("Theon Vol. 6", player) + or state.has("High Jump", player, 3) + or has_emblems(state, player, options.keyblades_unlock_chests) + ) + and state.has("Progressive Fire", player) + and + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + or state.has("Progressive Thunder", player) + or options.advanced_logic + ) + )) + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Chest)"), + lambda state: ( + state.has("Theon Vol. 6", player) + or state.has("High Jump", player, 3) + or has_emblems(state, player, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Statue)"), + lambda state: ( + ( + state.has("Theon Vol. 6", player) + or state.has("High Jump", player, 3) + or has_emblems(state, player, options.keyblades_unlock_chests) + ) + and state.has("Red Trinity", player) + )) + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Fountain)"), + lambda state: ( + state.has("Theon Vol. 6", player) + or state.has("High Jump", player, 3) + or has_emblems(state, player, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Hollow Bastion Library Speak to Belle Divine Rose"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Hollow Bastion Library Speak to Aerith Cure"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + if options.hundred_acre_wood: + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Left Cliff Chest"), + lambda state: ( + has_torn_pages(state, player, 4) + and + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + )) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Right Tree Alcove Chest"), + lambda state: ( + has_torn_pages(state, player, 4) + and + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + )) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Under Giant Pot Chest"), + lambda state: has_torn_pages(state, player, 4)) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 1"), + lambda state: has_torn_pages(state, player, 4)) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 2"), + lambda state: ( + has_torn_pages(state, player, 4) + and + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + )) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 3"), + lambda state: ( + has_torn_pages(state, player, 4) + and + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + )) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 4"), + lambda state: ( + has_torn_pages(state, player, 4) + and + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + )) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 5"), + lambda state: ( + has_torn_pages(state, player, 4) + and + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + )) + add_rule(kh1world.get_location("100 Acre Wood Pooh's House Owl Cheer"), + lambda state: has_torn_pages(state, player, 5)) + add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 1"), + lambda state: has_torn_pages(state, player, 1)) + add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 2"), + lambda state: has_torn_pages(state, player, 2)) + add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 3"), + lambda state: has_torn_pages(state, player, 3)) + add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 4"), + lambda state: has_torn_pages(state, player, 4)) + add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 5"), + lambda state: has_torn_pages(state, player, 5)) + add_rule(kh1world.get_location("100 Acre Wood Pooh's House Start Fire"), + lambda state: has_torn_pages(state, player, 3)) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Break Log"), + lambda state: has_torn_pages(state, player, 4)) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Fall Through Top of Tree Next to Pooh"), + lambda state: ( + has_torn_pages(state, player, 4) + and + ( + state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + )) + if options.atlantica: + add_rule(kh1world.get_location("Atlantica Ursula's Lair Use Fire on Urchin Chest"), + lambda state: ( + state.has_all({ + "Progressive Fire", + "Crystal Trident"}, player) + )) + add_rule(kh1world.get_location("Atlantica Triton's Palace White Trinity Chest"), + lambda state: state.has("White Trinity", player)) + add_rule(kh1world.get_location("Atlantica Defeat Ursula I Mermaid Kick Event"), + lambda state: ( + has_offensive_magic(state, player) + and state.has("Crystal Trident", player) + )) + add_rule(kh1world.get_location("Atlantica Defeat Ursula II Thunder Event"), + lambda state: ( + state.has("Mermaid Kick", player) + and has_offensive_magic(state, player) + and state.has("Crystal Trident", player) + )) + add_rule(kh1world.get_location("Atlantica Seal Keyhole Crabclaw Event"), + lambda state: ( + state.has("Mermaid Kick", player) + and has_offensive_magic(state, player) + and state.has("Crystal Trident", player) + )) + add_rule(kh1world.get_location("Atlantica Undersea Gorge Blizzard Clam"), + lambda state: state.has("Progressive Blizzard", player)) + add_rule(kh1world.get_location("Atlantica Undersea Valley Fire Clam"), + lambda state: state.has("Progressive Fire", player)) + add_rule(kh1world.get_location("Atlantica Triton's Palace Thunder Clam"), + lambda state: state.has("Progressive Thunder", player)) + add_rule(kh1world.get_location("Atlantica Cavern Nook Clam"), + lambda state: state.has("Crystal Trident", player)) + add_rule(kh1world.get_location("Atlantica Defeat Ursula II Ansem's Report 3"), + lambda state: ( + state.has_all({ + "Mermaid Kick", + "Crystal Trident"}, player) + and has_offensive_magic(state, player) + )) + if options.cups: + add_rule(kh1world.get_location("Olympus Coliseum Defeat Hades Ansem's Report 8"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Complete Phil Cup"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Entry Pass"}, player) + )) + add_rule(kh1world.get_location("Complete Phil Cup Solo"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Entry Pass"}, player) + )) + add_rule(kh1world.get_location("Complete Phil Cup Time Trial"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Entry Pass"}, player) + )) + add_rule(kh1world.get_location("Complete Pegasus Cup"), + lambda state: ( + state.has_all({ + "Pegasus Cup", + "Entry Pass"}, player) + )) + add_rule(kh1world.get_location("Complete Pegasus Cup Solo"), + lambda state: ( + state.has_all({ + "Pegasus Cup", + "Entry Pass"}, player) + )) + add_rule(kh1world.get_location("Complete Pegasus Cup Time Trial"), + lambda state: ( + state.has_all({ + "Pegasus Cup", + "Entry Pass"}, player) + )) + add_rule(kh1world.get_location("Complete Hercules Cup"), + lambda state: ( + state.has_all({ + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Complete Hercules Cup Solo"), + lambda state: ( + state.has_all({ + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Complete Hercules Cup Time Trial"), + lambda state: ( + state.has_all({ + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Complete Hades Cup"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Complete Hades Cup Solo"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Complete Hades Cup Time Trial"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Cloud and Leon Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Yuffie Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Cerberus Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Behemoth Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Hades Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Hercules Cup Defeat Cloud Event"), + lambda state: ( + state.has_all({ + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Hercules Cup Yellow Trinity Event"), + lambda state: ( + state.has_all({ + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Olympus Coliseum Defeat Ice Titan Diamond Dust Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass", + "Guard"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Olympus Coliseum Gates Purple Jar After Defeating Hades"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Olympus Coliseum Olympia Chest"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + )) + if options.super_bosses: + add_rule(kh1world.get_location("Neverland Defeat Phantom Stop Event"), + lambda state: ( + state.has("Green Trinity", player) + and has_all_magic_lvx(state, player, 2) + and has_defensive_tools(state, player) + and has_emblems(state, player, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Agrabah Defeat Kurt Zisa Ansem's Report 11"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Agrabah Defeat Kurt Zisa Zantetsuken Event"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests) and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) and has_defensive_tools(state, player) + )) + if options.super_bosses or options.goal.current_key == "sephiroth": + add_rule(kh1world.get_location("Olympus Coliseum Defeat Sephiroth Ansem's Report 12"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Olympus Coliseum Defeat Sephiroth One-Winged Angel Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup", + "Entry Pass"}, player) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + if options.super_bosses or options.goal.current_key == "unknown": + add_rule(kh1world.get_location("Hollow Bastion Defeat Unknown Ansem's Report 13"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + add_rule(kh1world.get_location("Hollow Bastion Defeat Unknown EXP Necklace Event"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests) and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_defensive_tools(state, player) + )) + for i in range(options.level_checks): + add_rule(kh1world.get_location("Level " + str(i+1).rjust(3,'0')), + lambda state, level_num=i: ( + has_x_worlds(state, player, min(((level_num//10)*2), 8), options.keyblades_unlock_chests) + )) + if options.goal.current_key == "final_ansem": + add_rule(kh1world.get_location("Final Ansem"), + lambda state: ( + has_final_rest_door(state, player, final_rest_door_requirement, final_rest_door_required_reports, options.keyblades_unlock_chests, options.puppies) + )) + if options.keyblades_unlock_chests: + add_rule(kh1world.get_location("Traverse Town 1st District Candle Puzzle Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town 1st District Accessory Shop Roof Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town 2nd District Boots and Shoes Awning Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town 2nd District Rooftop Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town 2nd District Gizmo Shop Facade Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Alleyway Balcony Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Alleyway Blue Room Awning Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Alleyway Corner Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Green Room Clock Puzzle Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Green Room Table Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Red Room Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Mystical House Yellow Trinity Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Accessory Shop Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Secret Waterway White Trinity Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Item Workshop Right Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town 1st District Blue Trinity Balcony Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Mystical House Glide Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Alleyway Behind Crates Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Item Workshop Left Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Traverse Town Secret Waterway Near Stairs Chest"), + lambda state: state.has("Lionheart", player)) + add_rule(kh1world.get_location("Wonderland Rabbit Hole Green Trinity Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Rabbit Hole Defeat Heartless 1 Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Rabbit Hole Defeat Heartless 2 Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Rabbit Hole Defeat Heartless 3 Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Bizarre Room Green Trinity Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Left Red Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Right Blue Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Right Red Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Thunder Plant Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Through the Painting Thunder Plant Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Glide Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Nut Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Corner Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Bizarre Room Lamp Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Bear and Clock Puzzle Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Through the Painting White Trinity Chest"), + lambda state: state.has("Lady Luck", player)) + add_rule(kh1world.get_location("Deep Jungle Tree House Beneath Tree House Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Tree House Rooftop Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Hippo's Lagoon Center Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Hippo's Lagoon Left Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Hippo's Lagoon Right Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Vines Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Vines 2 Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Climbing Trees Blue Trinity Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Tunnel Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Cavern of Hearts White Trinity Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Camp Blue Trinity Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Tent Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern Low Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern Middle Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern High Wall Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern High Middle Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Cliff Right Cliff Left Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Cliff Right Cliff Right Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Deep Jungle Tree House Suspended Boat Chest"), + lambda state: state.has("Jungle King", player)) + add_rule(kh1world.get_location("Agrabah Plaza By Storage Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Plaza Raised Terrace Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Plaza Top Corner Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Alley Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Bazaar Across Windows Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Bazaar High Corner Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Main Street Right Palace Entrance Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Main Street High Above Alley Entrance Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Main Street High Above Palace Gates Entrance Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Palace Gates Low Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Palace Gates High Opposite Palace Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Palace Gates High Close to Palace Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Storage Green Trinity Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Storage Behind Barrel Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance Left Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance Tall Tower Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Hall High Left Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Hall Near Bottomless Hall Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Bottomless Hall Raised Platform Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Bottomless Hall Pillar Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Bottomless Hall Across Chasm Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Across Platforms Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Small Treasure Pile Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Large Treasure Pile Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Above Fire Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Relic Chamber Jump from Stairs Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Relic Chamber Stairs Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Abu Gem Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Across from Relic Chamber Entrance Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Bridge Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Near Save Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Silent Chamber Blue Trinity Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Hidden Room Right Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Hidden Room Left Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Aladdin's House Main Street Entrance Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Aladdin's House Plaza Entrance Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance White Trinity Chest"), + lambda state: state.has("Three Wishes", player)) + add_rule(kh1world.get_location("Monstro Chamber 6 Other Platform Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 6 Platform Near Chamber 5 Entrance Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 6 Raised Area Near Chamber 1 Entrance Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 6 Low Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Halloween Town Moonlight Hill White Trinity Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Bridge Under Bridge"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Boneyard Tombstone Puzzle Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Bridge Right of Gate Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Cemetery Behind Grave Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Cemetery By Cat Shape Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Cemetery Between Graves Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Lower Iron Cage Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Upper Iron Cage Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Hollow Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Grounds Red Trinity Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Guillotine Square High Tower Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Left Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Entrance Steps Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Oogie's Manor Inside Entrance Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Bridge Left of Gate Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Cemetery By Striped Grave Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Guillotine Square Under Jack's House Stairs Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Right Chest"), + lambda state: state.has("Pumpkinhead", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Left Behind Columns Chest"), + lambda state: state.has("Olympia", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Right Blue Trinity Chest"), + lambda state: state.has("Olympia", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Left Blue Trinity Chest"), + lambda state: state.has("Olympia", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates White Trinity Chest"), + lambda state: state.has("Olympia", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Blizzara Chest"), + lambda state: state.has("Olympia", player)) + add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Blizzaga Chest"), + lambda state: state.has("Olympia", player)) + add_rule(kh1world.get_location("Monstro Mouth Boat Deck Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Mouth High Platform Boat Side Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Mouth High Platform Across from Boat Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Mouth Near Ship Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Mouth Green Trinity Top of Boat Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 2 Ground Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 2 Platform Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 5 Platform Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 3 Ground Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 3 Near Chamber 6 Entrance Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Mouth High Platform Near Teeth Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 5 Atop Barrel Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 5 Low 2nd Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Monstro Chamber 5 Low 1st Chest"), + lambda state: state.has("Wishing Star", player)) + add_rule(kh1world.get_location("Neverland Pirate Ship Deck White Trinity Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Pirate Ship Crows Nest Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Right Blue Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Left Blue Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Galley Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Cabin Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Hold Flight 1st Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Clock Tower Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Hold Flight 2nd Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Green Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Neverland Captain's Cabin Chest"), + lambda state: state.has("Fairy Harp", player)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Water's Surface Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Under Water 1st Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Under Water 2nd Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Floating Platform Near Save Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Floating Platform Near Bubble Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls High Platform Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Castle Gates Gravity Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Castle Gates Freestanding Pillar Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Castle Gates High Pillar Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Great Crest Lower Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Great Crest After Battle Platform Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion High Tower 2nd Gravity Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion High Tower 1st Gravity Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion High Tower Above Sliding Blocks Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Library Top of Bookshelf Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Library Node Gravity Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Under High Tower Sliding Blocks Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Outside Library Gravity Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Base Level Bubble Under the Wall Platform Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Base Level Platform Near Entrance Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Base Level Near Crystal Switch Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Waterway Near Save Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Waterway Blizzard on Bubble Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Waterway Unlock Passage from Base Level Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Dungeon By Candles Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Dungeon Corner Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Grand Hall Steps Right Side Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Grand Hall Oblivion Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Grand Hall Left of Gate Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Left of Emblem Door Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls White Trinity Chest"), + lambda state: state.has("Divine Rose", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 1st Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 2nd Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 3rd Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 4th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 5th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 6th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 10th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 9th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 8th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Dimension 7th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Giant Crevasse 3rd Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Giant Crevasse 5th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Giant Crevasse 1st Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Giant Crevasse 4th Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Giant Crevasse 2nd Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World World Terminus Traverse Town Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World World Terminus Wonderland Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World World Terminus Olympus Coliseum Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World World Terminus Deep Jungle Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World World Terminus Agrabah Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World World Terminus Halloween Town Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World World Terminus Neverland Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World World Terminus 100 Acre Wood Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("End of the World Final Rest Chest"), + lambda state: state.has("Oblivion", player)) + add_rule(kh1world.get_location("Monstro Chamber 6 White Trinity Chest"), + lambda state: state.has("Oblivion", player)) + if options.hundred_acre_wood: + add_rule(kh1world.get_location("100 Acre Wood Meadow Inside Log Chest"), + lambda state: state.has("Oathkeeper", player)) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Left Cliff Chest"), + lambda state: state.has("Oathkeeper", player)) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Right Tree Alcove Chest"), + lambda state: state.has("Oathkeeper", player)) + add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Under Giant Pot Chest"), + lambda state: state.has("Oathkeeper", player)) + + + add_rule(kh1world.get_entrance("Wonderland"), + lambda state: state.has("Wonderland", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + add_rule(kh1world.get_entrance("Olympus Coliseum"), + lambda state: state.has("Olympus Coliseum", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + add_rule(kh1world.get_entrance("Deep Jungle"), + lambda state: state.has("Deep Jungle", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + add_rule(kh1world.get_entrance("Agrabah"), + lambda state: state.has("Agrabah", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + add_rule(kh1world.get_entrance("Monstro"), + lambda state: state.has("Monstro", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + if options.atlantica: + add_rule(kh1world.get_entrance("Atlantica"), + lambda state: state.has("Atlantica", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + add_rule(kh1world.get_entrance("Halloween Town"), + lambda state: state.has("Halloween Town", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + add_rule(kh1world.get_entrance("Neverland"), + lambda state: state.has("Neverland", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests)) + add_rule(kh1world.get_entrance("Hollow Bastion"), + lambda state: state.has("Hollow Bastion", player) and has_x_worlds(state, player, 5, options.keyblades_unlock_chests)) + add_rule(kh1world.get_entrance("End of the World"), + lambda state: has_x_worlds(state, player, 7, options.keyblades_unlock_chests) and (has_reports(state, player, eotw_required_reports) or state.has("End of the World", player))) + add_rule(kh1world.get_entrance("100 Acre Wood"), + lambda state: state.has("Progressive Fire", player)) + + multiworld.completion_condition[player] = lambda state: state.has("Victory", player) diff --git a/worlds/kh1/__init__.py b/worlds/kh1/__init__.py new file mode 100644 index 000000000000..63b457556894 --- /dev/null +++ b/worlds/kh1/__init__.py @@ -0,0 +1,282 @@ +import logging +from typing import List + +from BaseClasses import Tutorial +from worlds.AutoWorld import WebWorld, World +from .Items import KH1Item, KH1ItemData, event_item_table, get_items_by_category, item_table, item_name_groups +from .Locations import KH1Location, location_table, get_locations_by_category, location_name_groups +from .Options import KH1Options, kh1_option_groups +from .Regions import create_regions +from .Rules import set_rules +from .Presets import kh1_option_presets +from worlds.LauncherComponents import Component, components, Type, launch_subprocess + + +def launch_client(): + from .Client import launch + launch_subprocess(launch, name="KH1 Client") + + +components.append(Component("KH1 Client", "KH1Client", func=launch_client, component_type=Type.CLIENT)) + + +class KH1Web(WebWorld): + theme = "ocean" + tutorials = [Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Kingdom Hearts Randomizer software on your computer." + "This guide covers single-player, multiworld, and related software.", + "English", + "kh1_en.md", + "kh1/en", + ["Gicu"] + )] + option_groups = kh1_option_groups + options_presets = kh1_option_presets + + +class KH1World(World): + """ + Kingdom Hearts is an action RPG following Sora on his journey + through many worlds to find Riku and Kairi. + """ + game = "Kingdom Hearts" + options_dataclass = KH1Options + options: KH1Options + topology_present = True + web = KH1Web() + + item_name_to_id = {name: data.code for name, data in item_table.items()} + location_name_to_id = {name: data.code for name, data in location_table.items()} + item_name_groups = item_name_groups + location_name_groups = location_name_groups + fillers = {} + fillers.update(get_items_by_category("Item")) + fillers.update(get_items_by_category("Camping")) + fillers.update(get_items_by_category("Stat Ups")) + + def create_items(self): + self.place_predetermined_items() + # Handle starting worlds + starting_worlds = [] + if self.options.starting_worlds > 0: + possible_starting_worlds = ["Wonderland", "Olympus Coliseum", "Deep Jungle", "Agrabah", "Monstro", "Halloween Town", "Neverland", "Hollow Bastion"] + if self.options.atlantica: + possible_starting_worlds.append("Atlantica") + if self.options.end_of_the_world_unlock == "item": + possible_starting_worlds.append("End of the World") + starting_worlds = self.random.sample(possible_starting_worlds, min(self.options.starting_worlds.value, len(possible_starting_worlds))) + for starting_world in starting_worlds: + self.multiworld.push_precollected(self.create_item(starting_world)) + + item_pool: List[KH1Item] = [] + possible_level_up_item_pool = [] + level_up_item_pool = [] + + # Calculate Level Up Items + # Fill pool with mandatory items + for _ in range(self.options.item_slot_increase): + level_up_item_pool.append("Item Slot Increase") + for _ in range(self.options.accessory_slot_increase): + level_up_item_pool.append("Accessory Slot Increase") + + # Create other pool + for _ in range(self.options.strength_increase): + possible_level_up_item_pool.append("Strength Increase") + for _ in range(self.options.defense_increase): + possible_level_up_item_pool.append("Defense Increase") + for _ in range(self.options.hp_increase): + possible_level_up_item_pool.append("Max HP Increase") + for _ in range(self.options.mp_increase): + possible_level_up_item_pool.append("Max MP Increase") + for _ in range(self.options.ap_increase): + possible_level_up_item_pool.append("Max AP Increase") + + # Fill remaining pool with items from other pool + self.random.shuffle(possible_level_up_item_pool) + level_up_item_pool = level_up_item_pool + possible_level_up_item_pool[:(100 - len(level_up_item_pool))] + + level_up_locations = list(get_locations_by_category("Levels").keys()) + self.random.shuffle(level_up_item_pool) + current_level_for_placing_stats = self.options.force_stats_on_levels.value + while len(level_up_item_pool) > 0 and current_level_for_placing_stats <= self.options.level_checks: + self.get_location(level_up_locations[current_level_for_placing_stats - 1]).place_locked_item(self.create_item(level_up_item_pool.pop())) + current_level_for_placing_stats += 1 + + # Calculate prefilled locations and items + prefilled_items = [] + if self.options.vanilla_emblem_pieces: + prefilled_items = prefilled_items + ["Emblem Piece (Flame)", "Emblem Piece (Chest)", "Emblem Piece (Fountain)", "Emblem Piece (Statue)"] + + total_locations = len(self.multiworld.get_unfilled_locations(self.player)) + + non_filler_item_categories = ["Key", "Magic", "Worlds", "Trinities", "Cups", "Summons", "Abilities", "Shared Abilities", "Keyblades", "Accessory", "Weapons", "Puppies"] + if self.options.hundred_acre_wood: + non_filler_item_categories.append("Torn Pages") + for name, data in item_table.items(): + quantity = data.max_quantity + if data.category not in non_filler_item_categories: + continue + if name in starting_worlds: + continue + if data.category == "Puppies": + if self.options.puppies == "triplets" and "-" in name: + item_pool += [self.create_item(name) for _ in range(quantity)] + if self.options.puppies == "individual" and "Puppy" in name: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + if self.options.puppies == "full" and name == "All Puppies": + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "Atlantica": + if self.options.atlantica: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "Mermaid Kick": + if self.options.atlantica: + if self.options.extra_shared_abilities: + item_pool += [self.create_item(name) for _ in range(0, 2)] + else: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "Crystal Trident": + if self.options.atlantica: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "High Jump": + if self.options.extra_shared_abilities: + item_pool += [self.create_item(name) for _ in range(0, 3)] + else: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "Progressive Glide": + if self.options.extra_shared_abilities: + item_pool += [self.create_item(name) for _ in range(0, 4)] + else: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "End of the World": + if self.options.end_of_the_world_unlock.current_key == "item": + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "EXP Zero": + if self.options.exp_zero_in_pool: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name not in prefilled_items: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + + for i in range(self.determine_reports_in_pool()): + item_pool += [self.create_item("Ansem's Report " + str(i+1))] + + while len(item_pool) < total_locations and len(level_up_item_pool) > 0: + item_pool += [self.create_item(level_up_item_pool.pop())] + + # Fill any empty locations with filler items. + while len(item_pool) < total_locations: + item_pool.append(self.create_item(self.get_filler_item_name())) + + self.multiworld.itempool += item_pool + + def place_predetermined_items(self) -> None: + goal_dict = { + "sephiroth": "Olympus Coliseum Defeat Sephiroth Ansem's Report 12", + "unknown": "Hollow Bastion Defeat Unknown Ansem's Report 13", + "postcards": "Traverse Town Mail Postcard 10 Event", + "final_ansem": "Final Ansem", + "puppies": "Traverse Town Piano Room Return 99 Puppies Reward 2", + "final_rest": "End of the World Final Rest Chest" + } + self.get_location(goal_dict[self.options.goal.current_key]).place_locked_item(self.create_item("Victory")) + if self.options.vanilla_emblem_pieces: + self.get_location("Hollow Bastion Entrance Hall Emblem Piece (Flame)").place_locked_item(self.create_item("Emblem Piece (Flame)")) + self.get_location("Hollow Bastion Entrance Hall Emblem Piece (Statue)").place_locked_item(self.create_item("Emblem Piece (Statue)")) + self.get_location("Hollow Bastion Entrance Hall Emblem Piece (Fountain)").place_locked_item(self.create_item("Emblem Piece (Fountain)")) + self.get_location("Hollow Bastion Entrance Hall Emblem Piece (Chest)").place_locked_item(self.create_item("Emblem Piece (Chest)")) + + def get_filler_item_name(self) -> str: + weights = [data.weight for data in self.fillers.values()] + return self.random.choices([filler for filler in self.fillers.keys()], weights)[0] + + def fill_slot_data(self) -> dict: + slot_data = {"xpmult": int(self.options.exp_multiplier)/16, + "required_reports_eotw": self.determine_reports_required_to_open_end_of_the_world(), + "required_reports_door": self.determine_reports_required_to_open_final_rest_door(), + "door": self.options.final_rest_door.current_key, + "seed": self.multiworld.seed_name, + "advanced_logic": bool(self.options.advanced_logic), + "hundred_acre_wood": bool(self.options.hundred_acre_wood), + "atlantica": bool(self.options.atlantica), + "goal": str(self.options.goal.current_key)} + if self.options.randomize_keyblade_stats: + min_str_bonus = min(self.options.keyblade_min_str.value, self.options.keyblade_max_str.value) + max_str_bonus = max(self.options.keyblade_min_str.value, self.options.keyblade_max_str.value) + self.options.keyblade_min_str.value = min_str_bonus + self.options.keyblade_max_str.value = max_str_bonus + min_mp_bonus = min(self.options.keyblade_min_mp.value, self.options.keyblade_max_mp.value) + max_mp_bonus = max(self.options.keyblade_min_mp.value, self.options.keyblade_max_mp.value) + self.options.keyblade_min_mp.value = min_mp_bonus + self.options.keyblade_max_mp.value = max_mp_bonus + slot_data["keyblade_stats"] = "" + for i in range(22): + if i < 4 and self.options.bad_starting_weapons: + slot_data["keyblade_stats"] = slot_data["keyblade_stats"] + "1,0," + else: + str_bonus = int(self.random.randint(min_str_bonus, max_str_bonus)) + mp_bonus = int(self.random.randint(min_mp_bonus, max_mp_bonus)) + slot_data["keyblade_stats"] = slot_data["keyblade_stats"] + str(str_bonus) + "," + str(mp_bonus) + "," + slot_data["keyblade_stats"] = slot_data["keyblade_stats"][:-1] + if self.options.donald_death_link: + slot_data["donalddl"] = "" + if self.options.goofy_death_link: + slot_data["goofydl"] = "" + if self.options.keyblades_unlock_chests: + slot_data["chestslocked"] = "" + else: + slot_data["chestsunlocked"] = "" + if self.options.interact_in_battle: + slot_data["interactinbattle"] = "" + return slot_data + + def create_item(self, name: str) -> KH1Item: + data = item_table[name] + return KH1Item(name, data.classification, data.code, self.player) + + def create_event(self, name: str) -> KH1Item: + data = event_item_table[name] + return KH1Item(name, data.classification, data.code, self.player) + + def set_rules(self): + set_rules(self) + + def create_regions(self): + create_regions(self.multiworld, self.player, self.options) + + def generate_early(self): + value_names = ["Reports to Open End of the World", "Reports to Open Final Rest Door", "Reports in Pool"] + initial_report_settings = [self.options.required_reports_eotw.value, self.options.required_reports_door.value, self.options.reports_in_pool.value] + self.change_numbers_of_reports_to_consider() + new_report_settings = [self.options.required_reports_eotw.value, self.options.required_reports_door.value, self.options.reports_in_pool.value] + for i in range(3): + if initial_report_settings[i] != new_report_settings[i]: + logging.info(f"{self.player_name}'s value {initial_report_settings[i]} for \"{value_names[i]}\" was invalid\n" + f"Setting \"{value_names[i]}\" value to {new_report_settings[i]}") + + def change_numbers_of_reports_to_consider(self) -> None: + if self.options.end_of_the_world_unlock == "reports" and self.options.final_rest_door == "reports": + self.options.required_reports_eotw.value, self.options.required_reports_door.value, self.options.reports_in_pool.value = sorted( + [self.options.required_reports_eotw.value, self.options.required_reports_door.value, self.options.reports_in_pool.value]) + + elif self.options.end_of_the_world_unlock == "reports": + self.options.required_reports_eotw.value, self.options.reports_in_pool.value = sorted( + [self.options.required_reports_eotw.value, self.options.reports_in_pool.value]) + + elif self.options.final_rest_door == "reports": + self.options.required_reports_door.value, self.options.reports_in_pool.value = sorted( + [self.options.required_reports_door.value, self.options.reports_in_pool.value]) + + def determine_reports_in_pool(self) -> int: + if self.options.end_of_the_world_unlock == "reports" or self.options.final_rest_door == "reports": + return self.options.reports_in_pool.value + return 0 + + def determine_reports_required_to_open_end_of_the_world(self) -> int: + if self.options.end_of_the_world_unlock == "reports": + return self.options.required_reports_eotw.value + return 14 + + def determine_reports_required_to_open_final_rest_door(self) -> int: + if self.options.final_rest_door == "reports": + return self.options.required_reports_door.value + return 14 diff --git a/worlds/kh1/docs/en_Kingdom Hearts.md b/worlds/kh1/docs/en_Kingdom Hearts.md new file mode 100644 index 000000000000..5167505efbbd --- /dev/null +++ b/worlds/kh1/docs/en_Kingdom Hearts.md @@ -0,0 +1,88 @@ +# Kingdom Hearts (PC) + +## Where is the options page? + +The [player options page for this game](../player-options) contains most of the options you need to +configure and export a config file. + +## What does randomization do to this game? + +The Kingdom Hearts AP Randomizer randomizes most rewards in the game and adds several items which are used to unlock worlds, Olympus Coliseum cups, and world progression. + +Worlds can only be accessed by finding the corresponding item. For example, you need to find the `Monstro` item to enter Monstro. + +The default goal is to enter End of the World and defeat Final Ansem. + +## What items and locations get shuffled? + +### Items + +Any weapon, accessory, spell, trinity, summon, world, key item, stat up, consumable, or ability can be found in any location. + +### Locations + +Locations the player can find items include chests, event rewards, Atlantica clams, level up rewards, 101 Dalmatian rewards, and postcard rewards. + +## Which items can be in another player's world? + +Any of the items which can be shuffled may also be placed into another player's world. It is possible to choose to limit +certain items to your own world. +## When the player receives an item, what happens? + +When the player receives an item, your client will display a message displaying the item you have obtained. You will also see a notification in the "LEVEL UP" box. + +## What do I do if I encounter a bug with the game? + +Please reach out to Gicu#7034 on Discord. + +## How do I progress in a certain world? + +### The evidence boxes aren't spawning in Wonderland. + +Find `Footprints` in the multiworld. + +### I can't enter any cups in Olympus Coliseum. + +Firstly, find `Entry Pass` in the multiworld. Additionally, `Phil Cup`, `Pegasus Cup`, and `Hercules Cup` are all multiworld items. Finding all 3 grant you access to the Hades Cup and the Platinum Match. Clearing all cups lets you challenge Ice Titan. + +### The slides aren't spawning in Deep Jungle. + +Find `Slides` in the multiworld. + +### I can't progress in Atlantica. +Find `Crystal Trident` in the multiworld. + +### I can't progress in Halloween Town. + +Find `Forget-Me-Not` and `Jack-in-the-Box` in the multiworld. + +### The Hollow Bastion Library is missing a book. + +Find `Theon Vol. 6` in the multiworld. + +## How do I enter the End of the World? + +You can enter End of the World by obtaining a number of Ansem's Reports or by finding `End of the World` in the multiworld, depending on your options. + +## Credits +This is a collaborative effort from several individuals in the Kingdom Hearts community, but most of all, denhonator. + +Denho's original KH rando laid the foundation for the work here and makes everything here possible, so thank you Denho for such a blast of a randomizer. + +Other credits include: + +Sonicshadowsilver2 for their work finding many memory addresses, working to identify and resolve bugs, and converting the code base to the latest EGS update. + +Shananas and the rest of the OpenKH team for providing such an amazing tool for us to utilize on this project. + +TopazTK for their work on the `Show Prompt` method and Krujo for their implementation of the method in AP. + +JaredWeakStrike for helping clean up my mess of code. + +KSX for their `Interact in Battle` code. + +RavSpect for their title screen image edit. + +SunCatMC for their work on ChecksFinder, which I used as a basis for game-to-client communication. + +ThePhar for their work on Rogue Legacy AP, which I used as a basis for the apworld creation. diff --git a/worlds/kh1/docs/kh1_en.md b/worlds/kh1/docs/kh1_en.md new file mode 100644 index 000000000000..522da20b0dc9 --- /dev/null +++ b/worlds/kh1/docs/kh1_en.md @@ -0,0 +1,54 @@ +# Kingdom Hearts Randomizer Setup Guide + +## Setting up the required mods + +BEFORE MODDING, PLEASE INSTALL AND RUN KH1 AT LEAST ONCE. + +1. Install OpenKH and the LUA Backend + + Download the [latest release of OpenKH](https://github.com/OpenKH/OpenKh/releases/tag/latest) + + Extract the files to a directory of your choosing. + + Open `OpenKh.Tools.ModsManager.exe` and run first time set up + + When prompted for game edition, choose `PC Release`, select which platform you're using (EGS or Steam), navigate to your `Kingdom Hearts I.5 + II.5` installation folder in the path box and click `Next` + + When prompted, install Panacea, then click `Next` + + When prompted, check KH1 plus any other AP game you play and click `Install and configure LUA backend`, then click `Next` + + Extracting game data for KH1 is unnecessary, but you may want to extract data for KH2 if you plan on playing KH2 AP + + Click `Finish` + +2. Open `OpenKh.Tools.ModsManager.exe` + +3. Click the drop-down menu at the top-right and choose `Kingdom Hearts 1` + +4. Click `Mods>Install a New Mod` + +5. In `Add a new mod from GitHub` paste `gaithern/KH-1FM-AP-LUA` + +6. Click `Install` + +7. Navigate to Mod Loader and click `Build and Run` + + +## Configuring your YAML file + +### What is a YAML file and why do I need one? + +Your YAML file contains a set of configuration options which provide the generator with information about how it should +generate your game. Each player of a multiworld will provide their own YAML file. This setup allows each player to enjoy +an experience customized for their taste, and different players in the same multiworld can all have different options. + +### Where do I get a YAML file? + +you can customize your settings by visiting the [Kingdom Hearts Options Page](/games/Kingdom%20Hearts/player-options). + +## Connect to the MultiWorld + +For first-time players, it is recommended to open your KH1 Client first before opening the game. + +On the title screen, open your KH1 Client and connect to your multiworld. diff --git a/worlds/kh1/test/__init__.py b/worlds/kh1/test/__init__.py new file mode 100644 index 000000000000..960b527f8b8a --- /dev/null +++ b/worlds/kh1/test/__init__.py @@ -0,0 +1,5 @@ +from test.bases import WorldTestBase + + +class KH1TestBase(WorldTestBase): + game = "Kingdom Hearts" diff --git a/worlds/kh1/test/test_goal.py b/worlds/kh1/test/test_goal.py new file mode 100644 index 000000000000..6b501404feee --- /dev/null +++ b/worlds/kh1/test/test_goal.py @@ -0,0 +1,33 @@ +from . import KH1TestBase + +class TestDefault(KH1TestBase): + options = {} + +class TestSephiroth(KH1TestBase): + options = { + "Goal": 0, + } + +class TestUnknown(KH1TestBase): + options = { + "Goal": 1, + } + +class TestPostcards(KH1TestBase): + options = { + "Goal": 2, + } + +class TestFinalAnsem(KH1TestBase): + options = { + "Goal": 3, + } + +class TestPuppies(KH1TestBase): + options = { + "Goal": 4, + } +class TestFinalRest(KH1TestBase): + options = { + "Goal": 5, + }