KH2 game implementation (#1438)
This commit is contained in:
parent
d4b793902f
commit
67bf12369a
|
@ -0,0 +1,874 @@
|
|||
import os
|
||||
import asyncio
|
||||
import ModuleUpdate
|
||||
import typing
|
||||
import json
|
||||
import Utils
|
||||
from pymem import pymem
|
||||
from worlds.kh2.Items import DonaldAbility_Table, GoofyAbility_Table, exclusionItem_table, CheckDupingItems
|
||||
from worlds.kh2 import all_locations, item_dictionary_table, exclusion_table
|
||||
|
||||
from worlds.kh2.WorldLocations import *
|
||||
|
||||
from worlds import network_data_package
|
||||
|
||||
if __name__ == "__main__":
|
||||
Utils.init_logging("KH2Client", exception_logger="Client")
|
||||
|
||||
from NetUtils import ClientStatus
|
||||
from CommonClient import gui_enabled, logger, get_base_parser, ClientCommandProcessor, \
|
||||
CommonContext, server_loop
|
||||
|
||||
ModuleUpdate.update()
|
||||
|
||||
kh2_loc_name_to_id = network_data_package["games"]["Kingdom Hearts 2"]["location_name_to_id"]
|
||||
|
||||
|
||||
# class KH2CommandProcessor(ClientCommandProcessor):
|
||||
|
||||
|
||||
class KH2Context(CommonContext):
|
||||
# command_processor: int = KH2CommandProcessor
|
||||
game = "Kingdom Hearts 2"
|
||||
items_handling = 0b101 # Indicates you get items sent from other worlds.
|
||||
|
||||
def __init__(self, server_address, password):
|
||||
super(KH2Context, self).__init__(server_address, password)
|
||||
self.kh2LocalItems = None
|
||||
self.ability = None
|
||||
self.growthlevel = None
|
||||
self.KH2_sync_task = None
|
||||
self.syncing = False
|
||||
self.kh2connected = False
|
||||
self.serverconneced = False
|
||||
self.item_name_to_data = {name: data for name, data, in item_dictionary_table.items()}
|
||||
self.location_name_to_data = {name: data for name, data, in all_locations.items()}
|
||||
self.lookup_id_to_item: typing.Dict[int, str] = {data.code: item_name for item_name, data in
|
||||
item_dictionary_table.items() if data.code}
|
||||
self.lookup_id_to_Location: typing.Dict[int, str] = {data.code: item_name for item_name, data in
|
||||
all_locations.items() if data.code}
|
||||
self.location_name_to_worlddata = {name: data for name, data, in all_world_locations.items()}
|
||||
|
||||
self.location_table = {}
|
||||
self.collectible_table = {}
|
||||
self.collectible_override_flags_address = 0
|
||||
self.collectible_offsets = {}
|
||||
self.sending = []
|
||||
# flag for if the player has gotten their starting inventory from the server
|
||||
self.hasStartingInvo = False
|
||||
# list used to keep track of locations+items player has. Used for disoneccting
|
||||
self.kh2seedsave = {"checked_locations": {"0": []},
|
||||
"starting_inventory": self.hasStartingInvo,
|
||||
|
||||
# Character: [back of invo, front of invo]
|
||||
"SoraInvo": [0x25CC, 0x2546],
|
||||
"DonaldInvo": [0x2678, 0x2658],
|
||||
"GoofyInvo": [0x278E, 0x276C],
|
||||
"AmountInvo": {
|
||||
"ServerItems": {
|
||||
"Ability": {},
|
||||
"Amount": {},
|
||||
"Growth": {"High Jump": 0, "Quick Run": 0, "Dodge Roll": 0, "Aerial Dodge": 0,
|
||||
"Glide": 0},
|
||||
"Bitmask": [],
|
||||
"Weapon": {"Sora": [], "Donald": [], "Goofy": []},
|
||||
"Equipment": [],
|
||||
"Magic": {},
|
||||
"StatIncrease": {},
|
||||
"Boost": {},
|
||||
},
|
||||
"LocalItems": {
|
||||
"Ability": {},
|
||||
"Amount": {},
|
||||
"Growth": {"High Jump": 0, "Quick Run": 0, "Dodge Roll": 0,
|
||||
"Aerial Dodge": 0, "Glide": 0},
|
||||
"Bitmask": [],
|
||||
"Weapon": {"Sora": [], "Donald": [], "Goofy": []},
|
||||
"Equipment": [],
|
||||
"Magic": {},
|
||||
"StatIncrease": {},
|
||||
"Boost": {},
|
||||
}},
|
||||
"worldIdChecks": {
|
||||
"1": [], # world of darkness (story cutscenes)
|
||||
"2": [],
|
||||
"3": [], # destiny island doesn't have checks to ima put tt checks here
|
||||
"4": [],
|
||||
"5": [],
|
||||
"6": [],
|
||||
"7": [],
|
||||
"8": [],
|
||||
"9": [],
|
||||
"10": [],
|
||||
"11": [],
|
||||
# atlantica isn't a supported world. if you go in atlantica it will check dc
|
||||
"12": [],
|
||||
"13": [],
|
||||
"14": [],
|
||||
"15": [],
|
||||
# world map, but you only go to the world map while on the way to goa so checking hb
|
||||
"16": [],
|
||||
"17": [],
|
||||
"18": [],
|
||||
"255": [], # starting screen
|
||||
},
|
||||
"Levels": {
|
||||
"SoraLevel": 0,
|
||||
"ValorLevel": 0,
|
||||
"WisdomLevel": 0,
|
||||
"LimitLevel": 0,
|
||||
"MasterLevel": 0,
|
||||
"FinalLevel": 0,
|
||||
}
|
||||
}
|
||||
self.slotDataProgressionNames = {}
|
||||
self.kh2seedname = None
|
||||
self.kh2slotdata = None
|
||||
self.itemamount = {}
|
||||
# sora equipped, valor equipped, master equipped, final equipped
|
||||
self.keybladeAnchorList = (0x24F0, 0x32F4, 0x339C, 0x33D4)
|
||||
if "localappdata" in os.environ:
|
||||
self.game_communication_path = os.path.expandvars(r"%localappdata%\KH2AP")
|
||||
self.amountOfPieces = 0
|
||||
# hooked object
|
||||
self.kh2 = None
|
||||
self.ItemIsSafe = False
|
||||
self.game_connected = False
|
||||
self.finalxemnas = False
|
||||
self.worldid = {
|
||||
1: TWTNW_Checks, # world of darkness (story cutscenes)
|
||||
2: TT_Checks,
|
||||
3: TT_Checks, # destiny island doesn't have checks to ima put tt checks here
|
||||
4: HB_Checks,
|
||||
5: BC_Checks,
|
||||
6: Oc_Checks,
|
||||
7: AG_Checks,
|
||||
8: LoD_Checks,
|
||||
9: HundredAcreChecks,
|
||||
10: PL_Checks,
|
||||
11: DC_Checks, # atlantica isn't a supported world. if you go in atlantica it will check dc
|
||||
12: DC_Checks,
|
||||
13: TR_Checks,
|
||||
14: HT_Checks,
|
||||
15: HB_Checks, # world map, but you only go to the world map while on the way to goa so checking hb
|
||||
16: PR_Checks,
|
||||
17: SP_Checks,
|
||||
18: TWTNW_Checks,
|
||||
255: HB_Checks, # starting screen
|
||||
}
|
||||
# 0x2A09C00+0x40 is the sve anchor. +1 is the last saved room
|
||||
self.sveroom = 0x2A09C00 + 0x41
|
||||
# 0 not in battle 1 in yellow battle 2 red battle #short
|
||||
self.inBattle = 0x2A0EAC4 + 0x40
|
||||
self.onDeath = 0xAB9078
|
||||
# PC Address anchors
|
||||
self.Now = 0x0714DB8
|
||||
self.Save = 0x09A70B0
|
||||
self.Sys3 = 0x2A59DF0
|
||||
self.Bt10 = 0x2A74880
|
||||
self.BtlEnd = 0x2A0D3E0
|
||||
self.Slot1 = 0x2A20C98
|
||||
|
||||
self.chest_set = set(exclusion_table["Chests"])
|
||||
|
||||
self.keyblade_set = set(CheckDupingItems["Weapons"]["Keyblades"])
|
||||
self.staff_set = set(CheckDupingItems["Weapons"]["Staffs"])
|
||||
self.shield_set = set(CheckDupingItems["Weapons"]["Shields"])
|
||||
|
||||
self.all_weapons = self.keyblade_set.union(self.staff_set).union(self.shield_set)
|
||||
|
||||
self.equipment_categories = CheckDupingItems["Equipment"]
|
||||
self.armor_set = set(self.equipment_categories["Armor"])
|
||||
self.accessories_set = set(self.equipment_categories["Accessories"])
|
||||
self.all_equipment = self.armor_set.union(self.accessories_set)
|
||||
|
||||
self.Equipment_Anchor_Dict = {
|
||||
"Armor": [0x2504, 0x2506, 0x2508, 0x250A],
|
||||
"Accessories": [0x2514, 0x2516, 0x2518, 0x251A]}
|
||||
|
||||
self.AbilityQuantityDict = {}
|
||||
self.ability_categories = CheckDupingItems["Abilities"]
|
||||
|
||||
self.sora_ability_set = set(self.ability_categories["Sora"])
|
||||
self.donald_ability_set = set(self.ability_categories["Donald"])
|
||||
self.goofy_ability_set = set(self.ability_categories["Goofy"])
|
||||
|
||||
self.all_abilities = self.sora_ability_set.union(self.donald_ability_set).union(self.goofy_ability_set)
|
||||
|
||||
self.boost_set = set(CheckDupingItems["Boosts"])
|
||||
self.stat_increase_set = set(CheckDupingItems["Stat Increases"])
|
||||
|
||||
self.AbilityQuantityDict = {item: self.item_name_to_data[item].quantity for item in self.all_abilities}
|
||||
# Growth:[level 1,level 4,slot]
|
||||
self.growth_values_dict = {"High Jump": [0x05E, 0x061, 0x25CE],
|
||||
"Quick Run": [0x62, 0x65, 0x25D0],
|
||||
"Dodge Roll": [0x234, 0x237, 0x25D2],
|
||||
"Aerial Dodge": [0x066, 0x069, 0x25D4],
|
||||
"Glide": [0x6A, 0x6D, 0x25D6]}
|
||||
self.boost_to_anchor_dict = {
|
||||
"Power Boost": 0x24F9,
|
||||
"Magic Boost": 0x24FA,
|
||||
"Defense Boost": 0x24FB,
|
||||
"AP Boost": 0x24F8}
|
||||
|
||||
self.AbilityCodeList = [self.item_name_to_data[item].code for item in exclusionItem_table["Ability"]]
|
||||
self.master_growth = {"High Jump", "Quick Run", "Dodge Roll", "Aerial Dodge", "Glide"}
|
||||
|
||||
self.bitmask_item_code = [
|
||||
0x130000, 0x130001, 0x130002, 0x130003, 0x130004, 0x130005, 0x130006, 0x130007
|
||||
, 0x130008, 0x130009, 0x13000A, 0x13000B, 0x13000C
|
||||
, 0x13001F, 0x130020, 0x130021, 0x130022, 0x130023
|
||||
, 0x13002A, 0x13002B, 0x13002C, 0x13002D]
|
||||
|
||||
async def server_auth(self, password_requested: bool = False):
|
||||
if password_requested and not self.password:
|
||||
await super(KH2Context, self).server_auth(password_requested)
|
||||
await self.get_username()
|
||||
await self.send_connect()
|
||||
|
||||
async def connection_closed(self):
|
||||
self.kh2connected = False
|
||||
self.serverconneced = False
|
||||
if self.kh2seedname is not None and self.auth is not None:
|
||||
with open(os.path.join(self.game_communication_path, f"kh2save{self.kh2seedname}{self.auth}.json"),
|
||||
'w') as f:
|
||||
f.write(json.dumps(self.kh2seedsave, indent=4))
|
||||
await super(KH2Context, self).connection_closed()
|
||||
|
||||
async def disconnect(self, allow_autoreconnect: bool = False):
|
||||
self.kh2connected = False
|
||||
self.serverconneced = False
|
||||
if self.kh2seedname not in {None} and self.auth not in {None}:
|
||||
with open(os.path.join(self.game_communication_path, f"kh2save{self.kh2seedname}{self.auth}.json"),
|
||||
'w') as f:
|
||||
f.write(json.dumps(self.kh2seedsave, indent=4))
|
||||
await super(KH2Context, self).disconnect()
|
||||
|
||||
@property
|
||||
def endpoints(self):
|
||||
if self.server:
|
||||
return [self.server]
|
||||
else:
|
||||
return []
|
||||
|
||||
async def shutdown(self):
|
||||
if self.kh2seedname not in {None} and self.auth not in {None}:
|
||||
with open(os.path.join(self.game_communication_path, f"kh2save{self.kh2seedname}{self.auth}.json"),
|
||||
'w') as f:
|
||||
f.write(json.dumps(self.kh2seedsave, indent=4))
|
||||
await super(KH2Context, self).shutdown()
|
||||
|
||||
def on_package(self, cmd: str, args: dict):
|
||||
if cmd in {"RoomInfo"}:
|
||||
self.kh2seedname = args['seed_name']
|
||||
if not os.path.exists(self.game_communication_path):
|
||||
os.makedirs(self.game_communication_path)
|
||||
if not os.path.exists(self.game_communication_path + f"\kh2save{self.kh2seedname}{self.auth}.json"):
|
||||
with open(os.path.join(self.game_communication_path, f"kh2save{self.kh2seedname}{self.auth}.json"),
|
||||
'wt') as f:
|
||||
pass
|
||||
elif os.path.exists(self.game_communication_path + f"\kh2save{self.kh2seedname}{self.auth}.json"):
|
||||
with open(self.game_communication_path + f"\kh2save{self.kh2seedname}{self.auth}.json", 'r') as f:
|
||||
self.kh2seedsave = json.load(f)
|
||||
|
||||
if cmd in {"Connected"}:
|
||||
for player in args['players']:
|
||||
if str(player.slot) not in self.kh2seedsave["checked_locations"]:
|
||||
self.kh2seedsave["checked_locations"].update({str(player.slot): []})
|
||||
self.kh2slotdata = args['slot_data']
|
||||
self.serverconneced = True
|
||||
self.kh2LocalItems = {int(location): item for location, item in self.kh2slotdata["LocalItems"].items()}
|
||||
try:
|
||||
self.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX")
|
||||
logger.info("You are now auto-tracking")
|
||||
self.kh2connected = True
|
||||
except Exception as e:
|
||||
logger.info("Line 247")
|
||||
if self.kh2connected:
|
||||
logger.info("Connection Lost")
|
||||
self.kh2connected = False
|
||||
logger.info(e)
|
||||
|
||||
if cmd in {"ReceivedItems"}:
|
||||
start_index = args["index"]
|
||||
if start_index != len(self.items_received):
|
||||
for item in args['items']:
|
||||
# starting invo from server
|
||||
if item.location in {-2}:
|
||||
if not self.kh2seedsave["starting_inventory"]:
|
||||
asyncio.create_task(self.give_item(item.item))
|
||||
# if location is not already given or is !getitem
|
||||
elif item.location not in self.kh2seedsave["checked_locations"][str(item.player)] \
|
||||
or item.location in {-1}:
|
||||
asyncio.create_task(self.give_item(item.item))
|
||||
if item.location not in self.kh2seedsave["checked_locations"][str(item.player)] \
|
||||
and item.location not in {-1, -2}:
|
||||
self.kh2seedsave["checked_locations"][str(item.player)].append(item.location)
|
||||
if not self.kh2seedsave["starting_inventory"] and self.kh2connected:
|
||||
self.kh2seedsave["starting_inventory"] = True
|
||||
|
||||
if cmd in {"RoomUpdate"}:
|
||||
if "checked_locations" in args:
|
||||
new_locations = set(args["checked_locations"])
|
||||
# TODO: make this take locations from other players on the same slot so proper coop happens
|
||||
#items_to_give = [self.kh2slotdata["LocalItems"][str(location_id)] for location_id in new_locations if
|
||||
# location_id in self.kh2LocalItems.keys()]
|
||||
self.checked_locations |= new_locations
|
||||
|
||||
async def checkWorldLocations(self):
|
||||
try:
|
||||
currentworldint = int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + 0x0714DB8, 1), "big")
|
||||
curworldid = self.worldid[currentworldint]
|
||||
if currentworldint != 1:
|
||||
for location, data in curworldid.items():
|
||||
if location not in self.locations_checked \
|
||||
and (int.from_bytes(
|
||||
self.kh2.read_bytes(self.kh2.base_address + self.Save + data.addrObtained, 1),
|
||||
"big") & 0x1 << data.bitIndex) > 0:
|
||||
self.locations_checked.add(location)
|
||||
self.sending = self.sending + [(int(kh2_loc_name_to_id[location]))]
|
||||
except Exception as e:
|
||||
logger.info("Line 285")
|
||||
if self.kh2connected:
|
||||
logger.info("Connection Lost.")
|
||||
self.kh2connected = False
|
||||
logger.info(e)
|
||||
|
||||
async def checkLevels(self):
|
||||
try:
|
||||
for location, data in SoraLevels.items():
|
||||
currentLevel = int.from_bytes(
|
||||
self.kh2.read_bytes(self.kh2.base_address + self.Save + 0x24FF, 1), "big")
|
||||
if location not in self.locations_checked \
|
||||
and currentLevel >= data.bitIndex:
|
||||
if self.kh2seedsave["Levels"]["SoraLevel"] < currentLevel:
|
||||
self.kh2seedsave["Levels"]["SoraLevel"] = currentLevel
|
||||
self.locations_checked.add(location)
|
||||
self.sending = self.sending + [(int(kh2_loc_name_to_id[location]))]
|
||||
formDict = {
|
||||
0: ["ValorLevel", ValorLevels], 1: ["WisdomLevel", WisdomLevels], 2: ["LimitLevel", LimitLevels],
|
||||
3: ["MasterLevel", MasterLevels], 4: ["FinalLevel", FinalLevels]}
|
||||
for i in range(5):
|
||||
for location, data in formDict[i][1].items():
|
||||
formlevel = int.from_bytes(
|
||||
self.kh2.read_bytes(self.kh2.base_address + self.Save + data.addrObtained, 1), "big")
|
||||
if location not in self.locations_checked \
|
||||
and formlevel >= data.bitIndex:
|
||||
if formlevel > self.kh2seedsave["Levels"][formDict[i][0]]:
|
||||
self.kh2seedsave["Levels"][formDict[i][0]] = formlevel
|
||||
self.locations_checked.add(location)
|
||||
self.sending = self.sending + [(int(kh2_loc_name_to_id[location]))]
|
||||
except Exception as e:
|
||||
logger.info("Line 312")
|
||||
if self.kh2connected:
|
||||
logger.info("Connection Lost.")
|
||||
self.kh2connected = False
|
||||
logger.info(e)
|
||||
|
||||
async def checkSlots(self):
|
||||
try:
|
||||
for location, data in weaponSlots.items():
|
||||
if location not in self.locations_checked:
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + data.addrObtained, 1),
|
||||
"big") > 0:
|
||||
self.locations_checked.add(location)
|
||||
self.sending = self.sending + [(int(kh2_loc_name_to_id[location]))]
|
||||
|
||||
for location, data in formSlots.items():
|
||||
if location not in self.locations_checked:
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + data.addrObtained, 1),
|
||||
"big") & 0x1 << data.bitIndex > 0:
|
||||
self.locations_checked.add(location)
|
||||
self.sending = self.sending + [(int(kh2_loc_name_to_id[location]))]
|
||||
except Exception as e:
|
||||
if self.kh2connected:
|
||||
logger.info("Line 333")
|
||||
logger.info("Connection Lost.")
|
||||
self.kh2connected = False
|
||||
logger.info(e)
|
||||
|
||||
async def verifyChests(self):
|
||||
try:
|
||||
currentworld = str(int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + 0x0714DB8, 1), "big"))
|
||||
for location in self.kh2seedsave["worldIdChecks"][currentworld]:
|
||||
locationName = self.lookup_id_to_Location[location]
|
||||
if locationName in self.chest_set:
|
||||
if locationName in self.location_name_to_worlddata.keys():
|
||||
locationData = self.location_name_to_worlddata[locationName]
|
||||
if int.from_bytes(
|
||||
self.kh2.read_bytes(self.kh2.base_address + self.Save + locationData.addrObtained, 1),
|
||||
"big") & 0x1 << locationData.bitIndex == 0:
|
||||
roomData = int.from_bytes(
|
||||
self.kh2.read_bytes(self.kh2.base_address + self.Save + locationData.addrObtained,
|
||||
1), "big")
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + locationData.addrObtained,
|
||||
(roomData | 0x01 << locationData.bitIndex).to_bytes(1, 'big'), 1)
|
||||
|
||||
except Exception as e:
|
||||
if self.kh2connected:
|
||||
logger.info("Line 350")
|
||||
logger.info("Connection Lost.")
|
||||
self.kh2connected = False
|
||||
logger.info(e)
|
||||
|
||||
async def verifyLevel(self):
|
||||
for leveltype, anchor in {"SoraLevel": 0x24FF,
|
||||
"ValorLevel": 0x32F6,
|
||||
"WisdomLevel": 0x332E,
|
||||
"LimitLevel": 0x3366,
|
||||
"MasterLevel": 0x339E,
|
||||
"FinalLevel": 0x33D6}.items():
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + anchor, 1), "big") < \
|
||||
self.kh2seedsave["Levels"][leveltype]:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + anchor,
|
||||
(self.kh2seedsave["Levels"][leveltype]).to_bytes(1, 'big'), 1)
|
||||
|
||||
def verifyLocation(self, location):
|
||||
locationData = self.location_name_to_worlddata[location]
|
||||
locationName = self.lookup_id_to_Location[location]
|
||||
isChecked = True
|
||||
|
||||
if locationName not in levels_locations:
|
||||
if (int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + locationData.addrObtained, 1),
|
||||
"big") & 0x1 << locationData.bitIndex) == 0:
|
||||
isChecked = False
|
||||
elif locationName in SoraLevels:
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + 0x24FF, 1),
|
||||
"big") < locationData.bitIndex:
|
||||
isChecked = False
|
||||
elif int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + locationData.addrObtained, 1),
|
||||
"big") < locationData.bitIndex:
|
||||
isChecked = False
|
||||
return isChecked
|
||||
|
||||
async def give_item(self, item, ItemType="ServerItems"):
|
||||
while not self.kh2connected:
|
||||
await asyncio.sleep(1)
|
||||
try:
|
||||
itemname = self.lookup_id_to_item[item]
|
||||
itemcode = self.item_name_to_data[itemname]
|
||||
# cannot give items during loading screens
|
||||
# 0x8E9DA3=load 0xAB8BC7=black 0x2A148E8=controllable 0x715568=room transition
|
||||
while int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Now, 1), "big") in {255, 1}:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
if itemcode.ability:
|
||||
abilityInvoType = 0
|
||||
TwilightZone = 2
|
||||
if ItemType == "LocalItems":
|
||||
abilityInvoType = 1
|
||||
TwilightZone = -2
|
||||
if itemname in {"High Jump", "Quick Run", "Dodge Roll", "Aerial Dodge", "Glide"}:
|
||||
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Growth"][itemname] += 1
|
||||
return
|
||||
|
||||
if itemname not in self.kh2seedsave["AmountInvo"][ItemType]["Ability"]:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Ability"][itemname] = []
|
||||
# appending the slot that the ability should be in
|
||||
|
||||
if len(self.kh2seedsave["AmountInvo"][ItemType]["Ability"][itemname]) < \
|
||||
self.AbilityQuantityDict[itemname]:
|
||||
if itemname in self.sora_ability_set:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Ability"][itemname].append(
|
||||
self.kh2seedsave["SoraInvo"][abilityInvoType])
|
||||
self.kh2seedsave["SoraInvo"][abilityInvoType] -= TwilightZone
|
||||
elif itemname in self.donald_ability_set:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Ability"][itemname].append(
|
||||
self.kh2seedsave["DonaldInvo"][abilityInvoType])
|
||||
self.kh2seedsave["DonaldInvo"][abilityInvoType] -= TwilightZone
|
||||
else:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Ability"][itemname].append(
|
||||
self.kh2seedsave["GoofyInvo"][abilityInvoType])
|
||||
self.kh2seedsave["GoofyInvo"][abilityInvoType] -= TwilightZone
|
||||
|
||||
elif itemcode.code in self.bitmask_item_code:
|
||||
|
||||
if itemname not in self.kh2seedsave["AmountInvo"][ItemType]["Bitmask"]:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Bitmask"].append(itemname)
|
||||
|
||||
elif itemcode.memaddr in {0x3594, 0x3595, 0x3596, 0x3597, 0x35CF, 0x35D0}:
|
||||
|
||||
if itemname in self.kh2seedsave["AmountInvo"][ItemType]["Magic"]:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Magic"][itemname] += 1
|
||||
else:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Magic"][itemname] = 1
|
||||
elif itemname in self.all_equipment:
|
||||
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Equipment"].append(itemname)
|
||||
|
||||
elif itemname in self.all_weapons:
|
||||
if itemname in self.keyblade_set:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Weapon"]["Sora"].append(itemname)
|
||||
elif itemname in self.staff_set:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Weapon"]["Donald"].append(itemname)
|
||||
else:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Weapon"]["Goofy"].append(itemname)
|
||||
|
||||
elif itemname in self.boost_set:
|
||||
if itemname in self.kh2seedsave["AmountInvo"][ItemType]["Boost"]:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Boost"][itemname] += 1
|
||||
else:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Boost"][itemname] = 1
|
||||
|
||||
elif itemname in self.stat_increase_set:
|
||||
|
||||
if itemname in self.kh2seedsave["AmountInvo"][ItemType]["StatIncrease"]:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["StatIncrease"][itemname] += 1
|
||||
else:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["StatIncrease"][itemname] = 1
|
||||
|
||||
else:
|
||||
if itemname in self.kh2seedsave["AmountInvo"][ItemType]["Amount"]:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Amount"][itemname] += 1
|
||||
else:
|
||||
self.kh2seedsave["AmountInvo"][ItemType]["Amount"][itemname] = 1
|
||||
|
||||
except Exception as e:
|
||||
if self.kh2connected:
|
||||
logger.info("Line 398")
|
||||
logger.info("Connection Lost.")
|
||||
self.kh2connected = False
|
||||
logger.info(e)
|
||||
|
||||
def run_gui(self):
|
||||
"""Import kivy UI system and start running it as self.ui_task."""
|
||||
from kvui import GameManager
|
||||
|
||||
class KH2Manager(GameManager):
|
||||
logging_pairs = [
|
||||
("Client", "Archipelago")
|
||||
]
|
||||
base_title = "Archipelago KH2 Client"
|
||||
|
||||
self.ui = KH2Manager(self)
|
||||
self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI")
|
||||
|
||||
async def verifyItems(self):
|
||||
try:
|
||||
local_amount = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Amount"].keys())
|
||||
server_amount = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Amount"].keys())
|
||||
master_amount = local_amount | server_amount
|
||||
|
||||
local_ability = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Ability"].keys())
|
||||
server_ability = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Ability"].keys())
|
||||
master_ability = local_ability | server_ability
|
||||
|
||||
local_bitmask = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Bitmask"])
|
||||
server_bitmask = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Bitmask"])
|
||||
master_bitmask = local_bitmask | server_bitmask
|
||||
|
||||
local_keyblade = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Weapon"]["Sora"])
|
||||
local_staff = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Weapon"]["Donald"])
|
||||
local_shield = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Weapon"]["Goofy"])
|
||||
|
||||
server_keyblade = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Weapon"]["Sora"])
|
||||
server_staff = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Weapon"]["Donald"])
|
||||
server_shield = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Weapon"]["Goofy"])
|
||||
|
||||
master_keyblade = local_keyblade | server_keyblade
|
||||
master_staff = local_staff | server_staff
|
||||
master_shield = local_shield | server_shield
|
||||
|
||||
local_equipment = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Equipment"])
|
||||
server_equipment = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Equipment"])
|
||||
master_equipment = local_equipment | server_equipment
|
||||
|
||||
local_magic = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Magic"].keys())
|
||||
server_magic = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Magic"].keys())
|
||||
master_magic = local_magic | server_magic
|
||||
|
||||
local_stat = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["StatIncrease"].keys())
|
||||
server_stat = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["StatIncrease"].keys())
|
||||
master_stat = local_stat | server_stat
|
||||
|
||||
local_boost = set(self.kh2seedsave["AmountInvo"]["LocalItems"]["Boost"].keys())
|
||||
server_boost = set(self.kh2seedsave["AmountInvo"]["ServerItems"]["Boost"].keys())
|
||||
master_boost = local_boost | server_boost
|
||||
|
||||
for itemName in master_amount:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
amountOfItems = 0
|
||||
if itemName in local_amount:
|
||||
amountOfItems += self.kh2seedsave["AmountInvo"]["LocalItems"]["Amount"][itemName]
|
||||
if itemName in server_amount:
|
||||
amountOfItems += self.kh2seedsave["AmountInvo"]["ServerItems"]["Amount"][itemName]
|
||||
|
||||
if itemName == "Torn Page":
|
||||
# Torn Pages are handled differently because they can be consumed.
|
||||
# Will check the progression in 100 acre and - the amount of visits
|
||||
# amountofitems-amount of visits done
|
||||
for location, data in tornPageLocks.items():
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + data.addrObtained, 1),
|
||||
"big") & 0x1 << data.bitIndex > 0:
|
||||
amountOfItems -= 1
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big") != amountOfItems and amountOfItems >= 0:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
amountOfItems.to_bytes(1, 'big'), 1)
|
||||
|
||||
for itemName in master_keyblade:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
# if isChecked:
|
||||
# if the inventory slot for that keyblade is less than the amount they should have
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big") <= 0:
|
||||
# Checking form anchors for the keyblade
|
||||
if self.kh2.read_short(self.kh2.base_address + self.Save + 0x24F0) == itemData.kh2id \
|
||||
or self.kh2.read_short(self.kh2.base_address + self.Save + 0x32F4) == itemData.kh2id \
|
||||
or self.kh2.read_short(self.kh2.base_address + self.Save + 0x339C) == itemData.kh2id \
|
||||
or self.kh2.read_short(self.kh2.base_address + self.Save + 0x33D4) == itemData.kh2id:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
(0).to_bytes(1, 'big'), 1)
|
||||
else:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
(1).to_bytes(1, 'big'), 1)
|
||||
for itemName in master_staff:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big") != 1 \
|
||||
and self.kh2.read_short(self.kh2.base_address + self.Save + 0x2604) != itemData.kh2id:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
(1).to_bytes(1, 'big'), 1)
|
||||
|
||||
for itemName in master_shield:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big") != 1 \
|
||||
and self.kh2.read_short(self.kh2.base_address + self.Save + 0x2718) != itemData.kh2id:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
(1).to_bytes(1, 'big'), 1)
|
||||
|
||||
for itemName in master_ability:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
ability_slot = []
|
||||
if itemName in local_ability:
|
||||
ability_slot += self.kh2seedsave["AmountInvo"]["LocalItems"]["Ability"][itemName]
|
||||
if itemName in server_ability:
|
||||
ability_slot += self.kh2seedsave["AmountInvo"]["ServerItems"]["Ability"][itemName]
|
||||
for slot in ability_slot:
|
||||
current = self.kh2.read_short(self.kh2.base_address + self.Save + slot)
|
||||
ability = current & 0x0FFF
|
||||
if ability | 0x8000 != (0x8000 + itemData.memaddr):
|
||||
self.kh2.write_short(self.kh2.base_address + self.Save + slot, itemData.memaddr)
|
||||
|
||||
for itemName in self.master_growth:
|
||||
growthLevel = self.kh2seedsave["AmountInvo"]["ServerItems"]["Growth"][itemName] \
|
||||
+ self.kh2seedsave["AmountInvo"]["LocalItems"]["Growth"][itemName]
|
||||
if growthLevel > 0:
|
||||
slot = self.growth_values_dict[itemName][2]
|
||||
min_growth = self.growth_values_dict[itemName][0]
|
||||
max_growth = self.growth_values_dict[itemName][1]
|
||||
if growthLevel > 4:
|
||||
growthLevel = 4
|
||||
current_growth_level = self.kh2.read_short(self.kh2.base_address + self.Save + slot)
|
||||
ability = current_growth_level & 0x0FFF
|
||||
# if the player should be getting a growth ability
|
||||
if ability | 0x8000 != 0x8000 + min_growth - 1 + growthLevel:
|
||||
# if it should be level one of that growth
|
||||
if 0x8000 + min_growth - 1 + growthLevel <= 0x8000 + min_growth or ability < min_growth:
|
||||
self.kh2.write_short(self.kh2.base_address + self.Save + slot, min_growth)
|
||||
# if it is already in the inventory
|
||||
elif ability | 0x8000 < (0x8000 + max_growth):
|
||||
self.kh2.write_short(self.kh2.base_address + self.Save + slot, current_growth_level + 1)
|
||||
|
||||
for itemName in master_bitmask:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
itemMemory = int.from_bytes(
|
||||
self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1), "big")
|
||||
if (int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big") & 0x1 << itemData.bitmask) == 0:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
(itemMemory | 0x01 << itemData.bitmask).to_bytes(1, 'big'), 1)
|
||||
|
||||
for itemName in master_equipment:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
isThere = False
|
||||
if itemName in self.accessories_set:
|
||||
Equipment_Anchor_List = self.Equipment_Anchor_Dict["Accessories"]
|
||||
else:
|
||||
Equipment_Anchor_List = self.Equipment_Anchor_Dict["Armor"]
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big") != 1:
|
||||
# Checking form anchors for the equipment
|
||||
for slot in Equipment_Anchor_List:
|
||||
if self.kh2.read_short(self.kh2.base_address + self.Save + slot) == itemData.kh2id:
|
||||
isThere = True
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
(0).to_bytes(1, 'big'), 1)
|
||||
break
|
||||
if not isThere:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
(1).to_bytes(1, 'big'), 1)
|
||||
|
||||
for itemName in master_magic:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
amountOfItems = 0
|
||||
if itemName in local_magic:
|
||||
amountOfItems += self.kh2seedsave["AmountInvo"]["LocalItems"]["Magic"][itemName]
|
||||
if itemName in server_magic:
|
||||
amountOfItems += self.kh2seedsave["AmountInvo"]["ServerItems"]["Magic"][itemName]
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big") != amountOfItems \
|
||||
and int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + 0x741320, 1), "big") in {10, 8}:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
amountOfItems.to_bytes(1, 'big'), 1)
|
||||
|
||||
for itemName in master_stat:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
amountOfItems = 0
|
||||
if itemName in local_stat:
|
||||
amountOfItems += self.kh2seedsave["AmountInvo"]["LocalItems"]["StatIncrease"][itemName]
|
||||
if itemName in server_stat:
|
||||
amountOfItems += self.kh2seedsave["AmountInvo"]["ServerItems"]["StatIncrease"][itemName]
|
||||
|
||||
if int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big") != amountOfItems \
|
||||
and int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + self.Slot1 + 0x1B2, 1),
|
||||
"big") >= 5:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
amountOfItems.to_bytes(1, 'big'), 1)
|
||||
|
||||
for itemName in master_boost:
|
||||
itemData = self.item_name_to_data[itemName]
|
||||
amountOfItems = 0
|
||||
if itemName in local_boost:
|
||||
amountOfItems += self.kh2seedsave["AmountInvo"]["LocalItems"]["Boost"][itemName]
|
||||
if itemName in server_boost:
|
||||
amountOfItems += self.kh2seedsave["AmountInvo"]["ServerItems"]["Boost"][itemName]
|
||||
amountOfBoostsInInvo = int.from_bytes(
|
||||
self.kh2.read_bytes(self.kh2.base_address + self.Save + itemData.memaddr, 1),
|
||||
"big")
|
||||
amountOfUsedBoosts = int.from_bytes(
|
||||
self.kh2.read_bytes(self.kh2.base_address + self.Save + self.boost_to_anchor_dict[itemName], 1),
|
||||
"big")
|
||||
# Ap Boots start at +50 for some reason
|
||||
if itemName == "AP Boost":
|
||||
amountOfUsedBoosts -= 50
|
||||
if (amountOfBoostsInInvo + amountOfUsedBoosts) <= amountOfItems and amountOfBoostsInInvo < 255:
|
||||
self.kh2.write_bytes(self.kh2.base_address + self.Save + itemData.memaddr,
|
||||
(amountOfBoostsInInvo + 1).to_bytes(1, 'big'), 1)
|
||||
|
||||
except Exception as e:
|
||||
logger.info("Line 573")
|
||||
if self.kh2connected:
|
||||
logger.info("Connection Lost.")
|
||||
self.kh2connected = False
|
||||
logger.info(e)
|
||||
|
||||
|
||||
def finishedGame(ctx: KH2Context, message):
|
||||
if ctx.kh2slotdata['FinalXemnas'] == 1:
|
||||
if 0x1301ED in message[0]["locations"]:
|
||||
ctx.finalxemnas = True
|
||||
# three proofs
|
||||
if ctx.kh2slotdata['Goal'] == 0:
|
||||
if int.from_bytes(ctx.kh2.read_bytes(ctx.kh2.base_address + ctx.Save + 0x36B2, 1), "big") > 0 \
|
||||
and int.from_bytes(ctx.kh2.read_bytes(ctx.kh2.base_address + ctx.Save + 0x36B3, 1), "big") > 0 \
|
||||
and int.from_bytes(ctx.kh2.read_bytes(ctx.kh2.base_address + ctx.Save + 0x36B4, 1), "big") > 0:
|
||||
if ctx.kh2slotdata['FinalXemnas'] == 1:
|
||||
if ctx.finalxemnas:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif ctx.kh2slotdata['Goal'] == 1:
|
||||
if int.from_bytes(ctx.kh2.read_bytes(ctx.kh2.base_address + ctx.Save + 0x3641, 1), "big") >= \
|
||||
ctx.kh2slotdata['LuckyEmblemsRequired']:
|
||||
ctx.kh2.write_bytes(ctx.kh2.base_address + ctx.Save + 0x36B2, (1).to_bytes(1, 'big'), 1)
|
||||
ctx.kh2.write_bytes(ctx.kh2.base_address + ctx.Save + 0x36B3, (1).to_bytes(1, 'big'), 1)
|
||||
ctx.kh2.write_bytes(ctx.kh2.base_address + ctx.Save + 0x36B4, (1).to_bytes(1, 'big'), 1)
|
||||
if ctx.kh2slotdata['FinalXemnas'] == 1:
|
||||
if ctx.finalxemnas:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif ctx.kh2slotdata['Goal'] == 2:
|
||||
for boss in ctx.kh2slotdata["hitlist"]:
|
||||
if boss in message[0]["locations"]:
|
||||
ctx.amountOfPieces += 1
|
||||
if ctx.amountOfPieces >= ctx.kh2slotdata["BountyRequired"]:
|
||||
ctx.kh2.write_bytes(ctx.kh2.base_address + ctx.Save + 0x36B2, (1).to_bytes(1, 'big'), 1)
|
||||
ctx.kh2.write_bytes(ctx.kh2.base_address + ctx.Save + 0x36B3, (1).to_bytes(1, 'big'), 1)
|
||||
ctx.kh2.write_bytes(ctx.kh2.base_address + ctx.Save + 0x36B4, (1).to_bytes(1, 'big'), 1)
|
||||
if ctx.kh2slotdata['FinalXemnas'] == 1:
|
||||
if ctx.finalxemnas:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
async def kh2_watcher(ctx: KH2Context):
|
||||
while not ctx.exit_event.is_set():
|
||||
try:
|
||||
if ctx.kh2connected and ctx.serverconneced:
|
||||
ctx.sending = []
|
||||
await asyncio.create_task(ctx.checkWorldLocations())
|
||||
await asyncio.create_task(ctx.checkLevels())
|
||||
await asyncio.create_task(ctx.checkSlots())
|
||||
await asyncio.create_task(ctx.verifyChests())
|
||||
await asyncio.create_task(ctx.verifyItems())
|
||||
await asyncio.create_task(ctx.verifyLevel())
|
||||
message = [{"cmd": 'LocationChecks', "locations": ctx.sending}]
|
||||
if finishedGame(ctx, message):
|
||||
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
|
||||
ctx.finished_game = True
|
||||
location_ids = []
|
||||
location_ids = [location for location in message[0]["locations"] if location not in location_ids]
|
||||
for location in location_ids:
|
||||
currentWorld = int.from_bytes(ctx.kh2.read_bytes(ctx.kh2.base_address + 0x0714DB8, 1), "big")
|
||||
if location not in ctx.kh2seedsave["worldIdChecks"][str(currentWorld)]:
|
||||
ctx.kh2seedsave["worldIdChecks"][str(currentWorld)].append(location)
|
||||
if location in ctx.kh2LocalItems:
|
||||
item = ctx.kh2slotdata["LocalItems"][str(location)]
|
||||
await asyncio.create_task(ctx.give_item(item, "LocalItems"))
|
||||
await ctx.send_msgs(message)
|
||||
elif not ctx.kh2connected and ctx.serverconneced:
|
||||
logger.info("Game is not open. Disconnecting from Server.")
|
||||
await ctx.disconnect()
|
||||
except Exception as e:
|
||||
logger.info("Line 661")
|
||||
if ctx.kh2connected:
|
||||
logger.info("Connection Lost.")
|
||||
ctx.kh2connected = False
|
||||
logger.info(e)
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
async def main(args):
|
||||
ctx = KH2Context(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(
|
||||
kh2_watcher(ctx), name="KH2ProgressionWatcher")
|
||||
|
||||
await ctx.exit_event.wait()
|
||||
ctx.server_address = None
|
||||
|
||||
await progression_watcher
|
||||
|
||||
await ctx.shutdown()
|
||||
|
||||
|
||||
import colorama
|
||||
|
||||
parser = get_base_parser(description="KH2 Client, for text interfacing.")
|
||||
|
||||
args, rest = parser.parse_known_args()
|
||||
colorama.init()
|
||||
asyncio.run(main(args))
|
||||
colorama.deinit()
|
|
@ -159,6 +159,8 @@ components: Iterable[Component] = (
|
|||
# Zillion
|
||||
Component('Zillion Client', 'ZillionClient',
|
||||
file_identifier=SuffixIdentifier('.apzl')),
|
||||
#Kingdom Hearts 2
|
||||
Component('KH2 Client', "KH2Client"),
|
||||
# Functions
|
||||
Component('Open host.yaml', func=open_host_yaml),
|
||||
Component('Open Patch', func=open_patch),
|
||||
|
|
|
@ -88,6 +88,8 @@ def download_slot_file(room_id, player_id: int):
|
|||
fname = f"AP_{app.jinja_env.filters['suuid'](room_id)}_SP.apsm64ex"
|
||||
elif slot_data.game == "Dark Souls III":
|
||||
fname = f"AP_{app.jinja_env.filters['suuid'](room_id)}.json"
|
||||
elif slot_data.game == "Kingdom Hearts 2":
|
||||
fname = f"AP_{app.jinja_env.filters['suuid'](room_id)}_P{slot_data.player_id}_{slot_data.player_name}.zip"
|
||||
else:
|
||||
return "Game download not supported."
|
||||
return send_file(io.BytesIO(slot_data.data), as_attachment=True, download_name=fname)
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
{% elif patch.game == "Factorio" %}
|
||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||
Download Factorio Mod...</a>
|
||||
{% elif patch.game == "Kingdom Hearts 2" %}
|
||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||
Download Kingdom Hearts 2 Mod...</a>
|
||||
{% elif patch.game == "Ocarina of Time" %}
|
||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||
Download APZ5 File...</a>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,404 @@
|
|||
# reports
|
||||
SecretAnsemsReport1 = "Secret Ansem's Report 1"
|
||||
SecretAnsemsReport2 = "Secret Ansem's Report 2"
|
||||
SecretAnsemsReport3 = "Secret Ansem's Report 3"
|
||||
SecretAnsemsReport4 = "Secret Ansem's Report 4"
|
||||
SecretAnsemsReport5 = "Secret Ansem's Report 5"
|
||||
SecretAnsemsReport6 = "Secret Ansem's Report 6"
|
||||
SecretAnsemsReport7 = "Secret Ansem's Report 7"
|
||||
SecretAnsemsReport8 = "Secret Ansem's Report 8"
|
||||
SecretAnsemsReport9 = "Secret Ansem's Report 9"
|
||||
SecretAnsemsReport10 = "Secret Ansem's Report 10"
|
||||
SecretAnsemsReport11 = "Secret Ansem's Report 11"
|
||||
SecretAnsemsReport12 = "Secret Ansem's Report 12"
|
||||
SecretAnsemsReport13 = "Secret Ansem's Report 13"
|
||||
|
||||
# progression
|
||||
ProofofConnection = "Proof of Connection"
|
||||
ProofofNonexistence = "Proof of Nonexistence"
|
||||
ProofofPeace = "Proof of Peace"
|
||||
PromiseCharm = "Promise Charm"
|
||||
BattlefieldsofWar = "Battlefields of War"
|
||||
SwordoftheAncestor = "Sword of the Ancestor"
|
||||
BeastsClaw = "Beast's Claw"
|
||||
BoneFist = "Bone Fist"
|
||||
ProudFang = "Proud Fang"
|
||||
SkillandCrossbones = "Skill and Crossbones"
|
||||
Scimitar = "Scimitar"
|
||||
MembershipCard = "Membership Card"
|
||||
IceCream = "Ice Cream"
|
||||
WaytotheDawn = "Way to the Dawn"
|
||||
IdentityDisk = "Identity Disk"
|
||||
NamineSketches = "Namine Sketches"
|
||||
CastleKey = "Disney Castle Key"
|
||||
TornPages = "Torn Page"
|
||||
TornPages = "Torn Page"
|
||||
TornPages = "Torn Page"
|
||||
TornPages = "Torn Page"
|
||||
TornPages = "Torn Page"
|
||||
ValorForm = "Valor Form"
|
||||
WisdomForm = "Wisdom Form"
|
||||
LimitForm = "Limit Form"
|
||||
MasterForm = "Master Form"
|
||||
FinalForm = "Final Form"
|
||||
|
||||
# magic and summons
|
||||
FireElement = "Fire Element"
|
||||
|
||||
BlizzardElement = "Blizzard Element"
|
||||
|
||||
ThunderElement = "Thunder Element"
|
||||
|
||||
CureElement = "Cure Element"
|
||||
|
||||
MagnetElement = "Magnet Element"
|
||||
|
||||
ReflectElement = "Reflect Element"
|
||||
|
||||
Genie = "Genie"
|
||||
PeterPan = "Peter Pan"
|
||||
Stitch = "Stitch"
|
||||
ChickenLittle = "Chicken Little"
|
||||
|
||||
#movement
|
||||
HighJump = "High Jump"
|
||||
|
||||
|
||||
QuickRun = "Quick Run"
|
||||
|
||||
|
||||
AerialDodge = "Aerial Dodge"
|
||||
|
||||
|
||||
Glide = "Glide"
|
||||
|
||||
|
||||
DodgeRoll = "Dodge Roll"
|
||||
|
||||
|
||||
#keyblades
|
||||
Oathkeeper = "Oathkeeper"
|
||||
Oblivion = "Oblivion"
|
||||
StarSeeker = "Star Seeker"
|
||||
HiddenDragon = "Hidden Dragon"
|
||||
HerosCrest = "Hero's Crest"
|
||||
Monochrome = "Monochrome"
|
||||
FollowtheWind = "Follow the Wind"
|
||||
CircleofLife = "Circle of Life"
|
||||
PhotonDebugger = "Photon Debugger"
|
||||
GullWing = "Gull Wing"
|
||||
RumblingRose = "Rumbling Rose"
|
||||
GuardianSoul = "Guardian Soul"
|
||||
WishingLamp = "Wishing Lamp"
|
||||
DecisivePumpkin = "Decisive Pumpkin"
|
||||
SleepingLion = "Sleeping Lion"
|
||||
SweetMemories = "Sweet Memories"
|
||||
MysteriousAbyss = "Mysterious Abyss"
|
||||
TwoBecomeOne = "Two Become One"
|
||||
FatalCrest = "Fatal Crest"
|
||||
BondofFlame = "Bond of Flame"
|
||||
Fenrir = "Fenrir"
|
||||
UltimaWeapon = "Ultima Weapon"
|
||||
WinnersProof = "Winner's Proof"
|
||||
Pureblood = "Pureblood"
|
||||
|
||||
# stafs
|
||||
HammerStaff = "Hammer Staff"
|
||||
LordsBroom = "Lord's Broom"
|
||||
MagesStaff = "Mages Staff"
|
||||
MeteorStaff = "Meteor Staff"
|
||||
CometStaff = "Comet Staff"
|
||||
Centurion2 = "Centurion+"
|
||||
MeteorStaff = "Meteor Staff"
|
||||
NobodyLance = "Nobody Lance"
|
||||
PreciousMushroom = "Precious Mushroom"
|
||||
PreciousMushroom2 = "Precious Mushroom+"
|
||||
PremiumMushroom = "Premium Mushroom"
|
||||
RisingDragon = "Rising Dragon"
|
||||
SaveTheQueen2 = "Save The Queen+"
|
||||
ShamansRelic = "Shaman's Relic"
|
||||
VictoryBell = "Victory Bell"
|
||||
WisdomWand = "Wisdom Wand"
|
||||
# shelds
|
||||
|
||||
AkashicRecord = "Akashic Record"
|
||||
FrozenPride2 = "Frozen Pride+"
|
||||
GenjiShield = "Genji Shield"
|
||||
MajesticMushroom = "Majestic Mushroom"
|
||||
MajesticMushroom2 = "Majestic Mushroom+"
|
||||
NobodyGuard = "Nobody Guard"
|
||||
OgreShield = "Ogre Shield"
|
||||
SaveTheKing2 = "Save The King+"
|
||||
UltimateMushroom = "Ultimate Mushroom"
|
||||
|
||||
# accesrosies
|
||||
AbilityRing = "Ability Ring"
|
||||
EngineersRing = "Engineer's Ring"
|
||||
TechniciansRing = "Technician's Ring"
|
||||
SkillRing = "Skill Ring"
|
||||
SkillfulRing = "Skillful Ring"
|
||||
ExpertsRing = "Expert's Ring"
|
||||
MastersRing = "Master's Ring"
|
||||
CosmicRing = "Cosmic Ring"
|
||||
ExecutivesRing = "Executive's Ring"
|
||||
SardonyxRing = "Sardonyx Ring"
|
||||
TourmalineRing = "Tourmaline Ring"
|
||||
AquamarineRing = "Aquamarine Ring"
|
||||
GarnetRing = "Garnet Ring"
|
||||
DiamondRing = "Diamond Ring"
|
||||
SilverRing = "Silver Ring"
|
||||
GoldRing = "Gold Ring"
|
||||
PlatinumRing = "Platinum Ring"
|
||||
MythrilRing = "Mythril Ring"
|
||||
OrichalcumRing = "Orichalcum Ring"
|
||||
SoldierEarring = "Soldier Earring"
|
||||
FencerEarring = "Fencer Earring"
|
||||
MageEarring = "Mage Earring"
|
||||
SlayerEarring = "Slayer Earring"
|
||||
Medal = "Medal"
|
||||
MoonAmulet = "Moon Amulet"
|
||||
StarCharm = "Star Charm"
|
||||
CosmicArts = "Cosmic Arts"
|
||||
ShadowArchive = "Shadow Archive"
|
||||
ShadowArchive2 = "Shadow Archive+"
|
||||
FullBloom = "Full Bloom"
|
||||
FullBloom2 = "Full Bloom+"
|
||||
DrawRing = "Draw Ring"
|
||||
LuckyRing = "Lucky Ring"
|
||||
|
||||
# armorers
|
||||
ElvenBandana = "Elven Bandana"
|
||||
DivineBandana = "Divine Bandana"
|
||||
ProtectBelt = "Protect Belt"
|
||||
GaiaBelt = "Gaia Belt"
|
||||
PowerBand = "Power Band"
|
||||
BusterBand = "Buster Band"
|
||||
CosmicBelt = "Cosmic Belt"
|
||||
FireBangle = "Fire Bangle"
|
||||
FiraBangle = "Fira Bangle"
|
||||
FiragaBangle = "Firaga Bangle"
|
||||
FiragunBangle = "Firagun Bangle"
|
||||
BlizzardArmlet = "Blizzard Armlet"
|
||||
BlizzaraArmlet = "Blizzara Armlet"
|
||||
BlizzagaArmlet = "Blizzaga Armlet"
|
||||
BlizzagunArmlet = "Blizzagun Armlet"
|
||||
ThunderTrinket = "Thunder Trinket"
|
||||
ThundaraTrinket = "Thundara Trinket"
|
||||
ThundagaTrinket = "Thundaga Trinket"
|
||||
ThundagunTrinket = "Thundagun Trinket"
|
||||
ShockCharm = "Shock Charm"
|
||||
ShockCharm2 = "Shock Charm+"
|
||||
ShadowAnklet = "Shadow Anklet"
|
||||
DarkAnklet = "Dark Anklet"
|
||||
MidnightAnklet = "Midnight Anklet"
|
||||
ChaosAnklet = "Chaos Anklet"
|
||||
ChampionBelt = "Champion Belt"
|
||||
AbasChain = "Abas Chain"
|
||||
AegisChain = "Aegis Chain"
|
||||
Acrisius = "Acrisius"
|
||||
Acrisius2 = "Acrisius+"
|
||||
CosmicChain = "Cosmic Chain"
|
||||
PetiteRibbon = "Petite Ribbon"
|
||||
Ribbon = "Ribbon"
|
||||
GrandRibbon = "Grand Ribbon"
|
||||
|
||||
# usefull and stat incre
|
||||
MickyMunnyPouch = "Mickey Munny Pouch"
|
||||
OletteMunnyPouch = "Olette Munny Pouch"
|
||||
HadesCupTrophy = "Hades Cup Trophy"
|
||||
UnknownDisk = "Unknown Disk"
|
||||
OlympusStone = "Olympus Stone"
|
||||
MaxHPUp = "Max HP Up"
|
||||
MaxMPUp = "Max MP Up"
|
||||
DriveGaugeUp = "Drive Gauge Up"
|
||||
ArmorSlotUp = "Armor Slot Up"
|
||||
AccessorySlotUp = "Accessory Slot Up"
|
||||
ItemSlotUp = "Item Slot Up"
|
||||
|
||||
# support abilitys
|
||||
Scan = "Scan"
|
||||
AerialRecovery = "Aerial Recovery"
|
||||
ComboMaster = "Combo Master"
|
||||
ComboPlus = "Combo Plus"
|
||||
AirComboPlus = "Air Combo Plus"
|
||||
ComboBoost = "Combo Boost"
|
||||
AirComboBoost = "Air Combo Boost"
|
||||
ReactionBoost = "Reaction Boost"
|
||||
FinishingPlus = "Finishing Plus"
|
||||
NegativeCombo = "Negative Combo"
|
||||
BerserkCharge = "Berserk Charge"
|
||||
DamageDrive = "Damage Drive"
|
||||
DriveBoost = "Drive Boost"
|
||||
FormBoost = "Form Boost"
|
||||
SummonBoost = "Summon Boost"
|
||||
ExperienceBoost = "Experience Boost"
|
||||
Draw = "Draw"
|
||||
Jackpot = "Jackpot"
|
||||
LuckyLucky = "Lucky Lucky"
|
||||
DriveConverter = "Drive Converter"
|
||||
FireBoost = "Fire Boost"
|
||||
BlizzardBoost = "Blizzard Boost"
|
||||
ThunderBoost = "Thunder Boost"
|
||||
ItemBoost = "Item Boost"
|
||||
MPRage = "MP Rage"
|
||||
MPHaste = "MP Haste"
|
||||
MPHastera = "MP Hastera"
|
||||
MPHastega = "MP Hastega"
|
||||
Defender = "Defender"
|
||||
DamageControl = "Damage Control"
|
||||
NoExperience = "No Experience"
|
||||
LightDarkness = "Light & Darkness"
|
||||
|
||||
# level ability
|
||||
MagicLock = "Magic Lock-On"
|
||||
LeafBracer = "Leaf Bracer"
|
||||
CombinationBoost = "Combination Boost"
|
||||
DamageDrive = "Damage Drive"
|
||||
OnceMore = "Once More"
|
||||
SecondChance = "Second Chance"
|
||||
|
||||
# action abilitys
|
||||
Guard = "Guard"
|
||||
UpperSlash = "Upper Slash"
|
||||
HorizontalSlash = "Horizontal Slash"
|
||||
FinishingLeap = "Finishing Leap"
|
||||
RetaliatingSlash = "Retaliating Slash"
|
||||
Slapshot = "Slapshot"
|
||||
DodgeSlash = "Dodge Slash"
|
||||
FlashStep = "Flash Step"
|
||||
SlideDash = "Slide Dash"
|
||||
VicinityBreak = "Vicinity Break"
|
||||
GuardBreak = "Guard Break"
|
||||
Explosion = "Explosion"
|
||||
AerialSweep = "Aerial Sweep"
|
||||
AerialDive = "Aerial Dive"
|
||||
AerialSpiral = "Aerial Spiral"
|
||||
AerialFinish = "Aerial Finish"
|
||||
MagnetBurst = "Magnet Burst"
|
||||
Counterguard = "Counterguard"
|
||||
AutoValor = "Auto Valor"
|
||||
AutoWisdom = "Auto Wisdom"
|
||||
AutoLimit = "Auto Limit"
|
||||
AutoMaster = "Auto Master"
|
||||
AutoFinal = "Auto Final"
|
||||
AutoSummon = "Auto Summon"
|
||||
TrinityLimit = "Trinity Limit"
|
||||
|
||||
# items
|
||||
Potion = "Potion"
|
||||
HiPotion = "Hi-Potion"
|
||||
Ether = "Ether"
|
||||
Elixir = "Elixir"
|
||||
MegaPotion = "Mega-Potion"
|
||||
MegaEther = "Mega-Ether"
|
||||
Megalixir = "Megalixir"
|
||||
Tent = "Tent"
|
||||
DriveRecovery = "Drive Recovery"
|
||||
HighDriveRecovery = "High Drive Recovery"
|
||||
PowerBoost = "Power Boost"
|
||||
MagicBoost = "Magic Boost"
|
||||
DefenseBoost = "Defense Boost"
|
||||
APBoost = "AP Boost"
|
||||
|
||||
# donald abilitys
|
||||
DonaldFire = "Donald Fire"
|
||||
DonaldBlizzard = "Donald Blizzard"
|
||||
DonaldThunder = "Donald Thunder"
|
||||
DonaldCure = "Donald Cure"
|
||||
Fantasia = "Donald Fantasia"
|
||||
FlareForce = "Donald Flare Force"
|
||||
DonaldMPRage = "Donald MP Rage"
|
||||
DonaldJackpot = "Donald Jackpot"
|
||||
DonaldLuckyLucky = "Donald Lucky Lucky"
|
||||
DonaldFireBoost = "Donald Fire Boost"
|
||||
DonaldBlizzardBoost = "Donald Blizzard Boost"
|
||||
DonaldThunderBoost = "Donald Thunder Boost"
|
||||
DonaldFireBoost = "Donald Fire Boost"
|
||||
DonaldBlizzardBoost = "Donald Blizzard Boost"
|
||||
DonaldThunderBoost = "Donald Thunder Boost"
|
||||
DonaldMPRage = "Donald MP Rage"
|
||||
DonaldMPHastera = "Donald MP Hastera"
|
||||
DonaldAutoLimit = "Donald Auto Limit"
|
||||
DonaldHyperHealing = "Donald Hyper Healing"
|
||||
DonaldAutoHealing = "Donald Auto Healing"
|
||||
DonaldMPHastega = "Donald MP Hastega"
|
||||
DonaldItemBoost = "Donald Item Boost"
|
||||
DonaldDamageControl = "Donald Damage Control"
|
||||
DonaldHyperHealing = "Donald Hyper Healing"
|
||||
DonaldMPRage = "Donald MP Rage"
|
||||
DonaldMPHaste = "Donald MP Haste"
|
||||
DonaldMPHastera = "Donald MP Hastera"
|
||||
DonaldMPHastega = "Donald MP Hastega"
|
||||
DonaldMPHaste = "Donald MP Haste"
|
||||
DonaldDamageControl = "Donald Damage Control"
|
||||
DonaldMPHastera = "Donald MP Hastera"
|
||||
DonaldDraw = "Donald Draw"
|
||||
|
||||
# goofy abili
|
||||
GoofyTornado = "Goofy Tornado"
|
||||
GoofyTurbo = "Goofy Turbo"
|
||||
GoofyBash = "Goofy Bash"
|
||||
TornadoFusion = "Tornado Fusion"
|
||||
Teamwork = "Teamwork"
|
||||
GoofyDraw = "Goofy Draw"
|
||||
GoofyJackpot = "Goofy Jackpot"
|
||||
GoofyLuckyLucky = "Goofy Lucky Lucky"
|
||||
GoofyItemBoost = "Goofy Item Boost"
|
||||
GoofyMPRage = "Goofy MP Rage"
|
||||
GoofyDefender = "Goofy Defender"
|
||||
GoofyDamageControl = "Goofy Damage Control"
|
||||
GoofyAutoLimit = "Goofy Auto Limit"
|
||||
GoofySecondChance = "Goofy Second Chance"
|
||||
GoofyOnceMore = "Goofy Once More"
|
||||
GoofyAutoChange = "Goofy Auto Change"
|
||||
GoofyHyperHealing = "Goofy Hyper Healing"
|
||||
GoofyAutoHealing = "Goofy Auto Healing"
|
||||
GoofyDefender = "Goofy Defender"
|
||||
GoofyHyperHealing = "Goofy Hyper Healing"
|
||||
GoofyMPHaste = "Goofy MP Haste"
|
||||
GoofyMPHastera = "Goofy MP Hastera"
|
||||
GoofyMPRage = "Goofy MP Rage"
|
||||
GoofyMPHastega = "Goofy MP Hastega"
|
||||
GoofyItemBoost = "Goofy Item Boost"
|
||||
GoofyDamageControl = "Goofy Damage Control"
|
||||
GoofyProtect = "Goofy Protect"
|
||||
GoofyProtera = "Goofy Protera"
|
||||
GoofyProtega = "Goofy Protega"
|
||||
GoofyDamageControl = "Goofy Damage Control"
|
||||
GoofyProtect = "Goofy Protect"
|
||||
GoofyProtera = "Goofy Protera"
|
||||
GoofyProtega = "Goofy Protega"
|
||||
|
||||
Victory = "Victory"
|
||||
LuckyEmblem = "Lucky Emblem"
|
||||
Bounty="Bounty"
|
||||
|
||||
UniversalKey="Universal Key"
|
||||
# Keyblade Slots
|
||||
FAKESlot = "FAKE (Slot)"
|
||||
DetectionSaberSlot = "Detection Saber (Slot)"
|
||||
EdgeofUltimaSlot = "Edge of Ultima (Slot)"
|
||||
KingdomKeySlot = "Kingdom Key (Slot)"
|
||||
OathkeeperSlot = "Oathkeeper (Slot)"
|
||||
OblivionSlot = "Oblivion (Slot)"
|
||||
StarSeekerSlot = "Star Seeker (Slot)"
|
||||
HiddenDragonSlot = "Hidden Dragon (Slot)"
|
||||
HerosCrestSlot = "Hero's Crest (Slot)"
|
||||
MonochromeSlot = "Monochrome (Slot)"
|
||||
FollowtheWindSlot = "Follow the Wind (Slot)"
|
||||
CircleofLifeSlot = "Circle of Life (Slot)"
|
||||
PhotonDebuggerSlot = "Photon Debugger (Slot)"
|
||||
GullWingSlot = "Gull Wing (Slot)"
|
||||
RumblingRoseSlot = "Rumbling Rose (Slot)"
|
||||
GuardianSoulSlot = "Guardian Soul (Slot)"
|
||||
WishingLampSlot = "Wishing Lamp (Slot)"
|
||||
DecisivePumpkinSlot = "Decisive Pumpkin (Slot)"
|
||||
SweetMemoriesSlot = "Sweet Memories (Slot)"
|
||||
MysteriousAbyssSlot = "Mysterious Abyss (Slot)"
|
||||
SleepingLionSlot = "Sleeping Lion (Slot)"
|
||||
BondofFlameSlot = "Bond of Flame (Slot)"
|
||||
TwoBecomeOneSlot = "Two Become One (Slot)"
|
||||
FatalCrestSlot = "Fatal Crest (Slot)"
|
||||
FenrirSlot = "Fenrir (Slot)"
|
||||
UltimaWeaponSlot = "Ultima Weapon (Slot)"
|
||||
WinnersProofSlot = "Winner's Proof (Slot)"
|
|
@ -0,0 +1,763 @@
|
|||
BambooGroveDarkShard = "(LoD) Bamboo Grove Dark Shard"
|
||||
BambooGroveEther = "(LoD) Bamboo Grove Ether"
|
||||
BambooGroveMythrilShard = "(LoD) Bamboo Grove Mythril Shard"
|
||||
EncampmentAreaMap = "(LoD) Bamboo Grove Encampment Area Map"
|
||||
Mission3 = "(LoD) Mission 3"
|
||||
CheckpointHiPotion = "(LoD) Checkpoint Hi-Potion"
|
||||
CheckpointMythrilShard = "(LoD) Checkpoint Mythril Shard"
|
||||
MountainTrailLightningShard = "(LoD) Mountain Trail Lightning Shard"
|
||||
MountainTrailRecoveryRecipe = "(LoD) Mountain Trail Recovery Recipe"
|
||||
MountainTrailEther = "(LoD) Mountain Trail Ether"
|
||||
MountainTrailMythrilShard = "(LoD) Mountain Trail Mythril Shard"
|
||||
VillageCaveAreaMap = "(LoD) Village Cave Area Map"
|
||||
VillageCaveAPBoost = "(LoD) Village Cave AP Boost"
|
||||
VillageCaveDarkShard = "(LoD) Village Cave Dark Shard"
|
||||
VillageCaveBonus = "(LoD) Village Cave Bonus: Sora Slot 1"
|
||||
RidgeFrostShard = "(LoD) Ridge Frost Shard"
|
||||
RidgeAPBoost = "(LoD) Ridge AP Boost"
|
||||
ShanYu = "(LoD) Shan-Yu Bonus: Sora Slot 1"
|
||||
ShanYuGetBonus = "(LoD) Shan-Yu Bonus: Sora Slot 2"
|
||||
HiddenDragon = "(LoD) Hidden Dragon"
|
||||
ThroneRoomTornPages = "(LoD2) Throne Room Torn Pages"
|
||||
ThroneRoomPalaceMap = "(LoD2) Throne Room Palace Map"
|
||||
ThroneRoomAPBoost = "(LoD2) Throne Room AP Boost"
|
||||
ThroneRoomQueenRecipe = "(LoD2) Throne Room Queen Recipe"
|
||||
ThroneRoomAPBoost2 = "(LoD2) Throne Room AP Boost 2"
|
||||
ThroneRoomOgreShield = "(LoD2) Throne Room Ogre Shield"
|
||||
ThroneRoomMythrilCrystal = "(LoD2) Throne Room Mythril Crystal"
|
||||
ThroneRoomOrichalcum = "(LoD2) Throne Room Orichalcum"
|
||||
StormRider = "(LoD2) Storm Rider Bonus: Sora Slot 1"
|
||||
XigbarDataDefenseBoost = "Data Xigbar"
|
||||
|
||||
AgrabahMap = "(AG) Agrabah Map"
|
||||
AgrabahDarkShard = "(AG) Agrabah Dark Shard"
|
||||
AgrabahMythrilShard = "(AG) Agrabah Mythril Shard"
|
||||
AgrabahHiPotion = "(AG) Agrabah Hi-Potion"
|
||||
AgrabahAPBoost = "(AG) Agrabah AP Boost"
|
||||
AgrabahMythrilStone = "(AG) Agrabah Mythril Stone"
|
||||
AgrabahMythrilShard2 = "(AG) Agrabah Mythril Shard 2"
|
||||
AgrabahSerenityShard = "(AG) Agrabah Serenity Shard"
|
||||
BazaarMythrilGem = "(AG) Bazaar Mythril Gem"
|
||||
BazaarPowerShard = "(AG) Bazaar Power Shard"
|
||||
BazaarHiPotion = "(AG) Bazaar Hi-Potion"
|
||||
BazaarAPBoost = "(AG) Bazaar AP Boost"
|
||||
BazaarMythrilShard = "(AG) Bazaar Mythril Shard"
|
||||
PalaceWallsSkillRing = "(AG) Palace Walls Skill Ring"
|
||||
PalaceWallsMythrilStone = "(AG) Palace Walls Mythril Stone"
|
||||
CaveEntrancePowerStone = "(AG) Cave Entrance Power Stone"
|
||||
CaveEntranceMythrilShard = "(AG) Cave Entrance Mythril Shard"
|
||||
ValleyofStoneMythrilStone = "(AG) Valley of Stone Mythril Stone"
|
||||
ValleyofStoneAPBoost = "(AG) Valley of Stone AP Boost"
|
||||
ValleyofStoneMythrilShard = "(AG) Valley of Stone Mythril Shard"
|
||||
ValleyofStoneHiPotion = "(AG) Valley of Stone Hi-Potion"
|
||||
AbuEscort = "(AG) Abu Escort Bonus: Sora Slot 1"
|
||||
ChasmofChallengesCaveofWondersMap = "(AG) Chasm of Challenges Cave of Wonders Map"
|
||||
ChasmofChallengesAPBoost = "(AG) Chasm of Challenges AP Boost"
|
||||
TreasureRoom = "(AG) Treasure Room"
|
||||
TreasureRoomAPBoost = "(AG) Treasure Room AP Boost"
|
||||
TreasureRoomSerenityGem = "(AG) Treasure Room Serenity Gem"
|
||||
ElementalLords = "(AG) Elemental Lords Bonus: Sora Slot 1"
|
||||
LampCharm = "(AG) Lamp Charm"
|
||||
RuinedChamberTornPages = "(AG2) Ruined Chamber Torn Pages"
|
||||
RuinedChamberRuinsMap = "(AG2) Ruined Chamber Ruins Map"
|
||||
GenieJafar = "(AG2) Genie Jafar"
|
||||
WishingLamp = "(AG2) Wishing Lamp"
|
||||
LexaeusBonus = "Lexaeus Bonus: Sora Slot 1"
|
||||
LexaeusASStrengthBeyondStrength = "AS Lexaeus"
|
||||
LexaeusDataLostIllusion = "Data Lexaeus"
|
||||
DCCourtyardMythrilShard = "(DC) Courtyard Mythril Shard"
|
||||
DCCourtyardStarRecipe = "(DC) Courtyard Star Recipe"
|
||||
DCCourtyardAPBoost = "(DC) Courtyard AP Boost"
|
||||
DCCourtyardMythrilStone = "(DC) Courtyard Mythril Stone"
|
||||
DCCourtyardBlazingStone = "(DC) Courtyard Blazing Stone"
|
||||
DCCourtyardBlazingShard = "(DC) Courtyard Blazing Shard"
|
||||
DCCourtyardMythrilShard2 = "(DC) Courtyard Mythril Shard 2"
|
||||
LibraryTornPages = "(DC) Library Torn Pages"
|
||||
DisneyCastleMap = "(DC) Disney Castle Map"
|
||||
MinnieEscort = "(DC) Minnie Escort Bonus: Sora Slot 1"
|
||||
MinnieEscortGetBonus = "(DC) Minnie Escort Bonus: Sora Slot 2"
|
||||
CornerstoneHillMap = "(TR) Cornerstone Hill Map"
|
||||
CornerstoneHillFrostShard = "(TR) Cornerstone Hill Frost Shard"
|
||||
PierMythrilShard = "(TR) Pier Mythril Shard"
|
||||
PierHiPotion = "(TR) Pier Hi-Potion"
|
||||
WaterwayMythrilStone = "(TR) Waterway Mythril Stone"
|
||||
WaterwayAPBoost = "(TR) Waterway AP Boost"
|
||||
WaterwayFrostStone = "(TR) Waterway Frost Stone"
|
||||
WindowofTimeMap = "(TR) Window of Time Map"
|
||||
BoatPete = "(TR) Boat Pete Bonus: Sora Slot 1"
|
||||
FuturePete = "(TR) Future Pete Bonus: Sora Slot 1"
|
||||
FuturePeteGetBonus = "(TR) Future Pete Bonus: Sora Slot 2"
|
||||
Monochrome = "(TR) Monochrome"
|
||||
WisdomForm = "(TR) Wisdom Form"
|
||||
MarluxiaGetBonus = "Marluxia Bonus: Sora Slot 1"
|
||||
MarluxiaASEternalBlossom = "AS Marluxia"
|
||||
MarluxiaDataLostIllusion = "Data Marluxia"
|
||||
LingeringWillBonus = "Lingering Will Bonus: Sora Slot 1"
|
||||
LingeringWillProofofConnection = "Lingering Will Proof of Connection"
|
||||
LingeringWillManifestIllusion = "Lingering Will Manifest Illusion"
|
||||
PoohsHouse100AcreWoodMap = "(100Acre) Pooh's House 100 Acre Wood Map"
|
||||
PoohsHouseAPBoost = "(100Acre) Pooh's House AP Boost"
|
||||
PoohsHouseMythrilStone = "(100Acre) Pooh's House Mythril Stone"
|
||||
PigletsHouseDefenseBoost = "(100Acre) Piglet's House Defense Boost"
|
||||
PigletsHouseAPBoost = "(100Acre) Piglet's House AP Boost"
|
||||
PigletsHouseMythrilGem = "(100Acre) Piglet's House Mythril Gem"
|
||||
RabbitsHouseDrawRing = "(100Acre) Rabbit's House Draw Ring"
|
||||
RabbitsHouseMythrilCrystal = "(100Acre) Rabbit's House Mythril Crystal"
|
||||
RabbitsHouseAPBoost = "(100Acre) Rabbit's House AP Boost"
|
||||
KangasHouseMagicBoost = "(100Acre) Kanga's House Magic Boost"
|
||||
KangasHouseAPBoost = "(100Acre) Kanga's House AP Boost"
|
||||
KangasHouseOrichalcum = "(100Acre) Kanga's House Orichalcum"
|
||||
SpookyCaveMythrilGem = "(100Acre) Spooky Cave Mythril Gem"
|
||||
SpookyCaveAPBoost = "(100Acre) Spooky Cave AP Boost"
|
||||
SpookyCaveOrichalcum = "(100Acre) Spooky Cave Orichalcum"
|
||||
SpookyCaveGuardRecipe = "(100Acre) Spooky Cave Guard Recipe"
|
||||
SpookyCaveMythrilCrystal = "(100Acre) Spooky Cave Mythril Crystal"
|
||||
SpookyCaveAPBoost2 = "(100Acre) Spooky Cave AP Boost 2"
|
||||
SweetMemories = "(100Acre) Sweet Memories"
|
||||
SpookyCaveMap = "(100Acre) Spooky Cave Map"
|
||||
StarryHillCosmicRing = "(100Acre) Starry Hill Cosmic Ring"
|
||||
StarryHillStyleRecipe = "(100Acre) Starry Hill Style Recipe"
|
||||
StarryHillCureElement = "(100Acre) Starry Hill Cure Element"
|
||||
StarryHillOrichalcumPlus = "(100Acre) Starry Hill Orichalcum+"
|
||||
PassageMythrilShard = "(OC) Passage Mythril Shard"
|
||||
PassageMythrilStone = "(OC) Passage Mythril Stone"
|
||||
PassageEther = "(OC) Passage Ether"
|
||||
PassageAPBoost = "(OC) Passage AP Boost"
|
||||
PassageHiPotion = "(OC) Passage Hi-Potion"
|
||||
InnerChamberUnderworldMap = "(OC) Inner Chamber Underworld Map"
|
||||
InnerChamberMythrilShard = "(OC) Inner Chamber Mythril Shard"
|
||||
Cerberus = "(OC) Cerberus Bonus: Sora Slot 1"
|
||||
ColiseumMap = "(OC) Coliseum Map"
|
||||
Urns = "(OC) Urns Bonus: Sora Slot 1"
|
||||
UnderworldEntrancePowerBoost = "(OC) Underworld Entrance Power Boost"
|
||||
CavernsEntranceLucidShard = "(OC) Caverns Entrance Lucid Shard"
|
||||
CavernsEntranceAPBoost = "(OC) Caverns Entrance AP Boost"
|
||||
CavernsEntranceMythrilShard = "(OC) Caverns Entrance Mythril Shard"
|
||||
TheLostRoadBrightShard = "(OC) The Lost Road Bright Shard"
|
||||
TheLostRoadEther = "(OC) The Lost Road Ether"
|
||||
TheLostRoadMythrilShard = "(OC) The Lost Road Mythril Shard"
|
||||
TheLostRoadMythrilStone = "(OC) The Lost Road Mythril Stone"
|
||||
AtriumLucidStone = "(OC) Atrium Lucid Stone"
|
||||
AtriumAPBoost = "(OC) Atrium AP Boost"
|
||||
DemyxOC = "(OC) Demyx Bonus: Sora Slot 1"
|
||||
SecretAnsemReport5 = "(OC) Secret Ansem Report 5 (Demyx)"
|
||||
OlympusStone = "(OC) Olympus Stone"
|
||||
TheLockCavernsMap = "(OC) The Lock Caverns Map"
|
||||
TheLockMythrilShard = "(OC) The Lock Mythril Shard"
|
||||
TheLockAPBoost = "(OC) The Lock AP Boost"
|
||||
PeteOC = "(OC) Pete OC Bonus: Sora Slot 1"
|
||||
Hydra = "(OC) Hydra Bonus: Sora Slot 1"
|
||||
HydraGetBonus = "(OC) Hydra Bonus: Sora Slot 2"
|
||||
HerosCrest = "(OC) Hero's Crest"
|
||||
AuronsStatue = "(OC2) Auron's Statue"
|
||||
Hades = "(OC2) Hades Bonus: Sora Slot 1"
|
||||
HadesGetBonus = "(OC2) Hades Bonus: Sora Slot 2"
|
||||
GuardianSoul = "(OC2) Guardian Soul"
|
||||
ProtectBeltPainandPanicCup = "Protect Belt Pain and Panic Cup"
|
||||
SerenityGemPainandPanicCup = "Serenity Gem Pain and Panic Cup"
|
||||
RisingDragonCerberusCup = "Rising Dragon Cerberus Cup"
|
||||
SerenityCrystalCerberusCup = "Serenity Crystal Cerberus Cup"
|
||||
GenjiShieldTitanCup = "Genji Shield Titan Cup"
|
||||
SkillfulRingTitanCup = "Skillful Ring Titan Cup"
|
||||
FatalCrestGoddessofFateCup = "Fatal Crest Goddess of Fate Cup"
|
||||
OrichalcumPlusGoddessofFateCup = "Orichalcum+ Goddess of Fate Cup"
|
||||
HadesCupTrophyParadoxCups = "Hades Cup Trophy Paradox Cups"
|
||||
ZexionBonus = "Zexion Bonus: Sora Slot 1"
|
||||
ZexionASBookofShadows = "AS Zexion"
|
||||
ZexionDataLostIllusion = "Data Zexion"
|
||||
|
||||
|
||||
BCCourtyardAPBoost = "(BC) Courtyard AP Boost"
|
||||
BCCourtyardHiPotion = "(BC) Courtyard Hi-Potion"
|
||||
BCCourtyardMythrilShard = "(BC) Courtyard Mythril Shard"
|
||||
BellesRoomCastleMap = "(BC) Belle's Room Castle Map"
|
||||
BellesRoomMegaRecipe = "(BC) Belle's Room Mega-Recipe"
|
||||
TheEastWingMythrilShard = "(BC) The East Wing Mythril Shard"
|
||||
TheEastWingTent = "(BC) The East Wing Tent"
|
||||
TheWestHallHiPotion = "(BC) The West Hall Hi-Potion"
|
||||
TheWestHallPowerShard = "(BC) The West Hall Power Shard"
|
||||
TheWestHallMythrilShard2 = "(BC) The West Hall Mythril Shard 2"
|
||||
TheWestHallBrightStone = "(BC) The West Hall Bright Stone"
|
||||
TheWestHallMythrilShard = "(BC) The West Hall Mythril Shard"
|
||||
Thresholder = "(BC) Thresholder Bonus: Sora Slot 1"
|
||||
DungeonBasementMap = "(BC) Dungeon Basement Map"
|
||||
DungeonAPBoost = "(BC) Dungeon AP Boost"
|
||||
SecretPassageMythrilShard = "(BC) Secret Passage Mythril Shard"
|
||||
SecretPassageHiPotion = "(BC) Secret Passage Hi-Potion"
|
||||
SecretPassageLucidShard = "(BC) Secret Passage Lucid Shard"
|
||||
TheWestHallAPBoostPostDungeon = "(BC) The West Hall AP Boost Post Dungeon"
|
||||
TheWestWingMythrilShard = "(BC) The West Wing Mythril Shard"
|
||||
TheWestWingTent = "(BC) The West Wing Tent"
|
||||
Beast = "(BC) Beast Bonus: Sora Slot 1"
|
||||
TheBeastsRoomBlazingShard = "(BC) The Beast's Room Blazing Shard"
|
||||
DarkThorn = "(BC) Dark Thorn Bonus: Sora Slot 1"
|
||||
DarkThornGetBonus = "(BC) Dark Thorn Bonus: Sora Slot 2"
|
||||
DarkThornCureElement = "(BC) Dark Thorn Cure Element"
|
||||
RumblingRose = "(BC2) Rumbling Rose"
|
||||
CastleWallsMap = "(BC2) Castle Walls Map"
|
||||
Xaldin = "(BC2) Xaldin Bonus: Sora Slot 1"
|
||||
XaldinGetBonus = "(BC2) Xaldin Bonus: Sora Slot 2"
|
||||
SecretAnsemReport4 = "(BC2) Secret Ansem Report 4 (Xaldin)"
|
||||
XaldinDataDefenseBoost = "Data Xaldin"
|
||||
|
||||
|
||||
|
||||
PitCellAreaMap = "(SP) Pit Cell Area Map"
|
||||
PitCellMythrilCrystal = "(SP) Pit Cell Mythril Crystal"
|
||||
CanyonDarkCrystal = "(SP) Canyon Dark Crystal"
|
||||
CanyonMythrilStone = "(SP) Canyon Mythril Stone"
|
||||
CanyonMythrilGem = "(SP) Canyon Mythril Gem"
|
||||
CanyonFrostCrystal = "(SP) Canyon Frost Crystal"
|
||||
Screens = "(SP) Screens Bonus: Sora Slot 1"
|
||||
HallwayPowerCrystal = "(SP) Hallway Power Crystal"
|
||||
HallwayAPBoost = "(SP) Hallway AP Boost"
|
||||
CommunicationsRoomIOTowerMap = "(SP) Communications Room I/O Tower Map"
|
||||
CommunicationsRoomGaiaBelt = "(SP) Communications Room Gaia Belt"
|
||||
HostileProgram = "(SP) Hostile Program Bonus: Sora Slot 1"
|
||||
HostileProgramGetBonus = "(SP) Hostile Program Bonus: Sora Slot 2"
|
||||
PhotonDebugger = "(SP) Photon Debugger"
|
||||
SolarSailer = "(SP2) Solar Sailer"
|
||||
CentralComputerCoreAPBoost = "(SP2) Central Computer Core AP Boost"
|
||||
CentralComputerCoreOrichalcumPlus = "(SP2) Central Computer Core Orichalcum+"
|
||||
CentralComputerCoreCosmicArts = "(SP2) Central Computer Core Cosmic Arts"
|
||||
CentralComputerCoreMap = "(SP2) Central Computer Core Map"
|
||||
MCP = "(SP2) MCP Bonus: Sora Slot 1"
|
||||
MCPGetBonus = "(SP2) MCP Bonus: Sora Slot 2"
|
||||
LarxeneBonus = "Larxene Bonus: Sora Slot 1"
|
||||
LarxeneASCloakedThunder = "AS Larxene"
|
||||
LarxeneDataLostIllusion = "Data Larxene"
|
||||
|
||||
GraveyardMythrilShard = "(HT) Graveyard Mythril Shard"
|
||||
GraveyardSerenityGem = "(HT) Graveyard Serenity Gem"
|
||||
FinklesteinsLabHalloweenTownMap = "(HT) Finklestein's Lab Halloween Town Map"
|
||||
TownSquareMythrilStone = "(HT) Town Square Mythril Stone"
|
||||
TownSquareEnergyShard = "(HT) Town Square Energy Shard"
|
||||
HinterlandsLightningShard = "(HT) Hinterlands Lightning Shard"
|
||||
HinterlandsMythrilStone = "(HT) Hinterlands Mythril Stone"
|
||||
HinterlandsAPBoost = "(HT) Hinterlands AP Boost"
|
||||
CandyCaneLaneMegaPotion = "(HT) Candy Cane Lane Mega-Potion"
|
||||
CandyCaneLaneMythrilGem = "(HT) Candy Cane Lane Mythril Gem"
|
||||
CandyCaneLaneLightningStone = "(HT) Candy Cane Lane Lightning Stone"
|
||||
CandyCaneLaneMythrilStone = "(HT) Candy Cane Lane Mythril Stone"
|
||||
SantasHouseChristmasTownMap = "(HT) Santa's House Christmas Town Map"
|
||||
SantasHouseAPBoost = "(HT) Santa's House AP Boost"
|
||||
PrisonKeeper = "(HT) Prison Keeper Bonus: Sora Slot 1"
|
||||
OogieBoogie = "(HT) Oogie Boogie Bonus: Sora Slot 1"
|
||||
OogieBoogieMagnetElement = "(HT) Oogie Boogie Magnet Element"
|
||||
Lock = "(HT2) Lock, Shock and Barrel Bonus: Sora Slot 1"
|
||||
Present = "(HT2) Present"
|
||||
DecoyPresents = "(HT2) Decoy Presents"
|
||||
Experiment = "(HT2) Experiment Bonus: Sora Slot 1"
|
||||
DecisivePumpkin = "(HT2) Decisive Pumpkin"
|
||||
VexenBonus = "Vexen Bonus: Sora Slot 1"
|
||||
VexenASRoadtoDiscovery = "AS Vexen"
|
||||
VexenDataLostIllusion = "Data Vexen"
|
||||
|
||||
RampartNavalMap = "(PR) Rampart Naval Map"
|
||||
RampartMythrilStone = "(PR) Rampart Mythril Stone"
|
||||
RampartDarkShard = "(PR) Rampart Dark Shard"
|
||||
TownDarkStone = "(PR) Town Dark Stone"
|
||||
TownAPBoost = "(PR) Town AP Boost"
|
||||
TownMythrilShard = "(PR) Town Mythril Shard"
|
||||
TownMythrilGem = "(PR) Town Mythril Gem"
|
||||
CaveMouthBrightShard = "(PR) Cave Mouth Bright Shard"
|
||||
CaveMouthMythrilShard = "(PR) Cave Mouth Mythril Shard"
|
||||
IsladeMuertaMap = "(PR) Isla de Muerta Map"
|
||||
BoatFight = "(PR) Boat Fight Bonus: Sora Slot 1"
|
||||
InterceptorBarrels = "(PR) Interceptor Barrels Bonus: Sora Slot 1"
|
||||
PowderStoreAPBoost1 = "(PR) Powder Store AP Boost 1"
|
||||
PowderStoreAPBoost2 = "(PR) Powder Store AP Boost 2"
|
||||
MoonlightNookMythrilShard = "(PR) Moonlight Nook Mythril Shard"
|
||||
MoonlightNookSerenityGem = "(PR) Moonlight Nook Serenity Gem"
|
||||
MoonlightNookPowerStone = "(PR) Moonlight Nook Power Stone"
|
||||
Barbossa = "(PR) Barbossa Bonus: Sora Slot 1"
|
||||
BarbossaGetBonus = "(PR) Barbossa Bonus: Sora Slot 2"
|
||||
FollowtheWind = "(PR) Follow the Wind"
|
||||
GrimReaper1 = "(PR2) Grim Reaper 1 Bonus: Sora Slot 1"
|
||||
InterceptorsHoldFeatherCharm = "(PR2) Interceptor's Hold Feather Charm"
|
||||
SeadriftKeepAPBoost = "(PR2) Seadrift Keep AP Boost"
|
||||
SeadriftKeepOrichalcum = "(PR2) Seadrift Keep Orichalcum"
|
||||
SeadriftKeepMeteorStaff = "(PR2) Seadrift Keep Meteor Staff"
|
||||
SeadriftRowSerenityGem = "(PR2) Seadrift Row Serenity Gem"
|
||||
SeadriftRowKingRecipe = "(PR2) Seadrift Row King Recipe"
|
||||
SeadriftRowMythrilCrystal = "(PR2) Seadrift Row Mythril Crystal"
|
||||
SeadriftRowCursedMedallion = "(PR2) Seadrift Row Cursed Medallion"
|
||||
SeadriftRowShipGraveyardMap = "(PR2) Seadrift Row Ship Graveyard Map"
|
||||
GrimReaper2 = "(PR2) Grim Reaper 2 Bonus: Sora Slot 1"
|
||||
SecretAnsemReport6 = "(PR2) Secret Ansem Report 6 (Grim Reaper 2)"
|
||||
|
||||
LuxordDataAPBoost = "Data Luxord"
|
||||
|
||||
MarketplaceMap = "(HB) Marketplace Map"
|
||||
BoroughDriveRecovery = "(HB) Borough Drive Recovery"
|
||||
BoroughAPBoost = "(HB) Borough AP Boost"
|
||||
BoroughHiPotion = "(HB) Borough Hi-Potion"
|
||||
BoroughMythrilShard = "(HB) Borough Mythril Shard"
|
||||
BoroughDarkShard = "(HB) Borough Dark Shard"
|
||||
MerlinsHouseMembershipCard = "(HB) Merlin's House Membership Card"
|
||||
MerlinsHouseBlizzardElement = "(HB) Merlin's House Blizzard Element"
|
||||
Bailey = "(HB) Bailey Bonus: Sora Slot 1"
|
||||
BaileySecretAnsemReport7 = "(HB) Bailey Secret Ansem Report 7"
|
||||
BaseballCharm = "(HB) Baseball Charm"
|
||||
PosternCastlePerimeterMap = "(HB2) Postern Castle Perimeter Map"
|
||||
PosternMythrilGem = "(HB2) Postern Mythril Gem"
|
||||
PosternAPBoost = "(HB2) Postern AP Boost"
|
||||
CorridorsMythrilStone = "(HB2) Corridors Mythril Stone"
|
||||
CorridorsMythrilCrystal = "(HB2) Corridors Mythril Crystal"
|
||||
CorridorsDarkCrystal = "(HB2) Corridors Dark Crystal"
|
||||
CorridorsAPBoost = "(HB2) Corridors AP Boost"
|
||||
AnsemsStudyMasterForm = "(HB2) Ansem's Study Master Form"
|
||||
AnsemsStudySleepingLion = "(HB2) Ansem's Study Sleeping Lion"
|
||||
AnsemsStudySkillRecipe = "(HB2) Ansem's Study Skill Recipe"
|
||||
AnsemsStudyUkuleleCharm = "(HB2) Ansem's Study Ukulele Charm"
|
||||
RestorationSiteMoonRecipe = "(HB2) Restoration Site Moon Recipe"
|
||||
RestorationSiteAPBoost = "(HB2) Restoration Site AP Boost"
|
||||
DemyxHB = "(HB2) Demyx Bonus: Sora Slot 1"
|
||||
DemyxHBGetBonus = "(HB2) Demyx Bonus: Sora Slot 2"
|
||||
FFFightsCureElement = "(HB2) FF Fights Cure Element"
|
||||
CrystalFissureTornPages = "(HB2) Crystal Fissure Torn Pages"
|
||||
CrystalFissureTheGreatMawMap = "(HB2) Crystal Fissure The Great Maw Map"
|
||||
CrystalFissureEnergyCrystal = "(HB2) Crystal Fissure Energy Crystal"
|
||||
CrystalFissureAPBoost = "(HB2) Crystal Fissure AP Boost"
|
||||
ThousandHeartless = "(HB2) 1000 Heartless"
|
||||
ThousandHeartlessSecretAnsemReport1 = "(HB2) 1000 Heartless Secret Ansem Report 1"
|
||||
ThousandHeartlessIceCream = "(HB2) 1000 Heartless Ice Cream"
|
||||
ThousandHeartlessPicture = "(HB2) 1000 Heartless Picture"
|
||||
PosternGullWing = "(HB2) Postern Gull Wing"
|
||||
HeartlessManufactoryCosmicChain = "(HB2) Heartless Manufactory Cosmic Chain"
|
||||
SephirothBonus = "Sephiroth Bonus: Sora Slot 1"
|
||||
SephirothFenrir = "Sephiroth Fenrir"
|
||||
WinnersProof = "(HB2) Winner's Proof"
|
||||
ProofofPeace = "(HB2) Proof of Peace"
|
||||
DemyxDataAPBoost = "Data Demyx"
|
||||
|
||||
CoRDepthsAPBoost = "(CoR) Depths AP Boost"
|
||||
CoRDepthsPowerCrystal = "(CoR) Depths Power Crystal"
|
||||
CoRDepthsFrostCrystal = "(CoR) Depths Frost Crystal"
|
||||
CoRDepthsManifestIllusion = "(CoR) Depths Manifest Illusion"
|
||||
CoRDepthsAPBoost2 = "(CoR) Depths AP Boost 2"
|
||||
CoRMineshaftLowerLevelDepthsofRemembranceMap = "(CoR) Mineshaft Lower Level Depths of Remembrance Map"
|
||||
CoRMineshaftLowerLevelAPBoost = "(CoR) Mineshaft Lower Level AP Boost"
|
||||
CoRDepthsUpperLevelRemembranceGem = "(CoR) Depths Upper Level Remembrance Gem"
|
||||
CoRMiningAreaSerenityGem = "(CoR) Mining Area Serenity Gem"
|
||||
CoRMiningAreaAPBoost = "(CoR) Mining Area AP Boost"
|
||||
CoRMiningAreaSerenityCrystal = "(CoR) Mining Area Serenity Crystal"
|
||||
CoRMiningAreaManifestIllusion = "(CoR) Mining Area Manifest Illusion"
|
||||
CoRMiningAreaSerenityGem2 = "(CoR) Mining Area Serenity Gem 2"
|
||||
CoRMiningAreaDarkRemembranceMap = "(CoR) Mining Area Dark Remembrance Map"
|
||||
CoRMineshaftMidLevelPowerBoost = "(CoR) Mineshaft Mid Level Power Boost"
|
||||
CoREngineChamberSerenityCrystal = "(CoR) Engine Chamber Serenity Crystal"
|
||||
CoREngineChamberRemembranceCrystal = "(CoR) Engine Chamber Remembrance Crystal"
|
||||
CoREngineChamberAPBoost = "(CoR) Engine Chamber AP Boost"
|
||||
CoREngineChamberManifestIllusion = "(CoR) Engine Chamber Manifest Illusion"
|
||||
CoRMineshaftUpperLevelMagicBoost = "(CoR) Mineshaft Upper Level Magic Boost"
|
||||
CoRMineshaftUpperLevelAPBoost = "(CoR) Mineshaft Upper Level AP Boost"
|
||||
TransporttoRemembrance = "Transport to Remembrance"
|
||||
|
||||
GorgeSavannahMap = "(PL) Gorge Savannah Map"
|
||||
GorgeDarkGem = "(PL) Gorge Dark Gem"
|
||||
GorgeMythrilStone = "(PL) Gorge Mythril Stone"
|
||||
ElephantGraveyardFrostGem = "(PL) Elephant Graveyard Frost Gem"
|
||||
ElephantGraveyardMythrilStone = "(PL) Elephant Graveyard Mythril Stone"
|
||||
ElephantGraveyardBrightStone = "(PL) Elephant Graveyard Bright Stone"
|
||||
ElephantGraveyardAPBoost = "(PL) Elephant Graveyard AP Boost"
|
||||
ElephantGraveyardMythrilShard = "(PL) Elephant Graveyard Mythril Shard"
|
||||
PrideRockMap = "(PL) Pride Rock Map"
|
||||
PrideRockMythrilStone = "(PL) Pride Rock Mythril Stone"
|
||||
PrideRockSerenityCrystal = "(PL) Pride Rock Serenity Crystal"
|
||||
WildebeestValleyEnergyStone = "(PL) Wildebeest Valley Energy Stone"
|
||||
WildebeestValleyAPBoost = "(PL) Wildebeest Valley AP Boost"
|
||||
WildebeestValleyMythrilGem = "(PL) Wildebeest Valley Mythril Gem"
|
||||
WildebeestValleyMythrilStone = "(PL) Wildebeest Valley Mythril Stone"
|
||||
WildebeestValleyLucidGem = "(PL) Wildebeest Valley Lucid Gem"
|
||||
WastelandsMythrilShard = "(PL) Wastelands Mythril Shard"
|
||||
WastelandsSerenityGem = "(PL) Wastelands Serenity Gem"
|
||||
WastelandsMythrilStone = "(PL) Wastelands Mythril Stone"
|
||||
JungleSerenityGem = "(PL) Jungle Serenity Gem"
|
||||
JungleMythrilStone = "(PL) Jungle Mythril Stone"
|
||||
JungleSerenityCrystal = "(PL) Jungle Serenity Crystal"
|
||||
OasisMap = "(PL) Oasis Map"
|
||||
OasisTornPages = "(PL) Oasis Torn Pages"
|
||||
OasisAPBoost = "(PL) Oasis AP Boost"
|
||||
CircleofLife = "(PL) Circle of Life"
|
||||
Hyenas1 = "(PL) Hyenas 1 Bonus: Sora Slot 1"
|
||||
Scar = "(PL) Scar Bonus: Sora Slot 1"
|
||||
ScarFireElement = "(PL) Scar Fire Element"
|
||||
Hyenas2 = "(PL2) Hyenas 2 Bonus: Sora Slot 1"
|
||||
Groundshaker = "(PL2) Groundshaker Bonus: Sora Slot 1"
|
||||
GroundshakerGetBonus = "(PL2) Groundshaker Bonus: Sora Slot 2"
|
||||
SaixDataDefenseBoost = "Data Saix"
|
||||
|
||||
TwilightTownMap = "(STT) Twilight Town Map"
|
||||
MunnyPouchOlette = "(STT) Munny Pouch Olette"
|
||||
StationDusks = "(STT) Station Dusks"
|
||||
StationofSerenityPotion = "(STT) Station of Serenity Potion"
|
||||
StationofCallingPotion = "(STT) Station of Calling Potion"
|
||||
TwilightThorn = "(STT) Twilight Thorn"
|
||||
Axel1 = "(STT) Axel 1"
|
||||
JunkChampionBelt = "(STT) Junk Champion Belt"
|
||||
JunkMedal = "(STT) Junk Medal"
|
||||
TheStruggleTrophy = "(STT) The Struggle Trophy"
|
||||
CentralStationPotion1 = "(STT) Central Station Potion 1"
|
||||
STTCentralStationHiPotion = "(STT) Central Station Hi-Potion"
|
||||
CentralStationPotion2 = "(STT) Central Station Potion 2"
|
||||
SunsetTerraceAbilityRing = "(STT) Sunset Terrace Ability Ring"
|
||||
SunsetTerraceHiPotion = "(STT) Sunset Terrace Hi-Potion"
|
||||
SunsetTerracePotion1 = "(STT) Sunset Terrace Potion 1"
|
||||
SunsetTerracePotion2 = "(STT) Sunset Terrace Potion 2"
|
||||
MansionFoyerHiPotion = "(STT) Mansion Foyer Hi-Potion"
|
||||
MansionFoyerPotion1 = "(STT) Mansion Foyer Potion 1"
|
||||
MansionFoyerPotion2 = "(STT) Mansion Foyer Potion 2"
|
||||
MansionDiningRoomElvenBandanna = "(STT) Mansion Dining Room Elven Bandanna"
|
||||
MansionDiningRoomPotion = "(STT) Mansion Dining Room Potion"
|
||||
NaminesSketches = "(STT) Namine's Sketches"
|
||||
MansionMap = "(STT) Mansion Map"
|
||||
MansionLibraryHiPotion = "(STT) Mansion Library Hi-Potion"
|
||||
Axel2 = "(STT) Axel 2"
|
||||
MansionBasementCorridorHiPotion = "(STT) Mansion Basement Corridor Hi-Potion"
|
||||
RoxasDataMagicBoost = "Data Roxas"
|
||||
|
||||
OldMansionPotion = "(TT) Old Mansion Potion"
|
||||
OldMansionMythrilShard = "(TT) Old Mansion Mythril Shard"
|
||||
TheWoodsPotion = "(TT) The Woods Potion"
|
||||
TheWoodsMythrilShard = "(TT) The Woods Mythril Shard"
|
||||
TheWoodsHiPotion = "(TT) The Woods Hi-Potion"
|
||||
TramCommonHiPotion = "(TT) Tram Common Hi-Potion"
|
||||
TramCommonAPBoost = "(TT) Tram Common AP Boost"
|
||||
TramCommonTent = "(TT) Tram Common Tent"
|
||||
TramCommonMythrilShard1 = "(TT) Tram Common Mythril Shard 1"
|
||||
TramCommonPotion1 = "(TT) Tram Common Potion 1"
|
||||
TramCommonMythrilShard2 = "(TT) Tram Common Mythril Shard 2"
|
||||
TramCommonPotion2 = "(TT) Tram Common Potion 2"
|
||||
StationPlazaSecretAnsemReport2 = "(TT) Station Plaza Secret Ansem Report 2"
|
||||
MunnyPouchMickey = "(TT) Munny Pouch Mickey"
|
||||
CrystalOrb = "(TT) Crystal Orb"
|
||||
CentralStationTent = "(TT) Central Station Tent"
|
||||
TTCentralStationHiPotion = "(TT) Central Station Hi-Potion"
|
||||
CentralStationMythrilShard = "(TT) Central Station Mythril Shard"
|
||||
TheTowerPotion = "(TT) The Tower Potion"
|
||||
TheTowerHiPotion = "(TT) The Tower Hi-Potion"
|
||||
TheTowerEther = "(TT) The Tower Ether"
|
||||
TowerEntrywayEther = "(TT) Tower Entryway Ether"
|
||||
TowerEntrywayMythrilShard = "(TT) Tower Entryway Mythril Shard"
|
||||
SorcerersLoftTowerMap = "(TT) Sorcerer's Loft Tower Map"
|
||||
TowerWardrobeMythrilStone = "(TT) Tower Wardrobe Mythril Stone"
|
||||
StarSeeker = "(TT) Star Seeker"
|
||||
ValorForm = "(TT) Valor Form"
|
||||
SeifersTrophy = "(TT2) Seifer's Trophy"
|
||||
Oathkeeper = "(TT2) Oathkeeper"
|
||||
LimitForm = "(TT2) Limit Form"
|
||||
UndergroundConcourseMythrilGem = "(TT3) Underground Concourse Mythril Gem"
|
||||
UndergroundConcourseOrichalcum = "(TT3) Underground Concourse Orichalcum"
|
||||
UndergroundConcourseAPBoost = "(TT3) Underground Concourse AP Boost"
|
||||
UndergroundConcourseMythrilCrystal = "(TT3) Underground Concourse Mythril Crystal"
|
||||
TunnelwayOrichalcum = "(TT3) Tunnelway Orichalcum"
|
||||
TunnelwayMythrilCrystal = "(TT3) Tunnelway Mythril Crystal"
|
||||
SunsetTerraceOrichalcumPlus = "(TT3) Sunset Terrace Orichalcum+"
|
||||
SunsetTerraceMythrilShard = "(TT3) Sunset Terrace Mythril Shard"
|
||||
SunsetTerraceMythrilCrystal = "(TT3) Sunset Terrace Mythril Crystal"
|
||||
SunsetTerraceAPBoost = "(TT3) Sunset Terrace AP Boost"
|
||||
MansionNobodies = "(TT3) Mansion Nobodies Bonus: Sora Slot 1"
|
||||
MansionFoyerMythrilCrystal = "(TT3) Mansion Foyer Mythril Crystal"
|
||||
MansionFoyerMythrilStone = "(TT3) Mansion Foyer Mythril Stone"
|
||||
MansionFoyerSerenityCrystal = "(TT3) Mansion Foyer Serenity Crystal"
|
||||
MansionDiningRoomMythrilCrystal = "(TT3) Mansion Dining Room Mythril Crystal"
|
||||
MansionDiningRoomMythrilStone = "(TT3) Mansion Dining Room Mythril Stone"
|
||||
MansionLibraryOrichalcum = "(TT3) Mansion Library Orichalcum"
|
||||
BeamSecretAnsemReport10 = "(TT3) Beam Secret Ansem Report 10"
|
||||
MansionBasementCorridorUltimateRecipe = "(TT3) Mansion Basement Corridor Ultimate Recipe"
|
||||
BetwixtandBetween = "(TT3) Betwixt and Between"
|
||||
BetwixtandBetweenBondofFlame = "(TT3) Betwixt and Between Bond of Flame"
|
||||
AxelDataMagicBoost = "Data Axel"
|
||||
|
||||
FragmentCrossingMythrilStone = "(TWTNW) Fragment Crossing Mythril Stone"
|
||||
FragmentCrossingMythrilCrystal = "(TWTNW) Fragment Crossing Mythril Crystal"
|
||||
FragmentCrossingAPBoost = "(TWTNW) Fragment Crossing AP Boost"
|
||||
FragmentCrossingOrichalcum = "(TWTNW) Fragment Crossing Orichalcum"
|
||||
Roxas = "(TWTNW) Roxas Bonus: Sora Slot 1"
|
||||
RoxasGetBonus = "(TWTNW) Roxas Bonus: Sora Slot 2"
|
||||
RoxasSecretAnsemReport8 = "(TWTNW) Roxas Secret Ansem Report 8"
|
||||
TwoBecomeOne = "(TWTNW) Two Become One"
|
||||
MemorysSkyscaperMythrilCrystal = "(TWTNW) Memory's Skyscaper Mythril Crystal"
|
||||
MemorysSkyscaperAPBoost = "(TWTNW) Memory's Skyscaper AP Boost"
|
||||
MemorysSkyscaperMythrilStone = "(TWTNW) Memory's Skyscaper Mythril Stone"
|
||||
TheBrinkofDespairDarkCityMap = "(TWTNW) The Brink of Despair Dark City Map"
|
||||
TheBrinkofDespairOrichalcumPlus = "(TWTNW) The Brink of Despair Orichalcum+"
|
||||
NothingsCallMythrilGem = "(TWTNW) Nothing's Call Mythril Gem"
|
||||
NothingsCallOrichalcum = "(TWTNW) Nothing's Call Orichalcum"
|
||||
TwilightsViewCosmicBelt = "(TWTNW) Twilight's View Cosmic Belt"
|
||||
XigbarBonus = "(TWTNW) Xigbar Bonus: Sora Slot 1"
|
||||
XigbarSecretAnsemReport3 = "(TWTNW) Xigbar Secret Ansem Report 3"
|
||||
NaughtsSkywayMythrilGem = "(TWTNW) Naught's Skyway Mythril Gem"
|
||||
NaughtsSkywayOrichalcum = "(TWTNW) Naught's Skyway Orichalcum"
|
||||
NaughtsSkywayMythrilCrystal = "(TWTNW) Naught's Skyway Mythril Crystal"
|
||||
Oblivion = "(TWTNW) Oblivion"
|
||||
CastleThatNeverWasMap = "(TWTNW) Castle That Never Was Map"
|
||||
Luxord = "(TWTNW) Luxord"
|
||||
LuxordGetBonus = "(TWTNW) Luxord Bonus: Sora Slot 1"
|
||||
LuxordSecretAnsemReport9 = "(TWTNW) Luxord Secret Ansem Report 9"
|
||||
SaixBonus = "(TWTNW) Saix Bonus: Sora Slot 1"
|
||||
SaixSecretAnsemReport12 = "(TWTNW) Saix Secret Ansem Report 12"
|
||||
PreXemnas1SecretAnsemReport11 = "(TWTNW) Secret Ansem Report 11 (Pre-Xemnas 1)"
|
||||
RuinandCreationsPassageMythrilStone = "(TWTNW) Ruin and Creation's Passage Mythril Stone"
|
||||
RuinandCreationsPassageAPBoost = "(TWTNW) Ruin and Creation's Passage AP Boost"
|
||||
RuinandCreationsPassageMythrilCrystal = "(TWTNW) Ruin and Creation's Passage Mythril Crystal"
|
||||
RuinandCreationsPassageOrichalcum = "(TWTNW) Ruin and Creation's Passage Orichalcum"
|
||||
Xemnas1 = "(TWTNW) Xemnas 1 Bonus: Sora Slot 1"
|
||||
Xemnas1GetBonus = "(TWTNW) Xemnas 1 Bonus: Sora Slot 2"
|
||||
Xemnas1SecretAnsemReport13 = "(TWTNW) Xemnas 1 Secret Ansem Report 13"
|
||||
FinalXemnas = "Final Xemnas"
|
||||
XemnasDataPowerBoost = "Data Xemnas"
|
||||
Lvl1 ="Level 01"
|
||||
Lvl2 ="Level 02"
|
||||
Lvl3 ="Level 03"
|
||||
Lvl4 ="Level 04"
|
||||
Lvl5 ="Level 05"
|
||||
Lvl6 ="Level 06"
|
||||
Lvl7 ="Level 07"
|
||||
Lvl8 ="Level 08"
|
||||
Lvl9 ="Level 09"
|
||||
Lvl10 ="Level 10"
|
||||
Lvl11 ="Level 11"
|
||||
Lvl12 ="Level 12"
|
||||
Lvl13 ="Level 13"
|
||||
Lvl14 ="Level 14"
|
||||
Lvl15 ="Level 15"
|
||||
Lvl16 ="Level 16"
|
||||
Lvl17 ="Level 17"
|
||||
Lvl18 ="Level 18"
|
||||
Lvl19 ="Level 19"
|
||||
Lvl20 ="Level 20"
|
||||
Lvl21 ="Level 21"
|
||||
Lvl22 ="Level 22"
|
||||
Lvl23 ="Level 23"
|
||||
Lvl24 ="Level 24"
|
||||
Lvl25 ="Level 25"
|
||||
Lvl26 ="Level 26"
|
||||
Lvl27 ="Level 27"
|
||||
Lvl28 ="Level 28"
|
||||
Lvl29 ="Level 29"
|
||||
Lvl30 ="Level 30"
|
||||
Lvl31 ="Level 31"
|
||||
Lvl32 ="Level 32"
|
||||
Lvl33 ="Level 33"
|
||||
Lvl34 ="Level 34"
|
||||
Lvl35 ="Level 35"
|
||||
Lvl36 ="Level 36"
|
||||
Lvl37 ="Level 37"
|
||||
Lvl38 ="Level 38"
|
||||
Lvl39 ="Level 39"
|
||||
Lvl40 ="Level 40"
|
||||
Lvl41 ="Level 41"
|
||||
Lvl42 ="Level 42"
|
||||
Lvl43 ="Level 43"
|
||||
Lvl44 ="Level 44"
|
||||
Lvl45 ="Level 45"
|
||||
Lvl46 ="Level 46"
|
||||
Lvl47 ="Level 47"
|
||||
Lvl48 ="Level 48"
|
||||
Lvl49 ="Level 49"
|
||||
Lvl50 ="Level 50"
|
||||
Lvl51 ="Level 51"
|
||||
Lvl52 ="Level 52"
|
||||
Lvl53 ="Level 53"
|
||||
Lvl54 ="Level 54"
|
||||
Lvl55 ="Level 55"
|
||||
Lvl56 ="Level 56"
|
||||
Lvl57 ="Level 57"
|
||||
Lvl58 ="Level 58"
|
||||
Lvl59 ="Level 59"
|
||||
Lvl60 ="Level 60"
|
||||
Lvl61 ="Level 61"
|
||||
Lvl62 ="Level 62"
|
||||
Lvl63 ="Level 63"
|
||||
Lvl64 ="Level 64"
|
||||
Lvl65 ="Level 65"
|
||||
Lvl66 ="Level 66"
|
||||
Lvl67 ="Level 67"
|
||||
Lvl68 ="Level 68"
|
||||
Lvl69 ="Level 69"
|
||||
Lvl70 ="Level 70"
|
||||
Lvl71 ="Level 71"
|
||||
Lvl72 ="Level 72"
|
||||
Lvl73 ="Level 73"
|
||||
Lvl74 ="Level 74"
|
||||
Lvl75 ="Level 75"
|
||||
Lvl76 ="Level 76"
|
||||
Lvl77 ="Level 77"
|
||||
Lvl78 ="Level 78"
|
||||
Lvl79 ="Level 79"
|
||||
Lvl80 ="Level 80"
|
||||
Lvl81 ="Level 81"
|
||||
Lvl82 ="Level 82"
|
||||
Lvl83 ="Level 83"
|
||||
Lvl84 ="Level 84"
|
||||
Lvl85 ="Level 85"
|
||||
Lvl86 ="Level 86"
|
||||
Lvl87 ="Level 87"
|
||||
Lvl88 ="Level 88"
|
||||
Lvl89 ="Level 89"
|
||||
Lvl90 ="Level 90"
|
||||
Lvl91 ="Level 91"
|
||||
Lvl92 ="Level 92"
|
||||
Lvl93 ="Level 93"
|
||||
Lvl94 ="Level 94"
|
||||
Lvl95 ="Level 95"
|
||||
Lvl96 ="Level 96"
|
||||
Lvl97 ="Level 97"
|
||||
Lvl98 ="Level 98"
|
||||
Lvl99 ="Level 99"
|
||||
Valorlvl1 ="Valor level 1"
|
||||
Valorlvl2 ="Valor level 2"
|
||||
Valorlvl3 ="Valor level 3"
|
||||
Valorlvl4 ="Valor level 4"
|
||||
Valorlvl5 ="Valor level 5"
|
||||
Valorlvl6 ="Valor level 6"
|
||||
Valorlvl7 ="Valor level 7"
|
||||
Wisdomlvl1 ="Wisdom level 1"
|
||||
Wisdomlvl2 ="Wisdom level 2"
|
||||
Wisdomlvl3 ="Wisdom level 3"
|
||||
Wisdomlvl4 ="Wisdom level 4"
|
||||
Wisdomlvl5 ="Wisdom level 5"
|
||||
Wisdomlvl6 ="Wisdom level 6"
|
||||
Wisdomlvl7 ="Wisdom level 7"
|
||||
Limitlvl1 ="Limit level 1"
|
||||
Limitlvl2 ="Limit level 2"
|
||||
Limitlvl3 ="Limit level 3"
|
||||
Limitlvl4 ="Limit level 4"
|
||||
Limitlvl5 ="Limit level 5"
|
||||
Limitlvl6 ="Limit level 6"
|
||||
Limitlvl7 ="Limit level 7"
|
||||
Masterlvl1 ="Master level 1"
|
||||
Masterlvl2 ="Master level 2"
|
||||
Masterlvl3 ="Master level 3"
|
||||
Masterlvl4 ="Master level 4"
|
||||
Masterlvl5 ="Master level 5"
|
||||
Masterlvl6 ="Master level 6"
|
||||
Masterlvl7 ="Master level 7"
|
||||
Finallvl1 ="Final level 1"
|
||||
Finallvl2 ="Final level 2"
|
||||
Finallvl3 ="Final level 3"
|
||||
Finallvl4 ="Final level 4"
|
||||
Finallvl5 ="Final level 5"
|
||||
Finallvl6 ="Final level 6"
|
||||
Finallvl7 ="Final level 7"
|
||||
|
||||
GardenofAssemblageMap ="Garden of Assemblage Map"
|
||||
GoALostIllusion ="GoA Lost Illusion"
|
||||
ProofofNonexistence ="Proof of Nonexistence Location"
|
||||
|
||||
test= "test"
|
||||
|
||||
|
||||
Crit_1 ="Critical Starting Ability 1"
|
||||
Crit_2 ="Critical Starting Ability 2"
|
||||
Crit_3 ="Critical Starting Ability 3"
|
||||
Crit_4 ="Critical Starting Ability 4"
|
||||
Crit_5 ="Critical Starting Ability 5"
|
||||
Crit_6 ="Critical Starting Ability 6"
|
||||
Crit_7 ="Critical Starting Ability 7"
|
||||
DonaldStarting1 ="Donald Starting Item 1"
|
||||
DonaldStarting2 ="Donald Starting Item 2"
|
||||
GoofyStarting1 ="Goofy Starting Item 1"
|
||||
GoofyStarting2 ="Goofy Starting Item 2"
|
||||
|
||||
|
||||
DonaldScreens ="(SP) Screens Bonus: Donald Slot 1"
|
||||
DonaldDemyxHBGetBonus ="(HB) Demyx Bonus: Donald Slot 1"
|
||||
DonaldDemyxOC ="(OC) Demyx Bonus: Donald Slot 1"
|
||||
DonaldBoatPete ="(TR) Boat Pete Bonus: Donald Slot 1"
|
||||
DonaldBoatPeteGetBonus ="(TR) Boat Pete Bonus: Donald Slot 2"
|
||||
DonaldPrisonKeeper ="(HT) Prison Keeper Bonus: Donald Slot 1"
|
||||
DonaldScar ="(PL) Scar Bonus: Donald Slot 1"
|
||||
DonaldSolarSailer ="(SP2) Solar Sailer Bonus: Donald Slot 1"
|
||||
DonaldExperiment ="(HT2) Experiment Bonus: Donald Slot 1"
|
||||
DonaldBoatFight ="(PR) Boat Fight Bonus: Donald Slot 1"
|
||||
DonaldMansionNobodies ="(TT3) Mansion Nobodies Bonus: Donald Slot 1"
|
||||
DonaldThresholder ="(BC) Thresholder Bonus: Donald Slot 1"
|
||||
DonaldXaldinGetBonus ="(BC2) Xaldin Bonus: Donald Slot 1"
|
||||
DonaladGrimReaper2 ="(PR2) Grim Reaper 2 Bonus: Donald Slot 1"
|
||||
DonaldAbuEscort ="(AG) Abu Escort Bonus: Donald Slot 1"
|
||||
|
||||
GoofyBarbossa ="(PR) Barbossa Bonus: Goofy Slot 1"
|
||||
GoofyBarbossaGetBonus ="(PR) Barbossa Bonus: Goofy Slot 2"
|
||||
GoofyGrimReaper1 ="(PR2) Grim Reaper 1 Bonus: Goofy Slot 1"
|
||||
GoofyHostileProgram ="(SP) Hostile Program Bonus: Goofy Slot 1"
|
||||
GoofyHyenas1 ="(PL) Hyenas 1 Bonus: Goofy Slot 1"
|
||||
GoofyHyenas2 ="(PL2) Hyenas 2 Bonus: Goofy Slot 1"
|
||||
GoofyLock ="(HT2) Lock, Shock and Barrel Bonus: Goofy Slot 1"
|
||||
GoofyOogieBoogie ="(HT) Oogie Boogie Bonus: Goofy Slot 1"
|
||||
GoofyPeteOC ="(OC) Pete Bonus: Goofy Slot 1"
|
||||
GoofyFuturePete ="(TR) Future Pete Bonus: Goofy Slot 1"
|
||||
GoofyShanYu ="(LoD) Shan-Yu Bonus: Goofy Slot 1"
|
||||
GoofyStormRider ="(LoD2) Storm Rider Bonus: Goofy Slot 1"
|
||||
GoofyBeast ="(BC) Beast Bonus: Goofy Slot 1"
|
||||
GoofyInterceptorBarrels ="(PR) Interceptor Barrels Bonus: Goofy Slot 1"
|
||||
GoofyTreasureRoom ="(AG) Treasure Room Heartless Bonus: Goofy Slot 1"
|
||||
GoofyZexion ="Zexion Bonus: Goofy Slot 1"
|
||||
|
||||
|
||||
AdamantShield ="Adamant Shield Slot"
|
||||
AkashicRecord ="Akashic Record Slot"
|
||||
ChainGear ="Chain Gear Slot"
|
||||
DreamCloud ="Dream Cloud Slot"
|
||||
FallingStar ="Falling Star Slot"
|
||||
FrozenPride2 ="Frozen Pride+ Slot"
|
||||
GenjiShield ="Genji Shield Slot"
|
||||
KnightDefender ="Knight Defender Slot"
|
||||
KnightsShield ="Knight's Shield Slot"
|
||||
MajesticMushroom ="Majestic Mushroom Slot"
|
||||
MajesticMushroom2 ="Majestic Mushroom+ Slot"
|
||||
NobodyGuard ="Nobody Guard Slot"
|
||||
OgreShield ="Ogre Shield Slot"
|
||||
SaveTheKing2 ="Save The King+ Slot"
|
||||
UltimateMushroom ="Ultimate Mushroom Slot"
|
||||
|
||||
HammerStaff ="Hammer Staff Slot"
|
||||
LordsBroom ="Lord's Broom Slot"
|
||||
MagesStaff ="Mages Staff Slot"
|
||||
MeteorStaff ="Meteor Staff Slot"
|
||||
CometStaff ="Comet Staff Slot"
|
||||
Centurion2 ="Centurion+ Slot"
|
||||
MeteorStaff ="Meteor Staff Slot"
|
||||
NobodyLance ="Nobody Lance Slot"
|
||||
PreciousMushroom ="Precious Mushroom Slot"
|
||||
PreciousMushroom2 ="Precious Mushroom+ Slot"
|
||||
PremiumMushroom ="Premium Mushroom Slot"
|
||||
RisingDragon ="Rising Dragon Slot"
|
||||
SaveTheQueen2 ="Save The Queen+ Slot"
|
||||
ShamansRelic ="Shaman's Relic Slot"
|
||||
VictoryBell ="Victory Bell Slot"
|
||||
WisdomWand ="Wisdom Wand Slot"
|
||||
|
||||
#Keyblade Slots
|
||||
FAKESlot ="FAKE Slot"
|
||||
DetectionSaberSlot ="Detection Saber Slot"
|
||||
EdgeofUltimaSlot ="Edge of Ultima Slot"
|
||||
KingdomKeySlot ="Kingdom Key Slot"
|
||||
OathkeeperSlot ="Oathkeeper Slot"
|
||||
OblivionSlot ="Oblivion Slot"
|
||||
StarSeekerSlot ="Star Seeker Slot"
|
||||
HiddenDragonSlot ="Hidden Dragon Slot"
|
||||
HerosCrestSlot ="Hero's Crest Slot"
|
||||
MonochromeSlot ="Monochrome Slot"
|
||||
FollowtheWindSlot ="Follow the Wind Slot"
|
||||
CircleofLifeSlot ="Circle of Life Slot"
|
||||
PhotonDebuggerSlot ="Photon Debugger Slot"
|
||||
GullWingSlot ="Gull Wing Slot"
|
||||
RumblingRoseSlot ="Rumbling Rose Slot"
|
||||
GuardianSoulSlot ="Guardian Soul Slot"
|
||||
WishingLampSlot ="Wishing Lamp Slot"
|
||||
DecisivePumpkinSlot ="Decisive Pumpkin Slot"
|
||||
SweetMemoriesSlot ="Sweet Memories Slot"
|
||||
MysteriousAbyssSlot ="Mysterious Abyss Slot"
|
||||
SleepingLionSlot ="Sleeping Lion Slot"
|
||||
BondofFlameSlot ="Bond of Flame Slot"
|
||||
TwoBecomeOneSlot ="Two Become One Slot"
|
||||
FatalCrestSlot ="Fatal Crest Slot"
|
||||
FenrirSlot ="Fenrir Slot"
|
||||
UltimaWeaponSlot ="Ultima Weapon Slot"
|
||||
WinnersProofSlot ="Winner's Proof Slot"
|
||||
PurebloodSlot ="Pureblood Slot"
|
||||
|
||||
#Final_Region ="Final Form"
|
|
@ -0,0 +1,90 @@
|
|||
LoD_Region ="Land of Dragons"
|
||||
LoD2_Region ="Land of Dragons 2"
|
||||
|
||||
Ag_Region ="Agrabah"
|
||||
Ag2_Region ="Agrabah 2"
|
||||
|
||||
Dc_Region ="Disney Castle"
|
||||
Tr_Region ="Timeless River"
|
||||
|
||||
HundredAcre1_Region ="Pooh's House"
|
||||
HundredAcre2_Region ="Piglet's House"
|
||||
HundredAcre3_Region ="Rabbit's House"
|
||||
HundredAcre4_Region ="Roo's House"
|
||||
HundredAcre5_Region ="Spookey Cave"
|
||||
HundredAcre6_Region ="Starry Hill"
|
||||
|
||||
Pr_Region ="Port Royal"
|
||||
Pr2_Region ="Port Royal 2"
|
||||
Gr2_Region ="Grim Reaper 2"
|
||||
|
||||
Oc_Region ="Olympus Coliseum"
|
||||
Oc2_Region ="Olympus Coliseum 2"
|
||||
Oc2_pain_and_panic_Region ="Pain and Panic Cup"
|
||||
Oc2_titan_Region ="Titan Cup"
|
||||
Oc2_cerberus_Region ="Cerberus Cup"
|
||||
Oc2_gof_Region ="Goddest of Fate Cup"
|
||||
Oc2Cups_Region ="Olympus Coliseum Cups"
|
||||
HadesCups_Region ="Olympus Coliseum Hade's Paradox"
|
||||
|
||||
Bc_Region ="Beast's Castle"
|
||||
Bc2_Region ="Beast's Castle 2"
|
||||
Xaldin_Region ="Xaldin"
|
||||
|
||||
Sp_Region ="Space Paranoids"
|
||||
Sp2_Region ="Space Paranoids 2"
|
||||
Mcp_Region ="Master Control Program"
|
||||
|
||||
Ht_Region ="Holloween Town"
|
||||
Ht2_Region ="Holloween Town 2"
|
||||
|
||||
Hb_Region ="Hollow Bastion"
|
||||
Hb2_Region ="Hollow Bastion 2"
|
||||
ThousandHeartless_Region ="Thousand Hearless"
|
||||
Mushroom13_Region ="Mushroom 13"
|
||||
CoR_Region ="Cavern of Rememberance"
|
||||
Transport_Region ="Transport to Rememberance"
|
||||
|
||||
Pl_Region ="Pride Lands"
|
||||
Pl2_Region ="Pride Lands 2"
|
||||
|
||||
STT_Region ="Simulated Twilight Town"
|
||||
|
||||
TT_Region ="Twlight Town"
|
||||
TT2_Region ="Twlight Town 2"
|
||||
TT3_Region ="Twlight Town 3"
|
||||
|
||||
Twtnw_Region ="The World That Never Was (First Visit)"
|
||||
Twtnw_PostRoxas ="The World That Never Was (Post Roxas)"
|
||||
Twtnw_PostXigbar ="The World That Never Was (Post Xigbar)"
|
||||
Twtnw2_Region ="The World That Never Was (Second Visit)" #before riku transformation
|
||||
|
||||
SoraLevels_Region ="Sora's Levels"
|
||||
GoA_Region ="Garden Of Assemblage"
|
||||
Keyblade_Region ="Keyblade Slots"
|
||||
|
||||
Valor_Region ="Valor Form"
|
||||
Wisdom_Region ="Wisdom Form"
|
||||
Limit_Region ="Limit Form"
|
||||
Master_Region ="Master Form"
|
||||
Final_Region ="Final Form"
|
||||
|
||||
Terra_Region ="Lingering Will"
|
||||
Sephi_Region ="Sephiroth"
|
||||
Marluxia_Region ="Marluxia"
|
||||
Larxene_Region ="Larxene"
|
||||
Vexen_Region ="Vexen"
|
||||
Lexaeus_Region ="Lexaeus"
|
||||
Zexion_Region ="Zexion"
|
||||
|
||||
LevelsVS1 ="Levels Region (1 Visit Locking Item)"
|
||||
LevelsVS3 ="Levels Region (3 Visit Locking Items)"
|
||||
LevelsVS6 ="Levels Region (6 Visit Locking Items)"
|
||||
LevelsVS9 ="Levels Region (9 Visit Locking Items)"
|
||||
LevelsVS12 ="Levels Region (12 Visit Locking Items)"
|
||||
LevelsVS15 ="Levels Region (15 Visit Locking Items)"
|
||||
LevelsVS18 ="Levels Region (18 Visit Locking Items)"
|
||||
LevelsVS21 ="Levels Region (21 Visit Locking Items)"
|
||||
LevelsVS24 ="Levels Region (24 Visit Locking Items)"
|
||||
LevelsVS26 ="Levels Region (26 Visit Locking Items)"
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
import yaml
|
||||
import os
|
||||
import Utils
|
||||
import zipfile
|
||||
|
||||
from .Items import item_dictionary_table, CheckDupingItems
|
||||
from .Locations import all_locations, SoraLevels, exclusion_table, AllWeaponSlot
|
||||
from .Names import LocationName
|
||||
from .XPValues import lvlStats, formExp, soraExp
|
||||
from worlds.Files import APContainer
|
||||
|
||||
|
||||
class KH2Container(APContainer):
|
||||
game: str = 'Kingdom Hearts 2'
|
||||
|
||||
def __init__(self, patch_data: dict, base_path: str, output_directory: str,
|
||||
player=None, player_name: str = "", server: str = ""):
|
||||
self.patch_data = patch_data
|
||||
self.file_path = base_path
|
||||
container_path = os.path.join(output_directory, base_path + ".zip")
|
||||
super().__init__(container_path, player, player_name, server)
|
||||
|
||||
def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None:
|
||||
for filename, yml in self.patch_data.items():
|
||||
opened_zipfile.writestr(filename, yml)
|
||||
for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), "mod_template")):
|
||||
for file in files:
|
||||
opened_zipfile.write(os.path.join(root, file),
|
||||
os.path.relpath(os.path.join(root, file),
|
||||
os.path.join(os.path.dirname(__file__), "mod_template")))
|
||||
# opened_zipfile.writestr(self.zpf_path, self.patch_data)
|
||||
super().write_contents(opened_zipfile)
|
||||
|
||||
|
||||
def patch_kh2(self, output_directory):
|
||||
def increaseStat(i):
|
||||
if lvlStats[i] == "str":
|
||||
self.strength += 2
|
||||
elif lvlStats[i] == "mag":
|
||||
self.magic += 2
|
||||
elif lvlStats[i] == "def":
|
||||
self.defense += 1
|
||||
elif lvlStats[i] == "ap":
|
||||
self.ap += 3
|
||||
|
||||
self.formattedTrsr = {}
|
||||
self.formattedBons = []
|
||||
self.formattedLvup = {"Sora": {}}
|
||||
self.formattedBons = {}
|
||||
self.formattedFmlv = {}
|
||||
self.formattedItem = {"Stats": []}
|
||||
self.formattedPlrp = []
|
||||
self.strength = 2
|
||||
self.magic = 6
|
||||
self.defense = 2
|
||||
self.ap = 0
|
||||
self.dblbonus = 0
|
||||
formexp = None
|
||||
formName = None
|
||||
levelsetting = list()
|
||||
slotDataDuping = set()
|
||||
for values in CheckDupingItems.values():
|
||||
if isinstance(values, set):
|
||||
slotDataDuping |= values
|
||||
else:
|
||||
for inner_values in values.values():
|
||||
slotDataDuping |= inner_values
|
||||
|
||||
if self.multiworld.Keyblade_Minimum[self.player].value > self.multiworld.Keyblade_Maximum[self.player].value:
|
||||
print(
|
||||
f"{self.multiworld.get_file_safe_player_name(self.player)} has Keyblade Minimum greater than Keyblade Maximum")
|
||||
keyblademin = self.multiworld.Keyblade_Maximum[self.player].value
|
||||
keyblademax = self.multiworld.Keyblade_Minimum[self.player].value
|
||||
else:
|
||||
keyblademin = self.multiworld.Keyblade_Minimum[self.player].value
|
||||
keyblademax = self.multiworld.Keyblade_Maximum[self.player].value
|
||||
|
||||
if self.multiworld.LevelDepth[self.player] == "level_50":
|
||||
levelsetting.extend(exclusion_table["Level50"])
|
||||
|
||||
elif self.multiworld.LevelDepth[self.player] == "level_99":
|
||||
levelsetting.extend(exclusion_table["Level99"])
|
||||
|
||||
elif self.multiworld.LevelDepth[self.player] in ["level_50_sanity", "level_99_sanity"]:
|
||||
levelsetting.extend(exclusion_table["Level50Sanity"])
|
||||
|
||||
if self.multiworld.LevelDepth[self.player] == "level_99_sanity":
|
||||
levelsetting.extend(exclusion_table["Level99Sanity"])
|
||||
|
||||
mod_name = f"AP-{self.multiworld.seed_name}-P{self.player}-{self.multiworld.get_file_safe_player_name(self.player)}"
|
||||
|
||||
for location in self.multiworld.get_filled_locations(self.player):
|
||||
|
||||
data = all_locations[location.name]
|
||||
if location.item.player == self.player:
|
||||
itemcode = item_dictionary_table[location.item.name].kh2id
|
||||
if location.item.name in slotDataDuping and \
|
||||
location.name not in AllWeaponSlot:
|
||||
self.LocalItems[location.address] = item_dictionary_table[location.item.name].code
|
||||
else:
|
||||
itemcode = 90 # castle map
|
||||
|
||||
if data.yml == "Chest":
|
||||
self.formattedTrsr[data.locid] = {"ItemId": itemcode}
|
||||
|
||||
elif data.yml in ["Get Bonus", "Double Get Bonus", "Second Get Bonus"]:
|
||||
if data.yml == "Get Bonus":
|
||||
self.dblbonus = 0
|
||||
# if double bonus then addresses dbl bonus so the next check gets 2 items on it
|
||||
if data.yml == "Double Get Bonus":
|
||||
self.dblbonus = itemcode
|
||||
continue
|
||||
if data.locid not in self.formattedBons.keys():
|
||||
self.formattedBons[data.locid] = {}
|
||||
self.formattedBons[data.locid][data.charName] = {
|
||||
"RewardId": data.locid,
|
||||
"CharacterId": data.charNumber,
|
||||
"HpIncrease": 0,
|
||||
"MpIncrease": 0,
|
||||
"DriveGaugeUpgrade": 0,
|
||||
"ItemSlotUpgrade": 0,
|
||||
"AccessorySlotUpgrade": 0,
|
||||
"ArmorSlotUpgrade": 0,
|
||||
"BonusItem1": itemcode,
|
||||
"BonusItem2": self.dblbonus,
|
||||
"Padding": 0
|
||||
|
||||
}
|
||||
# putting dbl bonus at 0 again, so we don't have the same item placed multiple time
|
||||
self.dblbonus = 0
|
||||
elif data.yml == "Keyblade":
|
||||
self.formattedItem["Stats"].append({
|
||||
"Id": data.locid,
|
||||
"Attack": self.multiworld.per_slot_randoms[self.player].randint(keyblademin, keyblademax),
|
||||
"Magic": self.multiworld.per_slot_randoms[self.player].randint(keyblademin, keyblademax),
|
||||
"Defense": 0,
|
||||
"Ability": itemcode,
|
||||
"AbilityPoints": 0,
|
||||
"Unknown08": 100,
|
||||
"FireResistance": 100,
|
||||
"IceResistance": 100,
|
||||
"LightningResistance": 100,
|
||||
"DarkResistance": 100,
|
||||
"Unknown0d": 100,
|
||||
"GeneralResistance": 100,
|
||||
"Unknown": 0
|
||||
})
|
||||
|
||||
elif data.yml == "Forms":
|
||||
# loc id is form lvl
|
||||
# char name is the form name number :)
|
||||
if data.locid == 2:
|
||||
formDict = {1: "Valor", 2: "Wisdom", 3: "Limit", 4: "Master", 5: "Final"}
|
||||
formDictExp = {
|
||||
1: self.multiworld.Valor_Form_EXP[self.player].value,
|
||||
2: self.multiworld.Wisdom_Form_EXP[self.player].value,
|
||||
3: self.multiworld.Limit_Form_EXP[self.player].value,
|
||||
4: self.multiworld.Master_Form_EXP[self.player].value,
|
||||
5: self.multiworld.Final_Form_EXP[self.player].value}
|
||||
formexp = formDictExp[data.charName]
|
||||
formName = formDict[data.charName]
|
||||
self.formattedFmlv[formName] = []
|
||||
self.formattedFmlv[formName].append({
|
||||
"Ability": 1,
|
||||
"Experience": int(formExp[data.charName][data.locid] / formexp),
|
||||
"FormId": data.charName,
|
||||
"FormLevel": 1,
|
||||
"GrowthAbilityLevel": 0,
|
||||
})
|
||||
# row is form column is lvl
|
||||
self.formattedFmlv[formName].append({
|
||||
"Ability": itemcode,
|
||||
"Experience": int(formExp[data.charName][data.locid] / formexp),
|
||||
"FormId": data.charName,
|
||||
"FormLevel": data.locid,
|
||||
"GrowthAbilityLevel": 0,
|
||||
})
|
||||
|
||||
# Summons have no checks on them so done fully locally
|
||||
self.formattedFmlv["Summon"] = []
|
||||
for x in range(1, 7):
|
||||
self.formattedFmlv["Summon"].append({
|
||||
"Ability": 123,
|
||||
"Experience": int(formExp[0][x] / self.multiworld.Summon_EXP[self.player].value),
|
||||
"FormId": 0,
|
||||
"FormLevel": x,
|
||||
"GrowthAbilityLevel": 0,
|
||||
})
|
||||
# levels done down here because of optional settings that can take locations out of the pool.
|
||||
self.i = 1
|
||||
for location in SoraLevels:
|
||||
increaseStat(self.multiworld.per_slot_randoms[self.player].randint(0, 3))
|
||||
if location in levelsetting:
|
||||
data = self.multiworld.get_location(location, self.player)
|
||||
if data.item.player == self.player:
|
||||
itemcode = item_dictionary_table[data.item.name].kh2id
|
||||
else:
|
||||
itemcode = 461
|
||||
else:
|
||||
increaseStat(self.multiworld.per_slot_randoms[self.player].randint(0, 3))
|
||||
itemcode = 0
|
||||
self.formattedLvup["Sora"][self.i] = {
|
||||
"Exp": int(soraExp[self.i] / self.multiworld.Sora_Level_EXP[self.player].value),
|
||||
"Strength": self.strength,
|
||||
"Magic": self.magic,
|
||||
"Defense": self.defense,
|
||||
"Ap": self.ap,
|
||||
"SwordAbility": itemcode,
|
||||
"ShieldAbility": itemcode,
|
||||
"StaffAbility": itemcode,
|
||||
"Padding": 0,
|
||||
"Character": "Sora",
|
||||
"Level": self.i
|
||||
}
|
||||
self.i += 1
|
||||
# averaging stats for the struggle bats
|
||||
for x in {122, 144, 145}:
|
||||
self.formattedItem["Stats"].append({
|
||||
"Id": x,
|
||||
"Attack": int((keyblademin + keyblademax) / 2),
|
||||
"Magic": int((keyblademin + keyblademax) / 2),
|
||||
"Defense": 0,
|
||||
"Ability": 405,
|
||||
"AbilityPoints": 0,
|
||||
"Unknown08": 100,
|
||||
"FireResistance": 100,
|
||||
"IceResistance": 100,
|
||||
"LightningResistance": 100,
|
||||
"DarkResistance": 100,
|
||||
"Unknown0d": 100,
|
||||
"GeneralResistance": 100,
|
||||
"Unknown": 0
|
||||
})
|
||||
mod_dir = os.path.join(output_directory, mod_name + "_" + Utils.__version__)
|
||||
|
||||
openkhmod = {
|
||||
"TrsrList.yml": yaml.dump(self.formattedTrsr, line_break="\n"),
|
||||
"LvupList.yml": yaml.dump(self.formattedLvup, line_break="\n"),
|
||||
"BonsList.yml": yaml.dump(self.formattedBons, line_break="\n"),
|
||||
"ItemList.yml": yaml.dump(self.formattedItem, line_break="\n"),
|
||||
"FmlvList.yml": yaml.dump(self.formattedFmlv, line_break="\n"),
|
||||
}
|
||||
|
||||
mod = KH2Container(openkhmod, mod_dir, output_directory, self.player,
|
||||
self.multiworld.get_file_safe_player_name(self.player))
|
||||
mod.write()
|
|
@ -0,0 +1,253 @@
|
|||
from Options import Choice, Option, Range, Toggle, OptionSet
|
||||
import typing
|
||||
|
||||
|
||||
class SoraEXP(Range):
|
||||
"""Sora Level Exp Multiplier"""
|
||||
display_name = "Sora Level EXP"
|
||||
range_start = 1
|
||||
range_end = 10
|
||||
default = 5
|
||||
|
||||
|
||||
class FinalEXP(Range):
|
||||
"""Final Form Exp Multiplier"""
|
||||
display_name = "Final Form EXP"
|
||||
range_start = 1
|
||||
range_end = 10
|
||||
default = 3
|
||||
|
||||
|
||||
class MasterEXP(Range):
|
||||
"""Master Form Exp Multiplier"""
|
||||
display_name = "Master Form EXP"
|
||||
range_start = 1
|
||||
range_end = 10
|
||||
default = 3
|
||||
|
||||
|
||||
class LimitEXP(Range):
|
||||
"""Limit Form Exp Multiplier"""
|
||||
display_name = "Limit Form EXP"
|
||||
range_start = 1
|
||||
range_end = 10
|
||||
default = 3
|
||||
|
||||
|
||||
class WisdomEXP(Range):
|
||||
"""Wisdom Form Exp Multiplier"""
|
||||
display_name = "Wisdom Form EXP"
|
||||
range_start = 1
|
||||
range_end = 10
|
||||
default = 3
|
||||
|
||||
|
||||
class ValorEXP(Range):
|
||||
"""Valor Form Exp Multiplier"""
|
||||
display_name = "Valor Form EXP"
|
||||
range_start = 1
|
||||
range_end = 10
|
||||
default = 3
|
||||
|
||||
|
||||
class SummonEXP(Range):
|
||||
"""Summon Exp Multiplier"""
|
||||
display_name = "Summon level EXP"
|
||||
range_start = 1
|
||||
range_end = 10
|
||||
default = 5
|
||||
|
||||
|
||||
class Schmovement(Choice):
|
||||
"""Level of Growth You Start With"""
|
||||
display_name = "Schmovement"
|
||||
option_level_0 = 0
|
||||
option_level_1 = 1
|
||||
option_level_2 = 2
|
||||
option_level_3 = 3
|
||||
option_level_4 = 4
|
||||
default = 1
|
||||
|
||||
|
||||
class RandomGrowth(Range):
|
||||
"""Amount of Random Growth Abilities You Start With"""
|
||||
display_name = "Random Starting Growth"
|
||||
range_start = 0
|
||||
range_end = 20
|
||||
default = 0
|
||||
|
||||
|
||||
class KeybladeMin(Range):
|
||||
"""Minimum Stats for the Keyblade"""
|
||||
display_name = "Keyblade Minimum Stats"
|
||||
range_start = 0
|
||||
range_end = 20
|
||||
default = 3
|
||||
|
||||
|
||||
class KeybladeMax(Range):
|
||||
"""Maximum Stats for the Keyblade"""
|
||||
display_name = "Keyblade Max Stats"
|
||||
range_start = 0
|
||||
range_end = 20
|
||||
default = 7
|
||||
|
||||
|
||||
class Visitlocking(Choice):
|
||||
"""Determines the level of visit locking
|
||||
No Visit Locking:No visit locks(everything is sphere 1.Not Recommended)# BK is making a lot of money
|
||||
Second Visit Locking:Start with 13 visit locking items for every first visit.
|
||||
First and Second Visit Locking:One item for First Visit Two For Second Visit"""
|
||||
display_name = "Visit locking"
|
||||
option_no_visit_locking = 0 # starts with 27 visit locking
|
||||
option_second_visit_locking = 1 # starts with 13 (no icecream/picture)
|
||||
option_first_and_second_visit_locking = 2 # starts with nothing
|
||||
default = 2
|
||||
|
||||
|
||||
class RandomVisitLockingItem(Range):
|
||||
display_name = "Random Visit Locking Item"
|
||||
range_start = 0
|
||||
range_end = 27
|
||||
default = 3
|
||||
|
||||
|
||||
class SuperBosses(Toggle):
|
||||
"""Terra, Sephiroth and Data Fights Toggle."""
|
||||
display_name = "Super Bosses"
|
||||
default = False
|
||||
|
||||
|
||||
class Cups(Choice):
|
||||
"""Olympus Cups Toggles
|
||||
No Cups: No Cups.
|
||||
Cups: Has every cup except Paradox.
|
||||
Cups and Hades Paradox: Has Every Cup On."""
|
||||
display_name = "Olympus Cups"
|
||||
option_no_cups = 0
|
||||
option_cups = 1
|
||||
option_cups_and_hades_paradox = 2
|
||||
default = 1
|
||||
|
||||
|
||||
class LevelDepth(Choice):
|
||||
"""Determines How many locations you want on levels
|
||||
Level 50:23 checks spread through 50 levels
|
||||
Level 99:23 checks spread through 99 levels
|
||||
Level 50 sanity:check per level for 50 levels
|
||||
Level 99 sanity:check per level for 99 levels
|
||||
Level 1: no checks on levels(checks are replaced with stats)"""
|
||||
display_name = "Level Depth"
|
||||
option_level_50 = 0
|
||||
option_level_99 = 1
|
||||
option_level_50_sanity = 2
|
||||
option_level_99_sanity = 3
|
||||
option_level_1 = 4
|
||||
default = 0
|
||||
|
||||
|
||||
class PromiseCharm(Toggle):
|
||||
"""Add Promise Charm to the Pool"""
|
||||
display_name = "Promise Charm"
|
||||
default = False
|
||||
|
||||
|
||||
class KeybladeAbilities(Choice):
|
||||
"""Action:Has Action Abilities on Keyblades
|
||||
Support:Has Support Abilities on Keyblades"""
|
||||
display_name = "Keyblade Abilities"
|
||||
option_support = 0
|
||||
option_action = 1
|
||||
option_both = 2
|
||||
default = 2
|
||||
|
||||
|
||||
class BlacklistKeyblade(OptionSet):
|
||||
"""Black List these Abilities on Keyblades"""
|
||||
display_name = "Blacklist Keyblade Abilities"
|
||||
verify_item_name = True
|
||||
|
||||
|
||||
class Goal(Choice):
|
||||
"""Win Condition
|
||||
Three Proofs: Obtain the Three Proofs and Have a Gold Crown on Sora's Head.
|
||||
Lucky Emblem Hunt: Acquire The Amount of Lucky Emblems you have set.
|
||||
Hitlist: Kill the Superbosses on the "Hitlist" then synth ultima weapon."""
|
||||
display_name = "Goal"
|
||||
option_three_proofs = 0
|
||||
option_lucky_emblem_hunt = 1
|
||||
option_hitlist = 2
|
||||
default = 0
|
||||
|
||||
|
||||
class FinalXemnas(Toggle):
|
||||
"""Kill Final Xemnas to Beat the Game.
|
||||
This is in addition to your Goal. I.E. get three proofs+kill final Xemnas"""
|
||||
display_name = "Final Xemnas"
|
||||
default = True
|
||||
|
||||
|
||||
class LuckyEmblemsRequired(Range):
|
||||
"""Number of Lucky Emblems to collect to Open The Final Door bosses.
|
||||
If Goal is not Lucky Emblem Hunt this does nothing."""
|
||||
display_name = "Lucky Emblems Required"
|
||||
range_start = 0
|
||||
range_end = 60
|
||||
default = 25
|
||||
|
||||
|
||||
class LuckyEmblemsAmount(Range):
|
||||
"""Number of Lucky Emblems that are in the pool.
|
||||
If Goal is not Lucky Emblem Hunt this does nothing."""
|
||||
display_name = "Lucky Emblems Available"
|
||||
range_start = 0
|
||||
range_end = 60
|
||||
default = 40
|
||||
|
||||
|
||||
class BountyRequired(Range):
|
||||
"""Number of Bounties that are Required.
|
||||
If Goal is not Hitlist this does nothing."""
|
||||
display_name = "Bounties Required"
|
||||
range_start = 0
|
||||
range_end = 24
|
||||
default = 7
|
||||
|
||||
|
||||
class BountyAmount(Range):
|
||||
"""Number of Bounties that are in the pool.
|
||||
If Goal is not Hitlist this does nothing."""
|
||||
display_name = "Bounties Available"
|
||||
range_start = 0
|
||||
range_end = 24
|
||||
default = 13
|
||||
|
||||
|
||||
KH2_Options: typing.Dict[str, type(Option)] = {
|
||||
"Sora_Level_EXP": SoraEXP,
|
||||
"Final_Form_EXP": FinalEXP,
|
||||
"Master_Form_EXP": MasterEXP,
|
||||
"Limit_Form_EXP": LimitEXP,
|
||||
"Wisdom_Form_EXP": WisdomEXP,
|
||||
"Valor_Form_EXP": ValorEXP,
|
||||
"Summon_EXP": SummonEXP,
|
||||
"Schmovement": Schmovement,
|
||||
"Keyblade_Minimum": KeybladeMin,
|
||||
"Keyblade_Maximum": KeybladeMax,
|
||||
"Visitlocking": Visitlocking,
|
||||
"RandomVisitLockingItem": RandomVisitLockingItem,
|
||||
"SuperBosses": SuperBosses,
|
||||
"LevelDepth": LevelDepth,
|
||||
"Promise_Charm": PromiseCharm,
|
||||
"KeybladeAbilities": KeybladeAbilities,
|
||||
"BlacklistKeyblade": BlacklistKeyblade,
|
||||
"RandomGrowth": RandomGrowth,
|
||||
"Goal": Goal,
|
||||
"FinalXemnas": FinalXemnas,
|
||||
"LuckyEmblemsAmount": LuckyEmblemsAmount,
|
||||
"LuckyEmblemsRequired": LuckyEmblemsRequired,
|
||||
"BountyAmount": BountyAmount,
|
||||
"BountyRequired": BountyRequired,
|
||||
"Cups": Cups,
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,96 @@
|
|||
|
||||
from BaseClasses import MultiWorld
|
||||
|
||||
from .Items import exclusionItem_table
|
||||
from .Locations import STT_Checks, exclusion_table
|
||||
from .Names import LocationName, ItemName
|
||||
from ..generic.Rules import add_rule, forbid_items, set_rule
|
||||
|
||||
|
||||
def set_rules(world: MultiWorld, player: int):
|
||||
|
||||
add_rule(world.get_location(LocationName.RoxasDataMagicBoost, player),
|
||||
lambda state: state.kh_dataroxas(player))
|
||||
add_rule(world.get_location(LocationName.DemyxDataAPBoost, player),
|
||||
lambda state: state.kh_datademyx(player))
|
||||
add_rule(world.get_location(LocationName.SaixDataDefenseBoost, player),
|
||||
lambda state: state.kh_datasaix(player))
|
||||
add_rule(world.get_location(LocationName.XaldinDataDefenseBoost, player),
|
||||
lambda state: state.kh_dataxaldin(player))
|
||||
add_rule(world.get_location(LocationName.XemnasDataPowerBoost, player),
|
||||
lambda state: state.kh_dataxemnas(player))
|
||||
add_rule(world.get_location(LocationName.XigbarDataDefenseBoost, player),
|
||||
lambda state: state.kh_dataxigbar(player))
|
||||
add_rule(world.get_location(LocationName.VexenDataLostIllusion, player),
|
||||
lambda state: state.kh_dataaxel(player))
|
||||
add_rule(world.get_location(LocationName.LuxordDataAPBoost, player),
|
||||
lambda state: state.kh_dataluxord(player))
|
||||
|
||||
for slot, weapon in exclusion_table["WeaponSlots"].items():
|
||||
add_rule(world.get_location(slot, player), lambda state: state.has(weapon, player))
|
||||
formLogicTable = {
|
||||
ItemName.ValorForm: [LocationName.Valorlvl4,
|
||||
LocationName.Valorlvl5,
|
||||
LocationName.Valorlvl6,
|
||||
LocationName.Valorlvl7],
|
||||
ItemName.WisdomForm: [LocationName.Wisdomlvl4,
|
||||
LocationName.Wisdomlvl5,
|
||||
LocationName.Wisdomlvl6,
|
||||
LocationName.Wisdomlvl7],
|
||||
ItemName.LimitForm: [LocationName.Limitlvl4,
|
||||
LocationName.Limitlvl5,
|
||||
LocationName.Limitlvl6,
|
||||
LocationName.Limitlvl7],
|
||||
ItemName.MasterForm: [LocationName.Masterlvl4,
|
||||
LocationName.Masterlvl5,
|
||||
LocationName.Masterlvl6,
|
||||
LocationName.Masterlvl7],
|
||||
ItemName.FinalForm: [LocationName.Finallvl4,
|
||||
LocationName.Finallvl5,
|
||||
LocationName.Finallvl6,
|
||||
LocationName.Finallvl7]
|
||||
}
|
||||
|
||||
for form in formLogicTable:
|
||||
for i in range(4):
|
||||
location = world.get_location(formLogicTable[form][i], player)
|
||||
set_rule(location, lambda state, i=i + 1, form=form: state.kh_amount_of_forms(player, i, form))
|
||||
|
||||
if world.Goal[player] == "three_proofs":
|
||||
add_rule(world.get_location(LocationName.FinalXemnas, player),
|
||||
lambda state: state.kh_three_proof_unlocked(player))
|
||||
if world.FinalXemnas[player]:
|
||||
world.completion_condition[player] = lambda state: state.kh_victory(player)
|
||||
else:
|
||||
world.completion_condition[player] = lambda state: state.kh_three_proof_unlocked(player)
|
||||
# lucky emblem hunt
|
||||
elif world.Goal[player] == "lucky_emblem_hunt":
|
||||
add_rule(world.get_location(LocationName.FinalXemnas, player),
|
||||
lambda state: state.kh_lucky_emblem_unlocked(player, world.LuckyEmblemsRequired[player].value))
|
||||
if world.FinalXemnas[player]:
|
||||
world.completion_condition[player] = lambda state: state.kh_victory(player)
|
||||
else:
|
||||
world.completion_condition[player] = lambda state: state.kh_lucky_emblem_unlocked(player, world.LuckyEmblemsRequired[player].value)
|
||||
# hitlist if == 2
|
||||
else:
|
||||
add_rule(world.get_location(LocationName.FinalXemnas, player),
|
||||
lambda state: state.kh_hitlist(player, world.BountyRequired[player].value))
|
||||
if world.FinalXemnas[player]:
|
||||
world.completion_condition[player] = lambda state: state.kh_victory(player)
|
||||
else:
|
||||
world.completion_condition[player] = lambda state: state.kh_hitlist(player, world.BountyRequired[player].value)
|
||||
|
||||
# Forbid Abilities on popups due to game limitations
|
||||
for location in exclusion_table["Popups"]:
|
||||
forbid_items(world.get_location(location, player), exclusionItem_table["Ability"])
|
||||
forbid_items(world.get_location(location, player), exclusionItem_table["StatUps"])
|
||||
|
||||
for location in STT_Checks:
|
||||
forbid_items(world.get_location(location, player), exclusionItem_table["StatUps"])
|
||||
|
||||
# Santa's house also breaks with stat ups
|
||||
for location in {LocationName.SantasHouseChristmasTownMap, LocationName.SantasHouseAPBoost}:
|
||||
forbid_items(world.get_location(location, player), exclusionItem_table["StatUps"])
|
||||
|
||||
add_rule(world.get_location(LocationName.TransporttoRemembrance, player),
|
||||
lambda state: state.kh_transport(player))
|
|
@ -0,0 +1,845 @@
|
|||
import typing
|
||||
from .Names import LocationName
|
||||
|
||||
|
||||
class WorldLocationData(typing.NamedTuple):
|
||||
# save+
|
||||
addrObtained: int
|
||||
# bitmask
|
||||
bitIndex: int
|
||||
|
||||
|
||||
LoD_Checks = {
|
||||
LocationName.BambooGroveDarkShard: WorldLocationData(0x23AC, 1),
|
||||
LocationName.BambooGroveEther: WorldLocationData(0x23D9, 7),
|
||||
LocationName.BambooGroveMythrilShard: WorldLocationData(0x23DA, 0),
|
||||
LocationName.EncampmentAreaMap: WorldLocationData(0x1D94, 6),
|
||||
LocationName.Mission3: WorldLocationData(0x1D96, 0),
|
||||
LocationName.CheckpointHiPotion: WorldLocationData(0x23AD, 1),
|
||||
LocationName.CheckpointMythrilShard: WorldLocationData(0x23AD, 2),
|
||||
LocationName.MountainTrailLightningShard: WorldLocationData(0x23AD, 3),
|
||||
LocationName.MountainTrailRecoveryRecipe: WorldLocationData(0x23AD, 4),
|
||||
LocationName.MountainTrailEther: WorldLocationData(0x23AD, 5),
|
||||
LocationName.MountainTrailMythrilShard: WorldLocationData(0x23AD, 6),
|
||||
LocationName.VillageCaveAreaMap: WorldLocationData(0x1D96, 6),
|
||||
LocationName.VillageCaveDarkShard: WorldLocationData(0x23AE, 0),
|
||||
LocationName.VillageCaveAPBoost: WorldLocationData(0x23AD, 7),
|
||||
LocationName.VillageCaveBonus: WorldLocationData(0x3709, 3),
|
||||
LocationName.RidgeFrostShard: WorldLocationData(0x23AE, 1),
|
||||
LocationName.RidgeAPBoost: WorldLocationData(0x23AE, 2),
|
||||
LocationName.ShanYu: WorldLocationData(0x3705, 1),
|
||||
LocationName.ShanYuGetBonus: WorldLocationData(0x3705, 1),
|
||||
LocationName.GoofyShanYu: WorldLocationData(0x3705, 1),
|
||||
LocationName.HiddenDragon: WorldLocationData(0x1D92, 2),
|
||||
LocationName.ThroneRoomTornPages: WorldLocationData(0x23AE, 3),
|
||||
LocationName.ThroneRoomPalaceMap: WorldLocationData(0x23AE, 4),
|
||||
LocationName.ThroneRoomAPBoost: WorldLocationData(0x23AE, 5),
|
||||
LocationName.ThroneRoomQueenRecipe: WorldLocationData(0x23AE, 6),
|
||||
LocationName.ThroneRoomAPBoost2: WorldLocationData(0x23AE, 7),
|
||||
LocationName.ThroneRoomOgreShield: WorldLocationData(0x23AF, 0),
|
||||
LocationName.ThroneRoomMythrilCrystal: WorldLocationData(0x23AF, 1),
|
||||
LocationName.ThroneRoomOrichalcum: WorldLocationData(0x23AF, 2),
|
||||
LocationName.StormRider: WorldLocationData(0x3705, 2),
|
||||
LocationName.GoofyStormRider: WorldLocationData(0x3705, 2),
|
||||
|
||||
}
|
||||
AG_Checks = {
|
||||
LocationName.AgrabahMap: WorldLocationData(0x1D74, 4),
|
||||
LocationName.AgrabahDarkShard: WorldLocationData(0x23AF, 3),
|
||||
LocationName.AgrabahMythrilShard: WorldLocationData(0x23AF, 4),
|
||||
LocationName.AgrabahHiPotion: WorldLocationData(0x23AF, 5),
|
||||
LocationName.AgrabahAPBoost: WorldLocationData(0x23AF, 6),
|
||||
LocationName.AgrabahMythrilStone: WorldLocationData(0x23AF, 7),
|
||||
LocationName.AgrabahMythrilShard2: WorldLocationData(0x23B0, 0),
|
||||
LocationName.AgrabahSerenityShard: WorldLocationData(0x23DA, 3),
|
||||
LocationName.BazaarMythrilGem: WorldLocationData(0x23B0, 1),
|
||||
LocationName.BazaarPowerShard: WorldLocationData(0x23B0, 2),
|
||||
LocationName.BazaarHiPotion: WorldLocationData(0x23B0, 3),
|
||||
LocationName.BazaarAPBoost: WorldLocationData(0x23B0, 4),
|
||||
LocationName.BazaarMythrilShard: WorldLocationData(0x23B0, 5),
|
||||
LocationName.PalaceWallsSkillRing: WorldLocationData(0x23B0, 6),
|
||||
LocationName.PalaceWallsMythrilStone: WorldLocationData(0x23DB, 5),
|
||||
LocationName.CaveEntrancePowerStone: WorldLocationData(0x23B0, 7),
|
||||
LocationName.CaveEntranceMythrilShard: WorldLocationData(0x23B1, 0),
|
||||
LocationName.ValleyofStoneMythrilStone: WorldLocationData(0x23B1, 2),
|
||||
LocationName.ValleyofStoneAPBoost: WorldLocationData(0x23B1, 3),
|
||||
LocationName.ValleyofStoneMythrilShard: WorldLocationData(0x23B1, 4),
|
||||
LocationName.ValleyofStoneHiPotion: WorldLocationData(0x23B1, 5),
|
||||
LocationName.AbuEscort: WorldLocationData(0x3709, 2),
|
||||
LocationName.DonaldAbuEscort: WorldLocationData(0x3709, 2),
|
||||
LocationName.ChasmofChallengesCaveofWondersMap: WorldLocationData(0x23D8, 7),
|
||||
LocationName.ChasmofChallengesAPBoost: WorldLocationData(0x23B1, 6),
|
||||
LocationName.TreasureRoom: WorldLocationData(0x3709, 6),
|
||||
LocationName.GoofyTreasureRoom: WorldLocationData(0x3709, 6),
|
||||
LocationName.TreasureRoomAPBoost: WorldLocationData(0x23DA, 4),
|
||||
LocationName.TreasureRoomSerenityGem: WorldLocationData(0x23DA, 5),
|
||||
LocationName.ElementalLords: WorldLocationData(0x3708, 5),
|
||||
LocationName.LampCharm: WorldLocationData(0x1D72, 4),
|
||||
LocationName.RuinedChamberTornPages: WorldLocationData(0x23B1, 1),
|
||||
LocationName.RuinedChamberRuinsMap: WorldLocationData(0x23D8, 6),
|
||||
LocationName.GenieJafar: WorldLocationData(0x3705, 7),
|
||||
LocationName.WishingLamp: WorldLocationData(0x1D77, 3),
|
||||
|
||||
}
|
||||
DC_Checks = {
|
||||
LocationName.DCCourtyardMythrilShard: WorldLocationData(0x23B4, 1),
|
||||
LocationName.DCCourtyardStarRecipe: WorldLocationData(0x23B4, 2),
|
||||
LocationName.DCCourtyardAPBoost: WorldLocationData(0x23B4, 3),
|
||||
LocationName.DCCourtyardMythrilStone: WorldLocationData(0x23B4, 4),
|
||||
LocationName.DCCourtyardBlazingStone: WorldLocationData(0x23B4, 5),
|
||||
LocationName.DCCourtyardBlazingShard: WorldLocationData(0x23B4, 6),
|
||||
LocationName.DCCourtyardMythrilShard2: WorldLocationData(0x23B4, 7),
|
||||
LocationName.LibraryTornPages: WorldLocationData(0x23B4, 0),
|
||||
LocationName.DisneyCastleMap: WorldLocationData(0x1E10, 4),
|
||||
LocationName.MinnieEscort: WorldLocationData(0x3708, 6),
|
||||
LocationName.MinnieEscortGetBonus: WorldLocationData(0x3708, 6),
|
||||
LocationName.LingeringWillBonus: WorldLocationData(0x370C, 6),
|
||||
LocationName.LingeringWillProofofConnection: WorldLocationData(0x370C, 6),
|
||||
LocationName.LingeringWillManifestIllusion: WorldLocationData(0x370C, 6),
|
||||
}
|
||||
TR_Checks = {
|
||||
LocationName.CornerstoneHillMap: WorldLocationData(0x23B2, 0),
|
||||
LocationName.CornerstoneHillFrostShard: WorldLocationData(0x23B2, 1),
|
||||
LocationName.PierMythrilShard: WorldLocationData(0x23B2, 3),
|
||||
LocationName.PierHiPotion: WorldLocationData(0x23B2, 4),
|
||||
LocationName.WaterwayMythrilStone: WorldLocationData(0x23B2, 5),
|
||||
LocationName.WaterwayAPBoost: WorldLocationData(0x23B2, 6),
|
||||
LocationName.WaterwayFrostStone: WorldLocationData(0x23B2, 7),
|
||||
LocationName.WindowofTimeMap: WorldLocationData(0x1E32, 4),
|
||||
LocationName.BoatPete: WorldLocationData(0x3706, 0),
|
||||
LocationName.DonaldBoatPete: WorldLocationData(0x3706, 0),
|
||||
LocationName.DonaldBoatPeteGetBonus: WorldLocationData(0x3706, 0),
|
||||
LocationName.FuturePete: WorldLocationData(0x3706, 1),
|
||||
LocationName.FuturePeteGetBonus: WorldLocationData(0x3706, 1),
|
||||
LocationName.GoofyFuturePete: WorldLocationData(0x3706, 1),
|
||||
LocationName.Monochrome: WorldLocationData(0x1E33, 2),
|
||||
LocationName.WisdomForm: WorldLocationData(0x1E33, 2),
|
||||
}
|
||||
|
||||
HundredAcreChecks = {
|
||||
LocationName.PoohsHouse100AcreWoodMap: WorldLocationData(0x23C9, 7),
|
||||
LocationName.PoohsHouseAPBoost: WorldLocationData(0x23B5, 4),
|
||||
LocationName.PoohsHouseMythrilStone: WorldLocationData(0x23B5, 5),
|
||||
LocationName.PigletsHouseDefenseBoost: WorldLocationData(0x23B6, 4),
|
||||
LocationName.PigletsHouseAPBoost: WorldLocationData(0x23B6, 2),
|
||||
LocationName.PigletsHouseMythrilGem: WorldLocationData(0x23B6, 3),
|
||||
LocationName.RabbitsHouseDrawRing: WorldLocationData(0x23CA, 0),
|
||||
LocationName.RabbitsHouseMythrilCrystal: WorldLocationData(0x23B5, 7),
|
||||
LocationName.RabbitsHouseAPBoost: WorldLocationData(0x23B6, 0),
|
||||
LocationName.KangasHouseMagicBoost: WorldLocationData(0x23B6, 7),
|
||||
LocationName.KangasHouseAPBoost: WorldLocationData(0x23B6, 5),
|
||||
LocationName.KangasHouseOrichalcum: WorldLocationData(0x23B6, 6),
|
||||
LocationName.SpookyCaveMythrilGem: WorldLocationData(0x23B7, 1),
|
||||
LocationName.SpookyCaveAPBoost: WorldLocationData(0x23B7, 2),
|
||||
LocationName.SpookyCaveOrichalcum: WorldLocationData(0x23B7, 3),
|
||||
LocationName.SpookyCaveGuardRecipe: WorldLocationData(0x23B7, 4),
|
||||
LocationName.SpookyCaveMythrilCrystal: WorldLocationData(0x23B7, 6),
|
||||
LocationName.SpookyCaveAPBoost2: WorldLocationData(0x23B7, 7),
|
||||
LocationName.SweetMemories: WorldLocationData(0x1DB4, 6),
|
||||
LocationName.SpookyCaveMap: WorldLocationData(0x1DB4, 6),
|
||||
LocationName.StarryHillCosmicRing: WorldLocationData(0x23C9, 6),
|
||||
LocationName.StarryHillStyleRecipe: WorldLocationData(0x23B5, 1),
|
||||
LocationName.StarryHillCureElement: WorldLocationData(0x1DB5, 5),
|
||||
LocationName.StarryHillOrichalcumPlus: WorldLocationData(0x1DB5, 5),
|
||||
}
|
||||
Oc_Checks = {
|
||||
LocationName.PassageMythrilShard: WorldLocationData(0x23B9, 6),
|
||||
LocationName.PassageMythrilStone: WorldLocationData(0x23B9, 7),
|
||||
LocationName.PassageEther: WorldLocationData(0x23BA, 0),
|
||||
LocationName.PassageAPBoost: WorldLocationData(0x23BA, 1),
|
||||
LocationName.PassageHiPotion: WorldLocationData(0x23BA, 2),
|
||||
LocationName.InnerChamberUnderworldMap: WorldLocationData(0x23B8, 4),
|
||||
LocationName.InnerChamberMythrilShard: WorldLocationData(0x23B8, 3),
|
||||
LocationName.Cerberus: WorldLocationData(0x3704, 5),
|
||||
LocationName.ColiseumMap: WorldLocationData(0x1D5A, 4),
|
||||
LocationName.Urns: WorldLocationData(0x370B, 1),
|
||||
LocationName.UnderworldEntrancePowerBoost: WorldLocationData(0x23B8, 0),
|
||||
LocationName.CavernsEntranceLucidShard: WorldLocationData(0x23B8, 5),
|
||||
LocationName.CavernsEntranceAPBoost: WorldLocationData(0x23B8, 6),
|
||||
LocationName.CavernsEntranceMythrilShard: WorldLocationData(0x23DA, 6),
|
||||
LocationName.TheLostRoadBrightShard: WorldLocationData(0x23BA, 3),
|
||||
LocationName.TheLostRoadEther: WorldLocationData(0x23BA, 4),
|
||||
LocationName.TheLostRoadMythrilShard: WorldLocationData(0x23BA, 5),
|
||||
LocationName.TheLostRoadMythrilStone: WorldLocationData(0x23BA, 6),
|
||||
LocationName.AtriumLucidStone: WorldLocationData(0x23BA, 7),
|
||||
LocationName.AtriumAPBoost: WorldLocationData(0x23BB, 0),
|
||||
LocationName.DemyxOC: WorldLocationData(0x370B, 2),
|
||||
LocationName.DonaldDemyxOC: WorldLocationData(0x370B, 2),
|
||||
LocationName.SecretAnsemReport5: WorldLocationData(0x1D5B, 3),
|
||||
LocationName.OlympusStone: WorldLocationData(0x1D5B, 3),
|
||||
LocationName.TheLockCavernsMap: WorldLocationData(0x23B9, 4),
|
||||
LocationName.TheLockMythrilShard: WorldLocationData(0x23B9, 0),
|
||||
LocationName.TheLockAPBoost: WorldLocationData(0x23B9, 2),
|
||||
LocationName.PeteOC: WorldLocationData(0x3704, 6),
|
||||
LocationName.GoofyPeteOC: WorldLocationData(0x3704, 6),
|
||||
LocationName.Hydra: WorldLocationData(0x3704, 7),
|
||||
LocationName.HydraGetBonus: WorldLocationData(0x3704, 7),
|
||||
LocationName.HerosCrest: WorldLocationData(0x1D55, 7),
|
||||
LocationName.AuronsStatue: WorldLocationData(0x1D5F, 2),
|
||||
LocationName.Hades: WorldLocationData(0x3705, 0),
|
||||
LocationName.HadesGetBonus: WorldLocationData(0x3705, 0),
|
||||
LocationName.GuardianSoul: WorldLocationData(0x1D56, 5),
|
||||
LocationName.ProtectBeltPainandPanicCup: WorldLocationData(0x1D57, 6),
|
||||
LocationName.SerenityGemPainandPanicCup: WorldLocationData(0x1D57, 6),
|
||||
LocationName.RisingDragonCerberusCup: WorldLocationData(0x1D58, 0),
|
||||
LocationName.SerenityCrystalCerberusCup: WorldLocationData(0x1D58, 0),
|
||||
LocationName.GenjiShieldTitanCup: WorldLocationData(0x1D58, 1),
|
||||
LocationName.SkillfulRingTitanCup: WorldLocationData(0x1D58, 1),
|
||||
LocationName.FatalCrestGoddessofFateCup: WorldLocationData(0x1D58, 4),
|
||||
LocationName.OrichalcumPlusGoddessofFateCup: WorldLocationData(0x1D58, 4),
|
||||
LocationName.HadesCupTrophyParadoxCups: WorldLocationData(0x1D5A, 1),
|
||||
}
|
||||
|
||||
BC_Checks = {
|
||||
LocationName.BCCourtyardAPBoost: WorldLocationData(0x23BB, 5),
|
||||
LocationName.BCCourtyardHiPotion: WorldLocationData(0x23BB, 6),
|
||||
LocationName.BCCourtyardMythrilShard: WorldLocationData(0x23DA, 7),
|
||||
LocationName.BellesRoomCastleMap: WorldLocationData(0x23BB, 2),
|
||||
LocationName.BellesRoomMegaRecipe: WorldLocationData(0x23BB, 3),
|
||||
LocationName.TheEastWingMythrilShard: WorldLocationData(0x23BB, 7),
|
||||
LocationName.TheEastWingTent: WorldLocationData(0x23BC, 0),
|
||||
LocationName.TheWestHallHiPotion: WorldLocationData(0x23BC, 1),
|
||||
LocationName.TheWestHallPowerShard: WorldLocationData(0x23BC, 3),
|
||||
LocationName.TheWestHallAPBoostPostDungeon: WorldLocationData(0x23BC, 5),
|
||||
LocationName.TheWestHallBrightStone: WorldLocationData(0x23DB, 0),
|
||||
LocationName.TheWestHallMythrilShard: WorldLocationData(0x23BC, 2),
|
||||
LocationName.TheWestHallMythrilShard2: WorldLocationData(0x23BC, 4),
|
||||
LocationName.Thresholder: WorldLocationData(0x3704, 2),
|
||||
LocationName.DonaldThresholder: WorldLocationData(0x3704, 2),
|
||||
LocationName.DungeonBasementMap: WorldLocationData(0x23BD, 0),
|
||||
LocationName.DungeonAPBoost: WorldLocationData(0x23BD, 1),
|
||||
LocationName.SecretPassageMythrilShard: WorldLocationData(0x23BD, 2),
|
||||
LocationName.SecretPassageHiPotion: WorldLocationData(0x23BD, 5),
|
||||
LocationName.SecretPassageLucidShard: WorldLocationData(0x23BD, 3),
|
||||
LocationName.TheWestWingMythrilShard: WorldLocationData(0x23BC, 6),
|
||||
LocationName.TheWestWingTent: WorldLocationData(0x23BC, 7),
|
||||
LocationName.Beast: WorldLocationData(0x3705, 4),
|
||||
LocationName.GoofyBeast: WorldLocationData(0x3705, 4),
|
||||
LocationName.TheBeastsRoomBlazingShard: WorldLocationData(0x23BB, 4),
|
||||
LocationName.DarkThorn: WorldLocationData(0x3704, 3),
|
||||
LocationName.DarkThornGetBonus: WorldLocationData(0x3704, 3),
|
||||
LocationName.DarkThornCureElement: WorldLocationData(0x1D32, 5),
|
||||
LocationName.RumblingRose: WorldLocationData(0x1D39, 0),
|
||||
LocationName.CastleWallsMap: WorldLocationData(0x1D39, 0),
|
||||
LocationName.Xaldin: WorldLocationData(0x3704, 4),
|
||||
LocationName.XaldinGetBonus: WorldLocationData(0x3704, 4),
|
||||
LocationName.DonaldXaldinGetBonus: WorldLocationData(0x3704, 4),
|
||||
LocationName.SecretAnsemReport4: WorldLocationData(0x1D31, 2),
|
||||
LocationName.XaldinDataDefenseBoost: WorldLocationData(0x1D34, 7),
|
||||
}
|
||||
SP_Checks = {
|
||||
LocationName.PitCellAreaMap: WorldLocationData(0x23CA, 2),
|
||||
LocationName.PitCellMythrilCrystal: WorldLocationData(0x23BD, 6),
|
||||
LocationName.CanyonDarkCrystal: WorldLocationData(0x23BE, 1),
|
||||
LocationName.CanyonMythrilStone: WorldLocationData(0x23BE, 2),
|
||||
LocationName.CanyonMythrilGem: WorldLocationData(0x23BE, 3),
|
||||
LocationName.CanyonFrostCrystal: WorldLocationData(0x23DB, 6),
|
||||
LocationName.Screens: WorldLocationData(0x3709, 5),
|
||||
LocationName.DonaldScreens: WorldLocationData(0x3709, 5),
|
||||
LocationName.HallwayPowerCrystal: WorldLocationData(0x23BE, 4),
|
||||
LocationName.HallwayAPBoost: WorldLocationData(0x23BE, 5),
|
||||
LocationName.CommunicationsRoomIOTowerMap: WorldLocationData(0x23BF, 1),
|
||||
LocationName.CommunicationsRoomGaiaBelt: WorldLocationData(0x23DA, 1),
|
||||
LocationName.HostileProgram: WorldLocationData(0x3707, 7),
|
||||
LocationName.HostileProgramGetBonus: WorldLocationData(0x3707, 7),
|
||||
LocationName.GoofyHostileProgram: WorldLocationData(0x3707, 7),
|
||||
LocationName.PhotonDebugger: WorldLocationData(0x1EB2, 3),
|
||||
LocationName.SolarSailer: WorldLocationData(0x370B, 5),
|
||||
LocationName.DonaldSolarSailer: WorldLocationData(0x370B, 5),
|
||||
LocationName.CentralComputerCoreAPBoost: WorldLocationData(0x23BF, 4),
|
||||
LocationName.CentralComputerCoreOrichalcumPlus: WorldLocationData(0x23BF, 5),
|
||||
LocationName.CentralComputerCoreCosmicArts: WorldLocationData(0x23BF, 6),
|
||||
LocationName.CentralComputerCoreMap: WorldLocationData(0x23D9, 0),
|
||||
LocationName.MCP: WorldLocationData(0x3708, 0),
|
||||
LocationName.MCPGetBonus: WorldLocationData(0x3708, 0),
|
||||
}
|
||||
HT_Checks = {
|
||||
LocationName.GraveyardMythrilShard: WorldLocationData(0x23C0, 2),
|
||||
LocationName.GraveyardSerenityGem: WorldLocationData(0x23C0, 3),
|
||||
LocationName.FinklesteinsLabHalloweenTownMap: WorldLocationData(0x23C0, 1),
|
||||
LocationName.TownSquareMythrilStone: WorldLocationData(0x23BF, 7),
|
||||
LocationName.TownSquareEnergyShard: WorldLocationData(0x23C0, 0),
|
||||
LocationName.HinterlandsLightningShard: WorldLocationData(0x23C0, 4),
|
||||
LocationName.HinterlandsMythrilStone: WorldLocationData(0x23C0, 5),
|
||||
LocationName.HinterlandsAPBoost: WorldLocationData(0x23C0, 6),
|
||||
LocationName.CandyCaneLaneMegaPotion: WorldLocationData(0x23C1, 0),
|
||||
LocationName.CandyCaneLaneMythrilGem: WorldLocationData(0x23C1, 1),
|
||||
LocationName.CandyCaneLaneLightningStone: WorldLocationData(0x23C1, 2),
|
||||
LocationName.CandyCaneLaneMythrilStone: WorldLocationData(0x23C1, 3),
|
||||
LocationName.SantasHouseChristmasTownMap: WorldLocationData(0x23C1, 6),
|
||||
LocationName.SantasHouseAPBoost: WorldLocationData(0x23C1, 4),
|
||||
LocationName.PrisonKeeper: WorldLocationData(0x3706, 2),
|
||||
LocationName.DonaldPrisonKeeper: WorldLocationData(0x3706, 2),
|
||||
LocationName.OogieBoogie: WorldLocationData(0x3706, 3),
|
||||
LocationName.GoofyOogieBoogie: WorldLocationData(0x3706, 3),
|
||||
LocationName.OogieBoogieMagnetElement: WorldLocationData(0x1E53, 2),
|
||||
LocationName.Lock: WorldLocationData(0x3709, 0),
|
||||
LocationName.GoofyLock: WorldLocationData(0x3709, 0),
|
||||
LocationName.Present: WorldLocationData(0x1E55, 1),
|
||||
LocationName.DecoyPresents: WorldLocationData(0x1E55, 4),
|
||||
LocationName.Experiment: WorldLocationData(0x3706, 4),
|
||||
LocationName.DonaldExperiment: WorldLocationData(0x3706, 4),
|
||||
LocationName.DecisivePumpkin: WorldLocationData(0x1E56, 0),
|
||||
|
||||
}
|
||||
PR_Checks = {
|
||||
LocationName.RampartNavalMap: WorldLocationData(0x23C2, 1),
|
||||
LocationName.RampartMythrilStone: WorldLocationData(0x23C2, 2),
|
||||
LocationName.RampartDarkShard: WorldLocationData(0x23C2, 3),
|
||||
LocationName.TownDarkStone: WorldLocationData(0x23C2, 4),
|
||||
LocationName.TownAPBoost: WorldLocationData(0x23C2, 5),
|
||||
LocationName.TownMythrilShard: WorldLocationData(0x23C2, 6),
|
||||
LocationName.TownMythrilGem: WorldLocationData(0x23C2, 7),
|
||||
LocationName.CaveMouthBrightShard: WorldLocationData(0x23C3, 1),
|
||||
LocationName.CaveMouthMythrilShard: WorldLocationData(0x23C3, 2),
|
||||
LocationName.IsladeMuertaMap: WorldLocationData(0x1E92, 4),
|
||||
LocationName.BoatFight: WorldLocationData(0x370B, 6),
|
||||
LocationName.DonaldBoatFight: WorldLocationData(0x370B, 6),
|
||||
LocationName.InterceptorBarrels: WorldLocationData(0x3708, 7),
|
||||
LocationName.GoofyInterceptorBarrels: WorldLocationData(0x3708, 7),
|
||||
LocationName.PowderStoreAPBoost1: WorldLocationData(0x23CA, 7),
|
||||
LocationName.PowderStoreAPBoost2: WorldLocationData(0x23CB, 0),
|
||||
LocationName.MoonlightNookMythrilShard: WorldLocationData(0x23C3, 4),
|
||||
LocationName.MoonlightNookSerenityGem: WorldLocationData(0x23C3, 5),
|
||||
LocationName.MoonlightNookPowerStone: WorldLocationData(0x23CB, 1),
|
||||
LocationName.Barbossa: WorldLocationData(0x3706, 5),
|
||||
LocationName.BarbossaGetBonus: WorldLocationData(0x3706, 5),
|
||||
LocationName.GoofyBarbossa: WorldLocationData(0x3706, 5),
|
||||
LocationName.GoofyBarbossaGetBonus: WorldLocationData(0x3706, 5),
|
||||
LocationName.FollowtheWind: WorldLocationData(0x1E93, 6),
|
||||
LocationName.GrimReaper1: WorldLocationData(0x370B, 3),
|
||||
LocationName.GoofyGrimReaper1: WorldLocationData(0x370B, 3),
|
||||
LocationName.InterceptorsHoldFeatherCharm: WorldLocationData(0x23C3, 3),
|
||||
LocationName.SeadriftKeepAPBoost: WorldLocationData(0x23C3, 6),
|
||||
LocationName.SeadriftKeepOrichalcum: WorldLocationData(0x23C3, 7),
|
||||
LocationName.SeadriftKeepMeteorStaff: WorldLocationData(0x23CB, 2),
|
||||
LocationName.SeadriftRowSerenityGem: WorldLocationData(0x23C4, 0),
|
||||
LocationName.SeadriftRowKingRecipe: WorldLocationData(0x23C4, 1),
|
||||
LocationName.SeadriftRowMythrilCrystal: WorldLocationData(0x23CB, 3),
|
||||
LocationName.SeadriftRowCursedMedallion: WorldLocationData(0x1E95, 2),
|
||||
LocationName.SeadriftRowShipGraveyardMap: WorldLocationData(0x1E95, 2),
|
||||
LocationName.GrimReaper2: WorldLocationData(0x3706, 6),
|
||||
LocationName.DonaladGrimReaper2: WorldLocationData(0x3706, 6),
|
||||
LocationName.SecretAnsemReport6: WorldLocationData(0x1E95, 7),
|
||||
|
||||
}
|
||||
HB_Checks = {
|
||||
LocationName.MarketplaceMap: WorldLocationData(0x1D17, 4),
|
||||
LocationName.BoroughDriveRecovery: WorldLocationData(0x23C6, 1),
|
||||
LocationName.BoroughAPBoost: WorldLocationData(0x23C6, 2),
|
||||
LocationName.BoroughHiPotion: WorldLocationData(0x23C6, 3),
|
||||
LocationName.BoroughMythrilShard: WorldLocationData(0x23C8, 7),
|
||||
LocationName.BoroughDarkShard: WorldLocationData(0x23DB, 1),
|
||||
LocationName.MerlinsHouseMembershipCard: WorldLocationData(0x1D10, 6),
|
||||
LocationName.MerlinsHouseBlizzardElement: WorldLocationData(0x1D10, 6),
|
||||
# you cannot get these checks without baily so they are all on the same memory value.
|
||||
LocationName.Bailey: WorldLocationData(0x3709, 7),
|
||||
LocationName.BaileySecretAnsemReport7: WorldLocationData(0x3709, 7),
|
||||
LocationName.BaseballCharm: WorldLocationData(0x3709, 7),
|
||||
LocationName.PosternCastlePerimeterMap: WorldLocationData(0x23C9, 4),
|
||||
LocationName.PosternMythrilGem: WorldLocationData(0x23C5, 4),
|
||||
LocationName.PosternAPBoost: WorldLocationData(0x23C5, 5),
|
||||
LocationName.CorridorsMythrilStone: WorldLocationData(0x23C6, 7),
|
||||
LocationName.CorridorsMythrilCrystal: WorldLocationData(0x23C7, 0),
|
||||
LocationName.CorridorsDarkCrystal: WorldLocationData(0x23C7, 1),
|
||||
LocationName.CorridorsAPBoost: WorldLocationData(0x23C9, 1),
|
||||
# this is probably gonna be wrong
|
||||
LocationName.AnsemsStudyMasterForm: WorldLocationData(0x1D12, 6),
|
||||
LocationName.AnsemsStudySleepingLion: WorldLocationData(0x1D12, 6),
|
||||
LocationName.AnsemsStudySkillRecipe: WorldLocationData(0x23C4, 7),
|
||||
LocationName.AnsemsStudyUkuleleCharm: WorldLocationData(0x23C4, 6),
|
||||
LocationName.RestorationSiteMoonRecipe: WorldLocationData(0x23C9, 3),
|
||||
LocationName.RestorationSiteAPBoost: WorldLocationData(0x23DB, 2),
|
||||
LocationName.DemyxHB: WorldLocationData(0x3707, 4),
|
||||
LocationName.DemyxHBGetBonus: WorldLocationData(0x3707, 4),
|
||||
LocationName.DonaldDemyxHBGetBonus: WorldLocationData(0x3707, 4),
|
||||
LocationName.FFFightsCureElement: WorldLocationData(0x1D14, 6),
|
||||
LocationName.CrystalFissureTornPages: WorldLocationData(0x23C4, 2),
|
||||
LocationName.CrystalFissureTheGreatMawMap: WorldLocationData(0x23D9, 1),
|
||||
LocationName.CrystalFissureEnergyCrystal: WorldLocationData(0x23C4, 3),
|
||||
LocationName.CrystalFissureAPBoost: WorldLocationData(0x23C4, 4),
|
||||
LocationName.ThousandHeartless: WorldLocationData(0x370B, 4),
|
||||
LocationName.ThousandHeartlessSecretAnsemReport1: WorldLocationData(0x1D19, 3),
|
||||
LocationName.ThousandHeartlessIceCream: WorldLocationData(0x1D23, 0),
|
||||
LocationName.ThousandHeartlessPicture: WorldLocationData(0x1D23, 0),
|
||||
LocationName.PosternGullWing: WorldLocationData(0x23D9, 3),
|
||||
LocationName.HeartlessManufactoryCosmicChain: WorldLocationData(0x23C9, 5),
|
||||
LocationName.SephirothBonus: WorldLocationData(0x3708, 3),
|
||||
LocationName.SephirothFenrir: WorldLocationData(0x1D1F, 7),
|
||||
LocationName.WinnersProof: WorldLocationData(0x1D27, 5),
|
||||
LocationName.ProofofPeace: WorldLocationData(0x1D27, 5),
|
||||
|
||||
LocationName.CoRDepthsAPBoost: WorldLocationData(0x23DC, 2),
|
||||
LocationName.CoRDepthsPowerCrystal: WorldLocationData(0x23DC, 3),
|
||||
LocationName.CoRDepthsFrostCrystal: WorldLocationData(0x23DC, 4),
|
||||
LocationName.CoRDepthsManifestIllusion: WorldLocationData(0x23DC, 5),
|
||||
LocationName.CoRDepthsAPBoost2: WorldLocationData(0x23DC, 6),
|
||||
LocationName.CoRMineshaftLowerLevelDepthsofRemembranceMap: WorldLocationData(0x23DE, 4),
|
||||
LocationName.CoRMineshaftLowerLevelAPBoost: WorldLocationData(0x23DE, 2),
|
||||
LocationName.CoRDepthsUpperLevelRemembranceGem: WorldLocationData(0x23DC, 7),
|
||||
LocationName.CoRMiningAreaSerenityGem: WorldLocationData(0x23DD, 0),
|
||||
LocationName.CoRMiningAreaAPBoost: WorldLocationData(0x23DD, 1),
|
||||
LocationName.CoRMiningAreaSerenityCrystal: WorldLocationData(0x23DD, 2),
|
||||
LocationName.CoRMiningAreaManifestIllusion: WorldLocationData(0x23DD, 3),
|
||||
LocationName.CoRMiningAreaSerenityGem2: WorldLocationData(0x23DD, 4),
|
||||
LocationName.CoRMiningAreaDarkRemembranceMap: WorldLocationData(0x23DD, 5),
|
||||
LocationName.CoRMineshaftMidLevelPowerBoost: WorldLocationData(0x23DE, 5),
|
||||
LocationName.CoREngineChamberSerenityCrystal: WorldLocationData(0x23DD, 6),
|
||||
LocationName.CoREngineChamberRemembranceCrystal: WorldLocationData(0x23DD, 7),
|
||||
LocationName.CoREngineChamberAPBoost: WorldLocationData(0x23DE, 0),
|
||||
LocationName.CoREngineChamberManifestIllusion: WorldLocationData(0x23DE, 1),
|
||||
LocationName.CoRMineshaftUpperLevelMagicBoost: WorldLocationData(0x23DE, 6),
|
||||
LocationName.CoRMineshaftUpperLevelAPBoost: WorldLocationData(0x23DE, 3),
|
||||
LocationName.TransporttoRemembrance: WorldLocationData(0x370D, 0),
|
||||
|
||||
LocationName.LexaeusBonus: WorldLocationData(0x370C, 1),
|
||||
LocationName.LexaeusASStrengthBeyondStrength: WorldLocationData(0x370C, 1),
|
||||
LocationName.LexaeusDataLostIllusion: WorldLocationData(0x370C, 1), #
|
||||
LocationName.MarluxiaGetBonus: WorldLocationData(0x370C, 3),
|
||||
LocationName.MarluxiaASEternalBlossom: WorldLocationData(0x370C, 3),
|
||||
LocationName.MarluxiaDataLostIllusion: WorldLocationData(0x370C, 3), #
|
||||
LocationName.ZexionBonus: WorldLocationData(0x370C, 2),
|
||||
LocationName.GoofyZexion: WorldLocationData(0x370C, 2),
|
||||
LocationName.ZexionASBookofShadows: WorldLocationData(0x370C, 2),
|
||||
LocationName.ZexionDataLostIllusion: WorldLocationData(0x370C, 2), #
|
||||
LocationName.LarxeneBonus: WorldLocationData(0x370C, 4),
|
||||
LocationName.LarxeneASCloakedThunder: WorldLocationData(0x370C, 4),
|
||||
LocationName.LarxeneDataLostIllusion: WorldLocationData(0x370C, 4), #
|
||||
LocationName.VexenBonus: WorldLocationData(0x370C, 0),
|
||||
LocationName.VexenASRoadtoDiscovery: WorldLocationData(0x370C, 0),
|
||||
LocationName.VexenDataLostIllusion: WorldLocationData(0x370C, 0), #
|
||||
LocationName.DemyxDataAPBoost: WorldLocationData(0x1D26, 5),
|
||||
LocationName.GardenofAssemblageMap: WorldLocationData(0x23DF, 1),
|
||||
LocationName.GoALostIllusion: WorldLocationData(0x23DF, 2),
|
||||
LocationName.ProofofNonexistence: WorldLocationData(0x23DF, 3),
|
||||
# given when you talk to the computer
|
||||
LocationName.KingdomKeySlot: WorldLocationData(0x1D27, 3),
|
||||
LocationName.MagesStaff: WorldLocationData(0x1D27, 3),
|
||||
LocationName.KnightsShield: WorldLocationData(0x1D27, 3),
|
||||
LocationName.DonaldStarting1: WorldLocationData(0x1D27, 3),
|
||||
LocationName.DonaldStarting2: WorldLocationData(0x1D27, 3),
|
||||
LocationName.GoofyStarting1: WorldLocationData(0x1D27, 3),
|
||||
LocationName.GoofyStarting2: WorldLocationData(0x1D27, 3),
|
||||
LocationName.Crit_1: WorldLocationData(0x1D27, 3),
|
||||
LocationName.Crit_2: WorldLocationData(0x1D27, 3),
|
||||
LocationName.Crit_3: WorldLocationData(0x1D27, 3),
|
||||
LocationName.Crit_4: WorldLocationData(0x1D27, 3),
|
||||
LocationName.Crit_5: WorldLocationData(0x1D27, 3),
|
||||
LocationName.Crit_6: WorldLocationData(0x1D27, 3),
|
||||
LocationName.Crit_7: WorldLocationData(0x1D27, 3),
|
||||
|
||||
}
|
||||
PL_Checks = {
|
||||
LocationName.GorgeSavannahMap: WorldLocationData(0x23D9, 4),
|
||||
LocationName.GorgeDarkGem: WorldLocationData(0x23CF, 0),
|
||||
LocationName.GorgeMythrilStone: WorldLocationData(0x23CF, 1),
|
||||
LocationName.ElephantGraveyardFrostGem: WorldLocationData(0x23CE, 5),
|
||||
LocationName.ElephantGraveyardMythrilStone: WorldLocationData(0x23CE, 6),
|
||||
LocationName.ElephantGraveyardBrightStone: WorldLocationData(0x23CE, 7),
|
||||
LocationName.ElephantGraveyardAPBoost: WorldLocationData(0x23DB, 3),
|
||||
LocationName.ElephantGraveyardMythrilShard: WorldLocationData(0x23DB, 4),
|
||||
LocationName.PrideRockMap: WorldLocationData(0x23D0, 3),
|
||||
LocationName.PrideRockMythrilStone: WorldLocationData(0x23CD, 4),
|
||||
LocationName.PrideRockSerenityCrystal: WorldLocationData(0x23CD, 5),
|
||||
LocationName.WildebeestValleyEnergyStone: WorldLocationData(0x23CE, 0),
|
||||
LocationName.WildebeestValleyAPBoost: WorldLocationData(0x23CE, 1),
|
||||
LocationName.WildebeestValleyMythrilGem: WorldLocationData(0x23CE, 2),
|
||||
LocationName.WildebeestValleyMythrilStone: WorldLocationData(0x23CE, 3),
|
||||
LocationName.WildebeestValleyLucidGem: WorldLocationData(0x23CE, 4),
|
||||
LocationName.WastelandsMythrilShard: WorldLocationData(0x23CF, 2),
|
||||
LocationName.WastelandsSerenityGem: WorldLocationData(0x23CF, 3),
|
||||
LocationName.WastelandsMythrilStone: WorldLocationData(0x23CF, 4),
|
||||
LocationName.JungleSerenityGem: WorldLocationData(0x23CF, 5),
|
||||
LocationName.JungleMythrilStone: WorldLocationData(0x23CF, 6),
|
||||
LocationName.JungleSerenityCrystal: WorldLocationData(0x23CF, 7),
|
||||
LocationName.OasisMap: WorldLocationData(0x23D0, 0),
|
||||
LocationName.OasisTornPages: WorldLocationData(0x23D9, 5),
|
||||
LocationName.OasisAPBoost: WorldLocationData(0x23D0, 1),
|
||||
LocationName.CircleofLife: WorldLocationData(0x1DD2, 1),
|
||||
LocationName.Hyenas1: WorldLocationData(0x370A, 1),
|
||||
LocationName.GoofyHyenas1: WorldLocationData(0x370A, 1),
|
||||
LocationName.Scar: WorldLocationData(0x3707, 5),
|
||||
LocationName.DonaldScar: WorldLocationData(0x3707, 5),
|
||||
LocationName.ScarFireElement: WorldLocationData(0x1DD4, 7),
|
||||
LocationName.Hyenas2: WorldLocationData(0x370A, 2),
|
||||
LocationName.GoofyHyenas2: WorldLocationData(0x370A, 2),
|
||||
LocationName.Groundshaker: WorldLocationData(0x3707, 6),
|
||||
LocationName.GroundshakerGetBonus: WorldLocationData(0x3707, 6),
|
||||
|
||||
}
|
||||
TT_Checks = {
|
||||
LocationName.TwilightTownMap: WorldLocationData(0x1CD6, 3),
|
||||
LocationName.MunnyPouchOlette: WorldLocationData(0x1CD6, 5),
|
||||
LocationName.StationDusks: WorldLocationData(0x370A, 6),
|
||||
LocationName.StationofSerenityPotion: WorldLocationData(0x23CA, 1),
|
||||
LocationName.StationofCallingPotion: WorldLocationData(0x23D7, 1),
|
||||
LocationName.TwilightThorn: WorldLocationData(0x3708, 1),
|
||||
LocationName.Axel1: WorldLocationData(0x370D, 1),
|
||||
LocationName.JunkChampionBelt: WorldLocationData(0x1CDC, 2),
|
||||
LocationName.JunkMedal: WorldLocationData(0x1CDC, 2),
|
||||
LocationName.TheStruggleTrophy: WorldLocationData(0x1CDC, 2),
|
||||
LocationName.CentralStationPotion1: WorldLocationData(0x23D1, 5),
|
||||
LocationName.STTCentralStationHiPotion: WorldLocationData(0x23D1, 6),
|
||||
LocationName.CentralStationPotion2: WorldLocationData(0x23D1, 7),
|
||||
LocationName.SunsetTerraceAbilityRing: WorldLocationData(0x23D2, 3),
|
||||
LocationName.SunsetTerraceHiPotion: WorldLocationData(0x23D2, 4),
|
||||
LocationName.SunsetTerracePotion1: WorldLocationData(0x23D2, 5),
|
||||
LocationName.SunsetTerracePotion2: WorldLocationData(0x23D2, 6),
|
||||
LocationName.MansionFoyerHiPotion: WorldLocationData(0x23D4, 2),
|
||||
LocationName.MansionFoyerPotion1: WorldLocationData(0x23D4, 3),
|
||||
LocationName.MansionFoyerPotion2: WorldLocationData(0x23D4, 4),
|
||||
LocationName.MansionDiningRoomElvenBandanna: WorldLocationData(0x23D5, 0),
|
||||
LocationName.MansionDiningRoomPotion: WorldLocationData(0x23D5, 1),
|
||||
LocationName.NaminesSketches: WorldLocationData(0x1CE0, 6),
|
||||
LocationName.MansionMap: WorldLocationData(0x1CE0, 6),
|
||||
LocationName.MansionLibraryHiPotion: WorldLocationData(0x23D5, 4),
|
||||
LocationName.Axel2: WorldLocationData(0x3708, 2),
|
||||
LocationName.MansionBasementCorridorHiPotion: WorldLocationData(0x23D6, 0),
|
||||
# stt and tt share the same world id
|
||||
LocationName.OldMansionPotion: WorldLocationData(0x23D4, 0),
|
||||
LocationName.OldMansionMythrilShard: WorldLocationData(0x23D4, 1),
|
||||
LocationName.TheWoodsPotion: WorldLocationData(0x23D3, 3),
|
||||
LocationName.TheWoodsMythrilShard: WorldLocationData(0x23D3, 4),
|
||||
LocationName.TheWoodsHiPotion: WorldLocationData(0x23D3, 5),
|
||||
LocationName.TramCommonHiPotion: WorldLocationData(0x23D0, 5),
|
||||
LocationName.TramCommonAPBoost: WorldLocationData(0x23D0, 6),
|
||||
LocationName.TramCommonTent: WorldLocationData(0x23D0, 7),
|
||||
LocationName.TramCommonMythrilShard1: WorldLocationData(0x23D1, 0),
|
||||
LocationName.TramCommonPotion1: WorldLocationData(0x23D1, 1),
|
||||
LocationName.TramCommonMythrilShard2: WorldLocationData(0x23D1, 2),
|
||||
LocationName.TramCommonPotion2: WorldLocationData(0x23D8, 5),
|
||||
LocationName.StationPlazaSecretAnsemReport2: WorldLocationData(0x1CE3, 3),
|
||||
LocationName.MunnyPouchMickey: WorldLocationData(0x1CE3, 3),
|
||||
LocationName.CrystalOrb: WorldLocationData(0x1CE3, 3),
|
||||
LocationName.CentralStationTent: WorldLocationData(0x23D2, 0),
|
||||
LocationName.TTCentralStationHiPotion: WorldLocationData(0x23D2, 1),
|
||||
LocationName.CentralStationMythrilShard: WorldLocationData(0x23D2, 2),
|
||||
LocationName.TheTowerPotion: WorldLocationData(0x23D6, 2),
|
||||
LocationName.TheTowerHiPotion: WorldLocationData(0x23D6, 3),
|
||||
LocationName.TheTowerEther: WorldLocationData(0x23DB, 7),
|
||||
LocationName.TowerEntrywayEther: WorldLocationData(0x23D6, 4),
|
||||
LocationName.TowerEntrywayMythrilShard: WorldLocationData(0x23D6, 5),
|
||||
LocationName.SorcerersLoftTowerMap: WorldLocationData(0x23D6, 6),
|
||||
LocationName.TowerWardrobeMythrilStone: WorldLocationData(0x23D6, 7),
|
||||
LocationName.StarSeeker: WorldLocationData(0x1CE5, 2),
|
||||
LocationName.ValorForm: WorldLocationData(0x1CE5, 2),
|
||||
LocationName.SeifersTrophy: WorldLocationData(0x1CE6, 4),
|
||||
LocationName.Oathkeeper: WorldLocationData(0x1CE6, 7),
|
||||
LocationName.LimitForm: WorldLocationData(0x1CE6, 7),
|
||||
LocationName.UndergroundConcourseMythrilGem: WorldLocationData(0x23D8, 0),
|
||||
LocationName.UndergroundConcourseAPBoost: WorldLocationData(0x23D8, 2),
|
||||
LocationName.UndergroundConcourseOrichalcum: WorldLocationData(0x23D8, 1),
|
||||
LocationName.UndergroundConcourseMythrilCrystal: WorldLocationData(0x23D8, 3),
|
||||
LocationName.TunnelwayOrichalcum: WorldLocationData(0x23D7, 6),
|
||||
LocationName.TunnelwayMythrilCrystal: WorldLocationData(0x23D7, 7),
|
||||
LocationName.SunsetTerraceOrichalcumPlus: WorldLocationData(0x23D2, 7),
|
||||
LocationName.SunsetTerraceMythrilShard: WorldLocationData(0x23D3, 0),
|
||||
LocationName.SunsetTerraceMythrilCrystal: WorldLocationData(0x23D3, 1),
|
||||
LocationName.SunsetTerraceAPBoost: WorldLocationData(0x23D3, 2),
|
||||
LocationName.MansionNobodies: WorldLocationData(0x370B, 0),
|
||||
LocationName.DonaldMansionNobodies: WorldLocationData(0x370B, 0),
|
||||
LocationName.MansionFoyerMythrilCrystal: WorldLocationData(0x23D4, 5),
|
||||
LocationName.MansionFoyerMythrilStone: WorldLocationData(0x23D4, 6),
|
||||
LocationName.MansionFoyerSerenityCrystal: WorldLocationData(0x23D4, 7),
|
||||
LocationName.MansionDiningRoomMythrilCrystal: WorldLocationData(0x23D5, 2),
|
||||
LocationName.MansionDiningRoomMythrilStone: WorldLocationData(0x23D5, 3),
|
||||
LocationName.MansionLibraryOrichalcum: WorldLocationData(0x23D5, 5),
|
||||
LocationName.BeamSecretAnsemReport10: WorldLocationData(0x1CE8, 3),
|
||||
LocationName.MansionBasementCorridorUltimateRecipe: WorldLocationData(0x23D6, 1),
|
||||
LocationName.BetwixtandBetween: WorldLocationData(0x370B, 7),
|
||||
LocationName.BetwixtandBetweenBondofFlame: WorldLocationData(0x1CE9, 1),
|
||||
LocationName.AxelDataMagicBoost: WorldLocationData(0x1CEB, 4),
|
||||
}
|
||||
TWTNW_Checks = {
|
||||
LocationName.FragmentCrossingMythrilStone: WorldLocationData(0x23CB, 4),
|
||||
LocationName.FragmentCrossingMythrilCrystal: WorldLocationData(0x23CB, 5),
|
||||
LocationName.FragmentCrossingAPBoost: WorldLocationData(0x23CB, 6),
|
||||
LocationName.FragmentCrossingOrichalcum: WorldLocationData(0x23CB, 7),
|
||||
LocationName.Roxas: WorldLocationData(0x370C, 5),
|
||||
LocationName.RoxasGetBonus: WorldLocationData(0x370C, 5),
|
||||
LocationName.RoxasSecretAnsemReport8: WorldLocationData(0x1ED1, 1),
|
||||
LocationName.TwoBecomeOne: WorldLocationData(0x1ED1, 1),
|
||||
LocationName.MemorysSkyscaperMythrilCrystal: WorldLocationData(0x23CD, 3),
|
||||
LocationName.MemorysSkyscaperAPBoost: WorldLocationData(0x23DC, 0),
|
||||
LocationName.MemorysSkyscaperMythrilStone: WorldLocationData(0x23DC, 1),
|
||||
LocationName.TheBrinkofDespairDarkCityMap: WorldLocationData(0x23CA, 5),
|
||||
LocationName.TheBrinkofDespairOrichalcumPlus: WorldLocationData(0x23DA, 2),
|
||||
LocationName.NothingsCallMythrilGem: WorldLocationData(0x23CC, 0),
|
||||
LocationName.NothingsCallOrichalcum: WorldLocationData(0x23CC, 1),
|
||||
LocationName.TwilightsViewCosmicBelt: WorldLocationData(0x23CA, 6),
|
||||
LocationName.XigbarBonus: WorldLocationData(0x3706, 7),
|
||||
LocationName.XigbarSecretAnsemReport3: WorldLocationData(0x1ED2, 2),
|
||||
LocationName.NaughtsSkywayMythrilGem: WorldLocationData(0x23CC, 2),
|
||||
LocationName.NaughtsSkywayOrichalcum: WorldLocationData(0x23CC, 3),
|
||||
LocationName.NaughtsSkywayMythrilCrystal: WorldLocationData(0x23CC, 4),
|
||||
LocationName.Oblivion: WorldLocationData(0x1ED2, 4),
|
||||
LocationName.CastleThatNeverWasMap: WorldLocationData(0x1ED2, 4),
|
||||
LocationName.Luxord: WorldLocationData(0x3707, 0),
|
||||
LocationName.LuxordGetBonus: WorldLocationData(0x3707, 0),
|
||||
LocationName.LuxordSecretAnsemReport9: WorldLocationData(0x1ED2, 7),
|
||||
LocationName.SaixBonus: WorldLocationData(0x3707, 1),
|
||||
LocationName.SaixSecretAnsemReport12: WorldLocationData(0x1ED3, 2),
|
||||
LocationName.PreXemnas1SecretAnsemReport11: WorldLocationData(0x1ED3, 6),
|
||||
LocationName.RuinandCreationsPassageMythrilStone: WorldLocationData(0x23CC, 7),
|
||||
LocationName.RuinandCreationsPassageAPBoost: WorldLocationData(0x23CD, 0),
|
||||
LocationName.RuinandCreationsPassageMythrilCrystal: WorldLocationData(0x23CD, 1),
|
||||
LocationName.RuinandCreationsPassageOrichalcum: WorldLocationData(0x23CD, 2),
|
||||
LocationName.Xemnas1: WorldLocationData(0x3707, 2),
|
||||
LocationName.Xemnas1GetBonus: WorldLocationData(0x3707, 2),
|
||||
LocationName.Xemnas1SecretAnsemReport13: WorldLocationData(0x1ED4, 5),
|
||||
LocationName.FinalXemnas: WorldLocationData(0x1ED8, 1),
|
||||
LocationName.XemnasDataPowerBoost: WorldLocationData(0x1EDA, 2),
|
||||
LocationName.XigbarDataDefenseBoost: WorldLocationData(0x1ED9, 7),
|
||||
LocationName.SaixDataDefenseBoost: WorldLocationData(0x1EDA, 0),
|
||||
LocationName.LuxordDataAPBoost: WorldLocationData(0x1EDA, 1),
|
||||
LocationName.RoxasDataMagicBoost: WorldLocationData(0x1ED9, 6),
|
||||
}
|
||||
SoraLevels = {
|
||||
# LocationName.Lvl1: WorldLocationData(0xFFFF,1),
|
||||
LocationName.Lvl2: WorldLocationData(0xFFFF, 2),
|
||||
LocationName.Lvl3: WorldLocationData(0xFFFF, 3),
|
||||
LocationName.Lvl4: WorldLocationData(0xFFFF, 4),
|
||||
LocationName.Lvl5: WorldLocationData(0xFFFF, 5),
|
||||
LocationName.Lvl6: WorldLocationData(0xFFFF, 6),
|
||||
LocationName.Lvl7: WorldLocationData(0xFFFF, 7),
|
||||
LocationName.Lvl8: WorldLocationData(0xFFFF, 8),
|
||||
LocationName.Lvl9: WorldLocationData(0xFFFF, 9),
|
||||
LocationName.Lvl10: WorldLocationData(0xFFFF, 10),
|
||||
LocationName.Lvl11: WorldLocationData(0xFFFF, 11),
|
||||
LocationName.Lvl12: WorldLocationData(0xFFFF, 12),
|
||||
LocationName.Lvl13: WorldLocationData(0xFFFF, 13),
|
||||
LocationName.Lvl14: WorldLocationData(0xFFFF, 14),
|
||||
LocationName.Lvl15: WorldLocationData(0xFFFF, 15),
|
||||
LocationName.Lvl16: WorldLocationData(0xFFFF, 16),
|
||||
LocationName.Lvl17: WorldLocationData(0xFFFF, 17),
|
||||
LocationName.Lvl18: WorldLocationData(0xFFFF, 18),
|
||||
LocationName.Lvl19: WorldLocationData(0xFFFF, 19),
|
||||
LocationName.Lvl20: WorldLocationData(0xFFFF, 20),
|
||||
LocationName.Lvl21: WorldLocationData(0xFFFF, 21),
|
||||
LocationName.Lvl22: WorldLocationData(0xFFFF, 22),
|
||||
LocationName.Lvl23: WorldLocationData(0xFFFF, 23),
|
||||
LocationName.Lvl24: WorldLocationData(0xFFFF, 24),
|
||||
LocationName.Lvl25: WorldLocationData(0xFFFF, 25),
|
||||
LocationName.Lvl26: WorldLocationData(0xFFFF, 26),
|
||||
LocationName.Lvl27: WorldLocationData(0xFFFF, 27),
|
||||
LocationName.Lvl28: WorldLocationData(0xFFFF, 28),
|
||||
LocationName.Lvl29: WorldLocationData(0xFFFF, 29),
|
||||
LocationName.Lvl30: WorldLocationData(0xFFFF, 30),
|
||||
LocationName.Lvl31: WorldLocationData(0xFFFF, 31),
|
||||
LocationName.Lvl32: WorldLocationData(0xFFFF, 32),
|
||||
LocationName.Lvl33: WorldLocationData(0xFFFF, 33),
|
||||
LocationName.Lvl34: WorldLocationData(0xFFFF, 34),
|
||||
LocationName.Lvl35: WorldLocationData(0xFFFF, 35),
|
||||
LocationName.Lvl36: WorldLocationData(0xFFFF, 36),
|
||||
LocationName.Lvl37: WorldLocationData(0xFFFF, 37),
|
||||
LocationName.Lvl38: WorldLocationData(0xFFFF, 38),
|
||||
LocationName.Lvl39: WorldLocationData(0xFFFF, 39),
|
||||
LocationName.Lvl40: WorldLocationData(0xFFFF, 40),
|
||||
LocationName.Lvl41: WorldLocationData(0xFFFF, 41),
|
||||
LocationName.Lvl42: WorldLocationData(0xFFFF, 42),
|
||||
LocationName.Lvl43: WorldLocationData(0xFFFF, 43),
|
||||
LocationName.Lvl44: WorldLocationData(0xFFFF, 44),
|
||||
LocationName.Lvl45: WorldLocationData(0xFFFF, 45),
|
||||
LocationName.Lvl46: WorldLocationData(0xFFFF, 46),
|
||||
LocationName.Lvl47: WorldLocationData(0xFFFF, 47),
|
||||
LocationName.Lvl48: WorldLocationData(0xFFFF, 48),
|
||||
LocationName.Lvl49: WorldLocationData(0xFFFF, 49),
|
||||
LocationName.Lvl50: WorldLocationData(0xFFFF, 50),
|
||||
LocationName.Lvl51: WorldLocationData(0xFFFF, 51),
|
||||
LocationName.Lvl52: WorldLocationData(0xFFFF, 52),
|
||||
LocationName.Lvl53: WorldLocationData(0xFFFF, 53),
|
||||
LocationName.Lvl54: WorldLocationData(0xFFFF, 54),
|
||||
LocationName.Lvl55: WorldLocationData(0xFFFF, 55),
|
||||
LocationName.Lvl56: WorldLocationData(0xFFFF, 56),
|
||||
LocationName.Lvl57: WorldLocationData(0xFFFF, 57),
|
||||
LocationName.Lvl58: WorldLocationData(0xFFFF, 58),
|
||||
LocationName.Lvl59: WorldLocationData(0xFFFF, 59),
|
||||
LocationName.Lvl60: WorldLocationData(0xFFFF, 60),
|
||||
LocationName.Lvl61: WorldLocationData(0xFFFF, 61),
|
||||
LocationName.Lvl62: WorldLocationData(0xFFFF, 62),
|
||||
LocationName.Lvl63: WorldLocationData(0xFFFF, 63),
|
||||
LocationName.Lvl64: WorldLocationData(0xFFFF, 64),
|
||||
LocationName.Lvl65: WorldLocationData(0xFFFF, 65),
|
||||
LocationName.Lvl66: WorldLocationData(0xFFFF, 66),
|
||||
LocationName.Lvl67: WorldLocationData(0xFFFF, 67),
|
||||
LocationName.Lvl68: WorldLocationData(0xFFFF, 68),
|
||||
LocationName.Lvl69: WorldLocationData(0xFFFF, 69),
|
||||
LocationName.Lvl70: WorldLocationData(0xFFFF, 70),
|
||||
LocationName.Lvl71: WorldLocationData(0xFFFF, 71),
|
||||
LocationName.Lvl72: WorldLocationData(0xFFFF, 72),
|
||||
LocationName.Lvl73: WorldLocationData(0xFFFF, 73),
|
||||
LocationName.Lvl74: WorldLocationData(0xFFFF, 74),
|
||||
LocationName.Lvl75: WorldLocationData(0xFFFF, 75),
|
||||
LocationName.Lvl76: WorldLocationData(0xFFFF, 76),
|
||||
LocationName.Lvl77: WorldLocationData(0xFFFF, 77),
|
||||
LocationName.Lvl78: WorldLocationData(0xFFFF, 78),
|
||||
LocationName.Lvl79: WorldLocationData(0xFFFF, 79),
|
||||
LocationName.Lvl80: WorldLocationData(0xFFFF, 80),
|
||||
LocationName.Lvl81: WorldLocationData(0xFFFF, 81),
|
||||
LocationName.Lvl82: WorldLocationData(0xFFFF, 82),
|
||||
LocationName.Lvl83: WorldLocationData(0xFFFF, 83),
|
||||
LocationName.Lvl84: WorldLocationData(0xFFFF, 84),
|
||||
LocationName.Lvl85: WorldLocationData(0xFFFF, 85),
|
||||
LocationName.Lvl86: WorldLocationData(0xFFFF, 86),
|
||||
LocationName.Lvl87: WorldLocationData(0xFFFF, 87),
|
||||
LocationName.Lvl88: WorldLocationData(0xFFFF, 88),
|
||||
LocationName.Lvl89: WorldLocationData(0xFFFF, 89),
|
||||
LocationName.Lvl90: WorldLocationData(0xFFFF, 90),
|
||||
LocationName.Lvl91: WorldLocationData(0xFFFF, 91),
|
||||
LocationName.Lvl92: WorldLocationData(0xFFFF, 92),
|
||||
LocationName.Lvl93: WorldLocationData(0xFFFF, 93),
|
||||
LocationName.Lvl94: WorldLocationData(0xFFFF, 94),
|
||||
LocationName.Lvl95: WorldLocationData(0xFFFF, 95),
|
||||
LocationName.Lvl96: WorldLocationData(0xFFFF, 96),
|
||||
LocationName.Lvl97: WorldLocationData(0xFFFF, 97),
|
||||
LocationName.Lvl98: WorldLocationData(0xFFFF, 98),
|
||||
LocationName.Lvl99: WorldLocationData(0xFFFF, 99),
|
||||
}
|
||||
|
||||
ValorLevels = {
|
||||
# LocationName.Valorlvl1: WorldLocationData(0x32F6, 1),
|
||||
LocationName.Valorlvl2: WorldLocationData(0x32F6, 2),
|
||||
LocationName.Valorlvl3: WorldLocationData(0x32F6, 3),
|
||||
LocationName.Valorlvl4: WorldLocationData(0x32F6, 4),
|
||||
LocationName.Valorlvl5: WorldLocationData(0x32F6, 5),
|
||||
LocationName.Valorlvl6: WorldLocationData(0x32F6, 6),
|
||||
LocationName.Valorlvl7: WorldLocationData(0x32F6, 7),
|
||||
}
|
||||
|
||||
WisdomLevels = {
|
||||
# LocationName.Wisdomlvl1: WorldLocationData(0x332E, 1),
|
||||
LocationName.Wisdomlvl2: WorldLocationData(0x332E, 2),
|
||||
LocationName.Wisdomlvl3: WorldLocationData(0x332E, 3),
|
||||
LocationName.Wisdomlvl4: WorldLocationData(0x332E, 4),
|
||||
LocationName.Wisdomlvl5: WorldLocationData(0x332E, 5),
|
||||
LocationName.Wisdomlvl6: WorldLocationData(0x332E, 6),
|
||||
LocationName.Wisdomlvl7: WorldLocationData(0x332E, 7),
|
||||
}
|
||||
|
||||
LimitLevels = {
|
||||
# LocationName.Limitlvl1: WorldLocationData(0x3366, 1),
|
||||
LocationName.Limitlvl2: WorldLocationData(0x3366, 2),
|
||||
LocationName.Limitlvl3: WorldLocationData(0x3366, 3),
|
||||
LocationName.Limitlvl4: WorldLocationData(0x3366, 4),
|
||||
LocationName.Limitlvl5: WorldLocationData(0x3366, 5),
|
||||
LocationName.Limitlvl6: WorldLocationData(0x3366, 6),
|
||||
LocationName.Limitlvl7: WorldLocationData(0x3366, 7),
|
||||
}
|
||||
MasterLevels = {
|
||||
# LocationName.Masterlvl1: WorldLocationData(0x339E, 1),
|
||||
LocationName.Masterlvl2: WorldLocationData(0x339E, 2),
|
||||
LocationName.Masterlvl3: WorldLocationData(0x339E, 3),
|
||||
LocationName.Masterlvl4: WorldLocationData(0x339E, 4),
|
||||
LocationName.Masterlvl5: WorldLocationData(0x339E, 5),
|
||||
LocationName.Masterlvl6: WorldLocationData(0x339E, 6),
|
||||
LocationName.Masterlvl7: WorldLocationData(0x339E, 7),
|
||||
}
|
||||
FinalLevels = {
|
||||
# LocationName.Finallvl1: WorldLocationData(0x33D6,1),
|
||||
LocationName.Finallvl2: WorldLocationData(0x33D6, 2),
|
||||
LocationName.Finallvl3: WorldLocationData(0x33D6, 3),
|
||||
LocationName.Finallvl4: WorldLocationData(0x33D6, 4),
|
||||
LocationName.Finallvl5: WorldLocationData(0x33D6, 5),
|
||||
LocationName.Finallvl6: WorldLocationData(0x33D6, 6),
|
||||
LocationName.Finallvl7: WorldLocationData(0x33D6, 7),
|
||||
|
||||
}
|
||||
weaponSlots = {
|
||||
LocationName.AdamantShield: WorldLocationData(0x35E6, 1),
|
||||
LocationName.AkashicRecord: WorldLocationData(0x35ED, 1),
|
||||
LocationName.ChainGear: WorldLocationData(0x35E7, 1),
|
||||
LocationName.DreamCloud: WorldLocationData(0x35EA, 1),
|
||||
LocationName.FallingStar: WorldLocationData(0x35E9, 1),
|
||||
LocationName.FrozenPride2: WorldLocationData(0x36A2, 1),
|
||||
LocationName.GenjiShield: WorldLocationData(0x35EC, 1),
|
||||
LocationName.KnightDefender: WorldLocationData(0x35EB, 1),
|
||||
LocationName.MajesticMushroom: WorldLocationData(0x36A5, 1),
|
||||
LocationName.MajesticMushroom2: WorldLocationData(0x36A6, 1),
|
||||
LocationName.NobodyGuard: WorldLocationData(0x35EE, 1),
|
||||
LocationName.OgreShield: WorldLocationData(0x35E8, 1),
|
||||
LocationName.SaveTheKing2: WorldLocationData(0x3693, 1),
|
||||
LocationName.UltimateMushroom: WorldLocationData(0x36A7, 1),
|
||||
|
||||
LocationName.CometStaff: WorldLocationData(0x35F2, 1),
|
||||
LocationName.HammerStaff: WorldLocationData(0x35EF, 1),
|
||||
LocationName.LordsBroom: WorldLocationData(0x35F3, 1),
|
||||
LocationName.MeteorStaff: WorldLocationData(0x35F1, 1),
|
||||
LocationName.NobodyLance: WorldLocationData(0x35F6, 1),
|
||||
LocationName.PreciousMushroom: WorldLocationData(0x369E, 1),
|
||||
LocationName.PreciousMushroom2: WorldLocationData(0x369F, 1),
|
||||
LocationName.PremiumMushroom: WorldLocationData(0x36A0, 1),
|
||||
LocationName.RisingDragon: WorldLocationData(0x35F5, 1),
|
||||
LocationName.SaveTheQueen2: WorldLocationData(0x3692, 1),
|
||||
LocationName.ShamansRelic: WorldLocationData(0x35F7, 1),
|
||||
LocationName.VictoryBell: WorldLocationData(0x35F0, 1),
|
||||
LocationName.WisdomWand: WorldLocationData(0x35F4, 1),
|
||||
LocationName.Centurion2: WorldLocationData(0x369B, 1),
|
||||
|
||||
LocationName.OathkeeperSlot: WorldLocationData(0x35A2, 1),
|
||||
LocationName.OblivionSlot: WorldLocationData(0x35A3, 1),
|
||||
LocationName.StarSeekerSlot: WorldLocationData(0x367B, 1),
|
||||
LocationName.HiddenDragonSlot: WorldLocationData(0x367C, 1),
|
||||
LocationName.HerosCrestSlot: WorldLocationData(0x367F, 1),
|
||||
LocationName.MonochromeSlot: WorldLocationData(0x3680, 1),
|
||||
LocationName.FollowtheWindSlot: WorldLocationData(0x3681, 1),
|
||||
LocationName.CircleofLifeSlot: WorldLocationData(0x3682, 1),
|
||||
LocationName.PhotonDebuggerSlot: WorldLocationData(0x3683, 1),
|
||||
LocationName.GullWingSlot: WorldLocationData(0x3684, 1),
|
||||
LocationName.RumblingRoseSlot: WorldLocationData(0x3685, 1),
|
||||
LocationName.GuardianSoulSlot: WorldLocationData(0x3686, 1),
|
||||
LocationName.WishingLampSlot: WorldLocationData(0x3687, 1),
|
||||
LocationName.DecisivePumpkinSlot: WorldLocationData(0x3688, 1),
|
||||
LocationName.SleepingLionSlot: WorldLocationData(0x3689, 1),
|
||||
LocationName.SweetMemoriesSlot: WorldLocationData(0x368A, 1),
|
||||
LocationName.MysteriousAbyssSlot: WorldLocationData(0x368B, 1),
|
||||
LocationName.TwoBecomeOneSlot: WorldLocationData(0x3698, 1),
|
||||
LocationName.FatalCrestSlot: WorldLocationData(0x368C, 1),
|
||||
LocationName.BondofFlameSlot: WorldLocationData(0x368D, 1),
|
||||
LocationName.FenrirSlot: WorldLocationData(0x368E, 1),
|
||||
LocationName.UltimaWeaponSlot: WorldLocationData(0x368F, 1),
|
||||
LocationName.WinnersProofSlot: WorldLocationData(0x3699, 1),
|
||||
LocationName.PurebloodSlot: WorldLocationData(0x35BF, 1),
|
||||
}
|
||||
|
||||
formSlots = {
|
||||
LocationName.FAKESlot: WorldLocationData(0x36C0, 1),
|
||||
LocationName.DetectionSaberSlot: WorldLocationData(0x36C0, 6),
|
||||
LocationName.EdgeofUltimaSlot: WorldLocationData(0x36C0, 4),
|
||||
}
|
||||
|
||||
tornPageLocks = {
|
||||
"TornPage1": WorldLocationData(0x1DB7, 4), # --Scenario_1_start
|
||||
"TornPage2": WorldLocationData(0x1DB7, 7), # --Scenario_2_start
|
||||
"TornPage3": WorldLocationData(0x1DB8, 2), # --Scenario_3_start
|
||||
"TornPage4": WorldLocationData(0x1DB8, 4), # --Scenario_4_start
|
||||
"TornPage5": WorldLocationData(0x1DB8, 7), # --Scenario_5_start
|
||||
}
|
||||
all_world_locations = {
|
||||
**TWTNW_Checks,
|
||||
**TT_Checks,
|
||||
**TT_Checks,
|
||||
**HB_Checks,
|
||||
**BC_Checks,
|
||||
**Oc_Checks,
|
||||
**AG_Checks,
|
||||
**LoD_Checks,
|
||||
**HundredAcreChecks,
|
||||
**PL_Checks,
|
||||
**DC_Checks,
|
||||
**TR_Checks,
|
||||
**HT_Checks,
|
||||
**HB_Checks,
|
||||
**PR_Checks,
|
||||
**SP_Checks,
|
||||
**TWTNW_Checks,
|
||||
**HB_Checks,
|
||||
}
|
||||
|
||||
levels_locations = {
|
||||
**SoraLevels,
|
||||
**ValorLevels,
|
||||
**WisdomLevels,
|
||||
**LimitLevels,
|
||||
**MasterLevels,
|
||||
**FinalLevels,
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
lvlStats = [
|
||||
"str",
|
||||
"mag",
|
||||
"def",
|
||||
"ap",
|
||||
"",
|
||||
]
|
||||
|
||||
formExp = {
|
||||
0: {1: 6, 2: 16, 3: 25, 4: 42, 5: 63, 6: 98, 7: 0},
|
||||
1: {1: 80, 2: 160, 3: 280, 4: 448, 5: 560, 6: 672, 7: 0},
|
||||
2: {1: 12, 2: 24, 3: 48, 4: 76, 5: 133, 6: 157, 7: 0},
|
||||
3: {1: 3, 2: 6, 3: 12, 4: 19, 5: 23, 6: 27, 7: 0},
|
||||
4: {1: 40, 2: 80, 3: 140, 4: 224, 5: 448, 6: 668, 7: 0},
|
||||
5: {1: 12, 2: 24, 3: 48, 4: 76, 5: 133, 6: 157, 7: 0}
|
||||
}
|
||||
|
||||
soraExp = [
|
||||
0,
|
||||
40,
|
||||
100,
|
||||
184,
|
||||
296,
|
||||
440,
|
||||
620,
|
||||
840,
|
||||
1128,
|
||||
1492,
|
||||
1940,
|
||||
2480,
|
||||
3120,
|
||||
3902,
|
||||
4838,
|
||||
5940,
|
||||
7260,
|
||||
8814,
|
||||
10618,
|
||||
12688,
|
||||
15088,
|
||||
17838,
|
||||
20949,
|
||||
24433,
|
||||
28302,
|
||||
32622,
|
||||
37407,
|
||||
42671,
|
||||
48485,
|
||||
54865,
|
||||
61886,
|
||||
69566,
|
||||
77984,
|
||||
87160,
|
||||
97177,
|
||||
108057,
|
||||
119887,
|
||||
132691,
|
||||
146560,
|
||||
161520,
|
||||
177666,
|
||||
195026,
|
||||
213699,
|
||||
233715,
|
||||
255177,
|
||||
278117,
|
||||
302642,
|
||||
328786,
|
||||
356660,
|
||||
386378,
|
||||
417978,
|
||||
450378,
|
||||
483578,
|
||||
517578,
|
||||
552378,
|
||||
587978,
|
||||
624378,
|
||||
661578,
|
||||
699578,
|
||||
738378,
|
||||
777978,
|
||||
818378,
|
||||
859578,
|
||||
901578,
|
||||
944378,
|
||||
987978,
|
||||
1032378,
|
||||
1077578,
|
||||
1123578,
|
||||
1170378,
|
||||
1217978,
|
||||
1266378,
|
||||
1315578,
|
||||
1365578,
|
||||
1416378,
|
||||
1467978,
|
||||
1520378,
|
||||
1573578,
|
||||
1627578,
|
||||
1682378,
|
||||
1737978,
|
||||
1794378,
|
||||
1851578,
|
||||
1909578,
|
||||
1968378,
|
||||
2027978,
|
||||
2088378,
|
||||
2149578,
|
||||
2211578,
|
||||
2274378,
|
||||
2337978,
|
||||
2402378,
|
||||
2467578,
|
||||
2533578,
|
||||
2600378,
|
||||
2667978,
|
||||
2736378,
|
||||
2805578,
|
||||
2875578,
|
||||
2875578
|
||||
]
|
|
@ -0,0 +1,315 @@
|
|||
|
||||
|
||||
from BaseClasses import Tutorial, ItemClassification
|
||||
|
||||
from .Items import *
|
||||
from .Locations import all_locations, setup_locations, exclusion_table
|
||||
from .Names import ItemName, LocationName
|
||||
from .OpenKH import patch_kh2
|
||||
from .Options import KH2_Options
|
||||
from .Regions import create_regions, connect_regions
|
||||
from .Rules import set_rules
|
||||
from ..AutoWorld import World, WebWorld
|
||||
from .logic import KH2Logic
|
||||
|
||||
|
||||
class KingdomHearts2Web(WebWorld):
|
||||
tutorials = [Tutorial(
|
||||
"Multiworld Setup Guide",
|
||||
"A guide to playing Kingdom Hearts 2 Final Mix with Archipelago.",
|
||||
"English",
|
||||
"setup_en.md",
|
||||
"setup/en",
|
||||
["JaredWeakStrike"]
|
||||
)]
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
class KH2World(World):
|
||||
"""
|
||||
Kingdom Hearts II is an action role-playing game developed and published by Square Enix and released in 2005.
|
||||
It is the sequel to Kingdom Hearts and Kingdom Hearts: Chain of Memories, and like the two previous games,
|
||||
focuses on Sora and his friends' continued battle against the Darkness.
|
||||
"""
|
||||
game: str = "Kingdom Hearts 2"
|
||||
web = KingdomHearts2Web()
|
||||
data_version = 1
|
||||
option_definitions = KH2_Options
|
||||
item_name_to_id = {name: data.code for name, data in item_dictionary_table.items()}
|
||||
location_name_to_id = {item_name: data.code for item_name, data in all_locations.items() if data.code}
|
||||
item_name_groups = item_groups
|
||||
|
||||
def __init__(self, multiworld: "MultiWorld", player: int):
|
||||
super().__init__(multiworld, player)
|
||||
self.BountiesRequired = None
|
||||
self.BountiesAmount = None
|
||||
self.hitlist = None
|
||||
self.LocalItems = {}
|
||||
self.RandomSuperBoss = list()
|
||||
self.filler_items = list()
|
||||
self.item_quantity_dict = {}
|
||||
self.donald_ability_pool = list()
|
||||
self.goofy_ability_pool = list()
|
||||
self.sora_keyblade_ability_pool = list()
|
||||
self.keyblade_slot_copy = list(Locations.Keyblade_Slots.keys())
|
||||
self.totalLocations = len(all_locations.items())
|
||||
self.growth_list = list()
|
||||
for x in range(4):
|
||||
self.growth_list.extend(Movement_Table.keys())
|
||||
self.visitlockingitem = list()
|
||||
self.visitlockingitem.extend(Progression_Dicts["AllVisitLocking"])
|
||||
|
||||
def fill_slot_data(self) -> dict:
|
||||
return {"hitlist": self.hitlist,
|
||||
"LocalItems": self.LocalItems,
|
||||
"Goal": self.multiworld.Goal[self.player].value,
|
||||
"FinalXemnas": self.multiworld.FinalXemnas[self.player].value,
|
||||
"LuckyEmblemsRequired": self.multiworld.LuckyEmblemsRequired[self.player].value,
|
||||
"BountyRequired": self.multiworld.BountyRequired[self.player].value}
|
||||
|
||||
def create_item(self, name: str, ) -> Item:
|
||||
data = item_dictionary_table[name]
|
||||
if name in Progression_Dicts["Progression"]:
|
||||
item_classification = ItemClassification.progression
|
||||
else:
|
||||
item_classification = ItemClassification.filler
|
||||
|
||||
created_item = KH2Item(name, item_classification, data.code, self.player)
|
||||
|
||||
return created_item
|
||||
|
||||
def generate_early(self) -> None:
|
||||
# Item Quantity dict because Abilities can be a problem for KH2's Software.
|
||||
for item, data in item_dictionary_table.items():
|
||||
self.item_quantity_dict[item] = data.quantity
|
||||
|
||||
if self.multiworld.KeybladeAbilities[self.player] == "support":
|
||||
self.sora_keyblade_ability_pool.extend(SupportAbility_Table.keys())
|
||||
elif self.multiworld.KeybladeAbilities[self.player] == "action":
|
||||
self.sora_keyblade_ability_pool.extend(ActionAbility_Table.keys())
|
||||
else:
|
||||
# both action and support on keyblades.
|
||||
# TODO: make option to just exclude scom
|
||||
self.sora_keyblade_ability_pool.extend(ActionAbility_Table.keys())
|
||||
self.sora_keyblade_ability_pool.extend(SupportAbility_Table.keys())
|
||||
|
||||
for item, value in self.multiworld.start_inventory[self.player].value.items():
|
||||
if item in ActionAbility_Table.keys() or item in SupportAbility_Table.keys():
|
||||
# cannot have more than the quantity for abilties
|
||||
if value > item_dictionary_table[item].quantity:
|
||||
print(f"{self.multiworld.get_file_safe_player_name(self.player)} cannot have more than {item_dictionary_table[item].quantity} of {item}")
|
||||
value = item_dictionary_table[item].quantity
|
||||
self.item_quantity_dict[item] -= value
|
||||
|
||||
# Option to turn off Promise Charm Item
|
||||
if not self.multiworld.Promise_Charm[self.player]:
|
||||
self.item_quantity_dict[ItemName.PromiseCharm] = 0
|
||||
|
||||
for ability in self.multiworld.BlacklistKeyblade[self.player].value:
|
||||
if ability in self.sora_keyblade_ability_pool:
|
||||
self.sora_keyblade_ability_pool.remove(ability)
|
||||
|
||||
# Option to turn off all superbosses. Can do this individually but its like 20+ checks
|
||||
if not self.multiworld.SuperBosses[self.player] and not self.multiworld.Goal[self.player] == "hitlist":
|
||||
for superboss in exclusion_table["Datas"]:
|
||||
self.multiworld.exclude_locations[self.player].value.add(superboss)
|
||||
for superboss in exclusion_table["SuperBosses"]:
|
||||
self.multiworld.exclude_locations[self.player].value.add(superboss)
|
||||
|
||||
# Option to turn off Olympus Colosseum Cups.
|
||||
if self.multiworld.Cups[self.player] == "no_cups":
|
||||
for cup in exclusion_table["Cups"]:
|
||||
self.multiworld.exclude_locations[self.player].value.add(cup)
|
||||
# exclude only hades paradox. If cups and hades paradox then nothing is excluded
|
||||
elif self.multiworld.Cups[self.player] == "cups":
|
||||
self.multiworld.exclude_locations[self.player].value.add(LocationName.HadesCupTrophyParadoxCups)
|
||||
|
||||
if self.multiworld.Goal[self.player] == "lucky_emblem_hunt":
|
||||
luckyemblemamount = self.multiworld.LuckyEmblemsAmount[self.player].value
|
||||
luckyemblemrequired = self.multiworld.LuckyEmblemsRequired[self.player].value
|
||||
if luckyemblemamount < luckyemblemrequired:
|
||||
luckyemblemamount = max(luckyemblemamount, luckyemblemrequired)
|
||||
print(f"Lucky Emblem Amount {self.multiworld.LuckyEmblemsAmount[self.player].value} is less than required \
|
||||
{self.multiworld.LuckyEmblemsRequired[self.player].value} for player {self.multiworld.get_file_safe_player_name(self.player)}")
|
||||
self.item_quantity_dict[ItemName.LuckyEmblem] = item_dictionary_table[ItemName.LuckyEmblem].quantity + luckyemblemamount
|
||||
# give this proof to unlock the final door once the player has the amount of lucky emblem required
|
||||
self.item_quantity_dict[ItemName.ProofofNonexistence] = 0
|
||||
|
||||
# hitlist
|
||||
elif self.multiworld.Goal[self.player] == "hitlist":
|
||||
self.RandomSuperBoss.extend(exclusion_table["Hitlist"])
|
||||
self.BountiesAmount = self.multiworld.BountyAmount[self.player].value
|
||||
self.BountiesRequired = self.multiworld.BountyRequired[self.player].value
|
||||
|
||||
for location in self.multiworld.exclude_locations[self.player].value:
|
||||
if location in self.RandomSuperBoss:
|
||||
self.RandomSuperBoss.remove(location)
|
||||
# Testing if the player has the right amount of Bounties for Completion.
|
||||
if len(self.RandomSuperBoss) < self.BountiesAmount:
|
||||
print(f"{self.multiworld.get_file_safe_player_name(self.player)} has too many bounties than bosses")
|
||||
self.BountiesAmount = len(self.RandomSuperBoss)
|
||||
self.multiworld.BountyAmount[self.player].value = len(self.RandomSuperBoss)
|
||||
|
||||
if len(self.RandomSuperBoss) < self.BountiesRequired:
|
||||
print(f"{self.multiworld.get_file_safe_player_name(self.player)} has too many required bounties")
|
||||
self.BountiesRequired = len(self.RandomSuperBoss)
|
||||
self.multiworld.BountyRequired[self.player].value = len(self.RandomSuperBoss)
|
||||
|
||||
if self.BountiesAmount < self.BountiesRequired:
|
||||
self.BountiesAmount = max(self.BountiesAmount, self.BountiesRequired)
|
||||
print(f"Bounties Amount {self.multiworld.BountyAmount[self.player].value} is less than required \
|
||||
{self.multiworld.BountyRequired[self.player].value} for player {self.multiworld.get_file_safe_player_name(self.player)}")
|
||||
|
||||
self.multiworld.start_hints[self.player].value.add(ItemName.Bounty)
|
||||
self.item_quantity_dict[ItemName.ProofofNonexistence] = 0
|
||||
|
||||
while len(self.sora_keyblade_ability_pool) < len(self.keyblade_slot_copy):
|
||||
self.sora_keyblade_ability_pool.append(
|
||||
self.multiworld.per_slot_randoms[self.player].choice(list(SupportAbility_Table.keys())))
|
||||
|
||||
for item in DonaldAbility_Table.keys():
|
||||
data = self.item_quantity_dict[item]
|
||||
for _ in range(data):
|
||||
self.donald_ability_pool.append(item)
|
||||
self.item_quantity_dict[item] = 0
|
||||
# 32 is the amount of donald abilities
|
||||
while len(self.donald_ability_pool) < 32:
|
||||
self.donald_ability_pool.append(self.multiworld.per_slot_randoms[self.player].choice(self.donald_ability_pool))
|
||||
|
||||
for item in GoofyAbility_Table.keys():
|
||||
data = self.item_quantity_dict[item]
|
||||
for _ in range(data):
|
||||
self.goofy_ability_pool.append(item)
|
||||
self.item_quantity_dict[item] = 0
|
||||
# 32 is the amount of goofy abilities
|
||||
while len(self.goofy_ability_pool) < 33:
|
||||
self.goofy_ability_pool.append(self.multiworld.per_slot_randoms[self.player].choice(self.goofy_ability_pool))
|
||||
|
||||
def generate_basic(self):
|
||||
itempool: typing.List[KH2Item] = []
|
||||
|
||||
self.hitlist = list()
|
||||
self.filler_items.extend(item_groups["Filler"])
|
||||
|
||||
if self.multiworld.FinalXemnas[self.player]:
|
||||
self.multiworld.get_location(LocationName.FinalXemnas, self.player).place_locked_item(
|
||||
self.create_item(ItemName.Victory))
|
||||
else:
|
||||
self.multiworld.get_location(LocationName.FinalXemnas, self.player).place_locked_item(
|
||||
self.create_item(self.multiworld.per_slot_randoms[self.player].choice(self.filler_items)))
|
||||
self.totalLocations -= 1
|
||||
|
||||
if self.multiworld.Goal[self.player] == "hitlist":
|
||||
for bounty in range(self.BountiesAmount):
|
||||
randomBoss = self.multiworld.per_slot_randoms[self.player].choice(self.RandomSuperBoss)
|
||||
self.multiworld.get_location(randomBoss, self.player).place_locked_item(
|
||||
self.create_item(ItemName.Bounty))
|
||||
self.hitlist.append(self.location_name_to_id[randomBoss])
|
||||
self.RandomSuperBoss.remove(randomBoss)
|
||||
self.totalLocations -= 1
|
||||
|
||||
# plando keyblades because they can only have abilities
|
||||
for keyblade in self.keyblade_slot_copy:
|
||||
random_ability = self.multiworld.per_slot_randoms[self.player].choice(self.sora_keyblade_ability_pool)
|
||||
self.multiworld.get_location(keyblade, self.player).place_locked_item(self.create_item(random_ability))
|
||||
self.item_quantity_dict[random_ability] -= 1
|
||||
self.sora_keyblade_ability_pool.remove(random_ability)
|
||||
self.totalLocations -= 1
|
||||
|
||||
# Placing Donald Abilities on donald locations
|
||||
for donaldLocation in Locations.Donald_Checks.keys():
|
||||
random_ability = self.multiworld.per_slot_randoms[self.player].choice(self.donald_ability_pool)
|
||||
self.multiworld.get_location(donaldLocation, self.player).place_locked_item(
|
||||
self.create_item(random_ability))
|
||||
self.totalLocations -= 1
|
||||
self.donald_ability_pool.remove(random_ability)
|
||||
|
||||
# Placing Goofy Abilities on goofy locations
|
||||
for goofyLocation in Locations.Goofy_Checks.keys():
|
||||
random_ability = self.multiworld.per_slot_randoms[self.player].choice(self.goofy_ability_pool)
|
||||
self.multiworld.get_location(goofyLocation, self.player).place_locked_item(self.create_item(random_ability))
|
||||
self.totalLocations -= 1
|
||||
self.goofy_ability_pool.remove(random_ability)
|
||||
|
||||
# same item placed because you can only get one of these 2 locations
|
||||
# they are both under the same flag so the player gets both locations just one of the two items
|
||||
random_stt_item = self.multiworld.per_slot_randoms[self.player].choice(self.filler_items)
|
||||
self.multiworld.get_location(LocationName.JunkChampionBelt, self.player).place_locked_item(
|
||||
self.create_item(random_stt_item))
|
||||
self.multiworld.get_location(LocationName.JunkMedal, self.player).place_locked_item(
|
||||
self.create_item(random_stt_item))
|
||||
self.totalLocations -= 2
|
||||
|
||||
if self.multiworld.Schmovement[self.player] != "level_0":
|
||||
for _ in range(self.multiworld.Schmovement[self.player].value):
|
||||
for name in {ItemName.HighJump, ItemName.QuickRun, ItemName.DodgeRoll, ItemName.AerialDodge,
|
||||
ItemName.Glide}:
|
||||
self.item_quantity_dict[name] -= 1
|
||||
self.growth_list.remove(name)
|
||||
self.multiworld.push_precollected(self.create_item(name))
|
||||
|
||||
if self.multiworld.RandomGrowth[self.player] != 0:
|
||||
max_growth = min(self.multiworld.RandomGrowth[self.player].value, len(self.growth_list))
|
||||
for _ in range(max_growth):
|
||||
random_growth = self.multiworld.per_slot_randoms[self.player].choice(self.growth_list)
|
||||
self.item_quantity_dict[random_growth] -= 1
|
||||
self.growth_list.remove(random_growth)
|
||||
self.multiworld.push_precollected(self.create_item(random_growth))
|
||||
|
||||
# no visit locking
|
||||
if self.multiworld.Visitlocking[self.player] == "no_visit_locking":
|
||||
for item in self.visitlockingitem:
|
||||
self.multiworld.push_precollected(self.create_item(item))
|
||||
self.item_quantity_dict[item] -= 1
|
||||
self.visitlockingitem.remove(item)
|
||||
|
||||
# first and second visit locking
|
||||
elif self.multiworld.Visitlocking[self.player] == "second_visit_locking":
|
||||
for item in Progression_Dicts["2VisitLocking"]:
|
||||
self.item_quantity_dict[item] -= 1
|
||||
self.multiworld.push_precollected(self.create_item(item))
|
||||
self.visitlockingitem.remove(item)
|
||||
|
||||
for _ in range(self.multiworld.RandomVisitLockingItem[self.player].value):
|
||||
if len(self.visitlockingitem) <= 0:
|
||||
break
|
||||
item = self.multiworld.per_slot_randoms[self.player].choice(self.visitlockingitem)
|
||||
self.item_quantity_dict[item] -= 1
|
||||
self.multiworld.push_precollected(self.create_item(item))
|
||||
self.visitlockingitem.remove(item)
|
||||
|
||||
# there are levels but level 1 is there to keep code clean
|
||||
if self.multiworld.LevelDepth[self.player] == "level_99_sanity":
|
||||
# level 99 sanity
|
||||
self.totalLocations -= 1
|
||||
elif self.multiworld.LevelDepth[self.player] == "level_50_sanity":
|
||||
# level 50 sanity
|
||||
self.totalLocations -= 50
|
||||
elif self.multiworld.LevelDepth[self.player] == "level_1":
|
||||
# level 1. No checks on levels
|
||||
self.totalLocations -= 99
|
||||
else:
|
||||
# level 50/99 since they contain the same amount of levels
|
||||
self.totalLocations -= 76
|
||||
|
||||
for item in item_dictionary_table:
|
||||
data = self.item_quantity_dict[item]
|
||||
for _ in range(data):
|
||||
itempool.append(self.create_item(item))
|
||||
|
||||
# Creating filler for unfilled locations
|
||||
while len(itempool) < self.totalLocations:
|
||||
item = self.multiworld.per_slot_randoms[self.player].choice(self.filler_items)
|
||||
itempool += [self.create_item(item)]
|
||||
self.multiworld.itempool += itempool
|
||||
|
||||
def create_regions(self):
|
||||
location_table = setup_locations()
|
||||
create_regions(self.multiworld, self.player, location_table)
|
||||
connect_regions(self.multiworld, self.player)
|
||||
|
||||
def set_rules(self):
|
||||
set_rules(self.multiworld, self.player)
|
||||
|
||||
def generate_output(self, output_directory: str):
|
||||
patch_kh2(self, output_directory)
|
|
@ -0,0 +1,105 @@
|
|||
# Kingdom Hearts 2
|
||||
|
||||
<h2 style="text-transform:none";>Changes from the vanilla game</h2>
|
||||
|
||||
This randomizer takes Kingdom Hearts 2 and randomizes the locations of the items for a more dynamic play experience. The items that randomize currently are all items within Chests, Popups, Get Bonuses, Form Levels, and Sora's Levels. This allows abilities that Sora would normally have to also be placed on Keyblades with random stats. With several options on ways to finish the game.
|
||||
|
||||
<h2 style="text-transform:none";>Where is the settings page</h2>
|
||||
|
||||
The [player settings page for this game](../player-settings) contains all the options you need to configure and export a config file.
|
||||
|
||||
|
||||
<h2 style="text-transform:none";>What is randomized in this game?</h2>
|
||||
|
||||
|
||||
The Chests, Popups, Get Bonuses, Form Levels, and Sora's Levels.
|
||||
|
||||
<h2 style="text-transform:none";>What Kingdom Hearts 2 items can appear in other players' worlds?</h2>
|
||||
|
||||
|
||||
Every item in the game with the exception being party members' abilities.
|
||||
|
||||
<h2 style="text-transform:none";>What is The Garden of Assemblage "GoA"?</h2>
|
||||
|
||||
|
||||
The Garden of Assemblage Mod made by Sonicshadowsilver2 and Num turns the Garden of Assemblage into a “World Hub” where each portal takes you to one of the game worlds (as opposed to having a world map). This allows you to enter worlds at any time, and world progression is maintained for each world individually.
|
||||
|
||||
<h2 style="text-transform:none";>What does another world's item look like in Kingdom Hearts 2?</h2>
|
||||
|
||||
|
||||
In Kingdom Hearts 2, items which need to be sent to other worlds appear in any location that has a item in the vanilla game. They are represented by the Archipelago icon, and must be "picked up" as if it were a normal item. Upon obtaining the item, it will be sent to its home world.
|
||||
|
||||
<h2 style="text-transform:none";>When the player receives an item, what happens?</h2>
|
||||
|
||||
|
||||
It is added to your inventory. If you obtain magic, you will need to pause your game to have it show up in your inventory, then enter a new room for it to become properly usable.
|
||||
|
||||
<h2 style="text-transform:none";>What Happens if I die before Room Saving?</h2>
|
||||
|
||||
|
||||
When you die in Kingdom Hearts 2, you are reverted to the last non-boss room you entered and your status is reverted to what it was at that time. However, in archipelago, any item that you have sent/received will not be taken away from the player, unlike vanilla Kingdom Hearts 2.
|
||||
|
||||
|
||||
For example, if you are fighting Roxas and you receive Reflect Element and you die fighting Roxas, you will keep that reflect. You will still need to pause your game to have it show up in your inventory, then enter a new room for it to become properly usable.
|
||||
|
||||
<h2 style="text-transform:none";>Customization options:</h2>
|
||||
|
||||
|
||||
- Choose a goal from the list below (with an additional option to Kill Final Xemnas alongside your goal).
|
||||
1. Obtain Three Proofs.
|
||||
2. Obtain a desired amount of Lucky Emblems.
|
||||
3. Obtain a desired amount of Bounties that are on late locations.
|
||||
- Customize how many World Locking Items You Need to Progress in that World.
|
||||
- Customize the Amount of World Locking Items You Start With.
|
||||
- Customize how many locations you want on Sora's Levels.
|
||||
- Customize the EXP Multiplier of everything that affects Sora.
|
||||
- Customize the Available Abilities on Keyblades.
|
||||
- Customize the level of Progressive Movement (Growth Abilities) you start with.
|
||||
- Customize the amount of Progressive Movement (Growth Abilities) you start with.
|
||||
- Customize start inventory, i.e., begin every run with certain items or spells of your choice.
|
||||
|
||||
<h2 style="text-transform:none";>Quality of life:</h2>
|
||||
|
||||
|
||||
With the help of Shananas, Num, and ZakTheRobot we have many QoL features such are:
|
||||
|
||||
|
||||
- Faster Wardrobe.
|
||||
- Faster Water Jafar Chase.
|
||||
- Carpet Skip.
|
||||
- Start with Lion Dash.
|
||||
- Faster Urns.
|
||||
- Removal of Absent Silhouette and go straight into the Data Fights.
|
||||
- And much more can be found at [Kingdom Hearts 2 GoA Overview](https://tommadness.github.io/KH2Randomizer/overview/)
|
||||
|
||||
<h2 style="text-transform:none";>Recommendation</h2>
|
||||
|
||||
- Recommended making a save at the start of the GoA before opening anything. This will be the recommended file to load if/when your game crashes.
|
||||
- If you don't want to have a save in the GoA. Disconnect the client, load the auto save, and then reconnect the client after it loads the auto save.
|
||||
- Recommended to set fps limit to 60fps.
|
||||
- Recommended to run the game in windows/borderless windowed mode. Fullscreen is stable but the game can crash if you alt-tab out.
|
||||
- Recommend viewing [Requirements/logic sheet](https://docs.google.com/spreadsheets/d/1Embae0t7pIrbzvX-NRywk7bTHHEvuFzzQBUUpSUL7Ak/edit?usp=sharing)
|
||||
|
||||
<h2 style="text-transform:none";>F.A.Q.</h2>
|
||||
|
||||
- Why am I not getting magic?
|
||||
- If you obtain magic, you will need to pause your game to have it show up in your inventory, then enter a new room for it to become properly usable.
|
||||
- Why am I missing worlds/portals in the GoA?
|
||||
- You are missing the required visit locking item to access the world/portal.
|
||||
- What versions of Kingdom Hearts 2 are supported?
|
||||
- Currently `only` the most up to date version on the Epic Game Store is supported `1.0.0.8_WW`. Emulator may be added in the future.
|
||||
- Why did I crash?
|
||||
- The port of Kingdom Hearts 2 can and will randomly crash, this is the fault of the game not the randomizer or the archipelago client.
|
||||
- If you have a continuous/constant crash (in the same area/event every time) you will want to reverify your installed files. This can be done by doing the following: Open Epic Game Store --> Library --> Click Triple Dots --> Manage --> Verify
|
||||
- Why am I getting dummy items or letters?
|
||||
- You will need to get the `JaredWeakStrike/APCompanion` (you can find how to get this in the setup guide)
|
||||
- Why am I not sending or receiving items?
|
||||
- Make sure you are connected to the KH2 client and the correct room (for more information reference the setup guide)
|
||||
- Why did I not load in to the correct visit
|
||||
- You need to trigger a cutscene or visit The World That Never Was for it to update you have recevied the item.
|
||||
- Why should I install the auto save mod at `KH2FM-Mods-equations19/auto-save`?
|
||||
- Because Kingdom Hearts 2 is prone to crashes and will keep you from losing your progress.
|
||||
- How do I load an auto save?
|
||||
- To load an auto-save, hold down the Select or your equivalent on your prefered controller while choosing a file. Make sure to hold the button down the whole time.
|
||||
- How do I do a soft reset?
|
||||
- Hold L1+L2+R1+R2+Start or your equivalent on your prefered controller at the same time to immediately reset the game to the start screen.
|
|
@ -0,0 +1,48 @@
|
|||
# Kingdom Hearts 2 Archipelago Setup Guide
|
||||
<h2 style="text-transform:none";>Quick Links</h2>
|
||||
|
||||
- [Main Page](../../../../games/Kingdom%20Hearts%202/info/en)
|
||||
- [Settings Page](../../../../games/Kingdom%20Hearts%202/player-settings)
|
||||
|
||||
<h2 style="text-transform:none";>Setting up the Mod Manager</h2>
|
||||
|
||||
Follow this Guide [KH2Rando.com](https://tommadness.github.io/KH2Randomizer/setup/Panacea-ModLoader/)
|
||||
|
||||
<h3 style="text-transform:none";>Loading A Seed</h3>
|
||||
|
||||
When you generate a game you will see a download link for a KH2 .zip seed on the room page. Download the seed then open OpenKH Mod Manager and click the green plus and `Select and install Mod Archive`. Make sure the seed is on the top of the list (Highest Priority)
|
||||
|
||||
<h3 style="text-transform:none";>Archipelago Compainion Mod and recommended mods</h3>
|
||||
|
||||
Load this mod just like the GoA ROM you did during the KH2 Rando setup. `JaredWeakStrike/APCompanion` Have this mod second highest priority below the .zip seed
|
||||
Load this mod just like the GoA ROM you did during the KH2 Rando setup. `KH2FM-Mods-equations19/auto-save` Location doesn't matter, recommended in case of crashes.
|
||||
Load this mod just like the GoA ROM you did during the KH2 Rando setup. `KH2FM-Mods-equations19/soft-reset` Location doesn't matter, recommneded in case of soft locks.
|
||||
|
||||
<h2 style="text-transform:none";>Using the KH2 Client</h2>
|
||||
|
||||
Once you have started the game through OpenKH Mod Manager and are on the title screen run the ArchipelagoKH2Client.exe. When you successfully connect to the server the client will automatically hook into the game to send/receive checks. If the client ever loses connection to the game, it will also disconnect from the server and you will need to reconnect. Make sure the game is open whenever you try to connect the client to the server otherwise it will immediately disconnect you. Most checks will be sent to you anywhere outside of a load or cutscene but if you obtain magic, you will need to pause your game to have it show up in your inventory, then enter a new room for it to become properly usable.
|
||||
|
||||
<h2 style="text-transform:none";>Generating a game</h2>
|
||||
|
||||
<h3 style="text-transform:none";>What is a YAML?</h3>
|
||||
|
||||
YAML is the file format which Archipelago uses in order to configure a player's world. It allows you to dictate which
|
||||
game you will be playing as well as the settings you would like for that game.
|
||||
|
||||
YAML is a format very similar to JSON however it is made to be more human-readable. If you are ever unsure of the
|
||||
validity of your YAML file you may check the file by uploading it to the check page on the Archipelago website. Check
|
||||
page: [YAML Validation Page](/mysterycheck)
|
||||
|
||||
<h3 style="text-transform:none";>Creating a YAML</h3>
|
||||
|
||||
YAML files may be generated on the Archipelago website by visiting the games page and clicking the "Settings Page" link
|
||||
under any game. Clicking "Export Settings" in a game's settings page will download the YAML to your system. Games
|
||||
page: [Archipelago Games List](/games)
|
||||
|
||||
In a multiworld there must be one YAML per world. Any number of players can play on each world using either the game's
|
||||
native coop system or using Archipelago's coop support. Each world will hold one slot in the multiworld and will have a
|
||||
slot name and, if the relevant game requires it, files to associate it with that multiworld.
|
||||
|
||||
If multiple people plan to play in one world cooperatively then they will only need one YAML for their coop world. If
|
||||
each player is planning on playing their own game then they will each need a YAML.
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
from .Names import ItemName
|
||||
from ..AutoWorld import LogicMixin
|
||||
|
||||
|
||||
class KH2Logic(LogicMixin):
|
||||
def kh_lod_unlocked(self, player, amount):
|
||||
return self.has(ItemName.SwordoftheAncestor, player, amount)
|
||||
|
||||
def kh_oc_unlocked(self, player, amount):
|
||||
return self.has(ItemName.BattlefieldsofWar, player, amount)
|
||||
|
||||
def kh_twtnw_unlocked(self, player, amount):
|
||||
return self.has(ItemName.WaytotheDawn, player, amount)
|
||||
|
||||
def kh_ht_unlocked(self, player, amount):
|
||||
return self.has(ItemName.BoneFist, player, amount)
|
||||
|
||||
def kh_tt_unlocked(self, player, amount):
|
||||
return self.has(ItemName.IceCream, player, amount)
|
||||
|
||||
def kh_pr_unlocked(self, player, amount):
|
||||
return self.has(ItemName.SkillandCrossbones, player, amount)
|
||||
|
||||
def kh_sp_unlocked(self, player, amount):
|
||||
return self.has(ItemName.IdentityDisk, player, amount)
|
||||
|
||||
def kh_stt_unlocked(self, player: int, amount):
|
||||
return self.has(ItemName.NamineSketches, player, amount)
|
||||
|
||||
# Using Dummy 13 for this
|
||||
def kh_dc_unlocked(self, player: int, amount):
|
||||
return self.has(ItemName.CastleKey, player, amount)
|
||||
|
||||
def kh_hb_unlocked(self, player, amount):
|
||||
return self.has(ItemName.MembershipCard, player, amount)
|
||||
|
||||
def kh_pl_unlocked(self, player, amount):
|
||||
return self.has(ItemName.ProudFang, player, amount)
|
||||
|
||||
def kh_ag_unlocked(self, player, amount):
|
||||
return self.has(ItemName.Scimitar, player, amount)
|
||||
|
||||
def kh_bc_unlocked(self, player, amount):
|
||||
return self.has(ItemName.BeastsClaw, player, amount)
|
||||
|
||||
def kh_amount_of_forms(self, player, amount, requiredform="None"):
|
||||
level = 0
|
||||
formList = [ItemName.ValorForm, ItemName.WisdomForm, ItemName.LimitForm, ItemName.MasterForm,
|
||||
ItemName.FinalForm]
|
||||
# required form is in the logic for region connections
|
||||
if requiredform != "None":
|
||||
formList.remove(requiredform)
|
||||
for form in formList:
|
||||
if self.has(form, player):
|
||||
level += 1
|
||||
return level >= amount
|
||||
|
||||
def kh_visit_locking_amount(self, player, amount):
|
||||
visit = 0
|
||||
# torn pages are not added since you cannot get exp from that world
|
||||
for item in {ItemName.CastleKey, ItemName.BattlefieldsofWar, ItemName.SwordoftheAncestor, ItemName.BeastsClaw,
|
||||
ItemName.BoneFist, ItemName.ProudFang, ItemName.SkillandCrossbones, ItemName.Scimitar,
|
||||
ItemName.MembershipCard,
|
||||
ItemName.IceCream, ItemName.WaytotheDawn,
|
||||
ItemName.IdentityDisk, ItemName.NamineSketches}:
|
||||
visit += self.item_count(item, player)
|
||||
return visit >= amount
|
||||
|
||||
def kh_three_proof_unlocked(self, player):
|
||||
return self.has(ItemName.ProofofConnection, player, 1) \
|
||||
and self.has(ItemName.ProofofNonexistence, player, 1) \
|
||||
and self.has(ItemName.ProofofPeace, player, 1)
|
||||
|
||||
def kh_hitlist(self, player, amount):
|
||||
return self.has(ItemName.Bounty, player, amount)
|
||||
|
||||
def kh_lucky_emblem_unlocked(self, player, amount):
|
||||
return self.has(ItemName.LuckyEmblem, player, amount)
|
||||
|
||||
def kh_victory(self, player):
|
||||
return self.has(ItemName.Victory, player, 1)
|
||||
|
||||
def kh_summon(self, player, amount):
|
||||
summonlevel = 0
|
||||
for summon in {ItemName.Genie, ItemName.ChickenLittle, ItemName.Stitch, ItemName.PeterPan}:
|
||||
if self.has(summon, player):
|
||||
summonlevel += 1
|
||||
return summonlevel >= amount
|
||||
|
||||
# magic progression
|
||||
def kh_fire(self, player):
|
||||
return self.has(ItemName.FireElement, player, 1)
|
||||
|
||||
def kh_fira(self, player):
|
||||
return self.has(ItemName.FireElement, player, 2)
|
||||
|
||||
def kh_firaga(self, player):
|
||||
return self.has(ItemName.FireElement, player, 3)
|
||||
|
||||
def kh_blizzard(self, player):
|
||||
return self.has(ItemName.BlizzardElement, player, 1)
|
||||
|
||||
def kh_blizzara(self, player):
|
||||
return self.has(ItemName.BlizzardElement, player, 2)
|
||||
|
||||
def kh_blizzaga(self, player):
|
||||
return self.has(ItemName.BlizzardElement, player, 3)
|
||||
|
||||
def kh_thunder(self, player):
|
||||
return self.has(ItemName.ThunderElement, player, 1)
|
||||
|
||||
def kh_thundara(self, player):
|
||||
return self.has(ItemName.ThunderElement, player, 2)
|
||||
|
||||
def kh_thundaga(self, player):
|
||||
return self.has(ItemName.ThunderElement, player, 3)
|
||||
|
||||
def kh_magnet(self, player):
|
||||
return self.has(ItemName.MagnetElement, player, 1)
|
||||
|
||||
def kh_magnera(self, player):
|
||||
return self.has(ItemName.MagnetElement, player, 2)
|
||||
|
||||
def kh_magnega(self, player):
|
||||
return self.has(ItemName.MagnetElement, player, 3)
|
||||
|
||||
def kh_reflect(self, player):
|
||||
return self.has(ItemName.ReflectElement, player, 1)
|
||||
|
||||
def kh_reflera(self, player):
|
||||
return self.has(ItemName.ReflectElement, player, 2)
|
||||
|
||||
def kh_reflega(self, player):
|
||||
return self.has(ItemName.ReflectElement, player, 3)
|
||||
|
||||
def kh_highjump(self, player, amount):
|
||||
return self.has(ItemName.HighJump, player, amount)
|
||||
|
||||
def kh_quickrun(self, player, amount):
|
||||
return self.has(ItemName.QuickRun, player, amount)
|
||||
|
||||
def kh_dodgeroll(self, player, amount):
|
||||
return self.has(ItemName.DodgeRoll, player, amount)
|
||||
|
||||
def kh_aerialdodge(self, player, amount):
|
||||
return self.has(ItemName.AerialDodge, player, amount)
|
||||
|
||||
def kh_glide(self, player, amount):
|
||||
return self.has(ItemName.Glide, player, amount)
|
||||
|
||||
def kh_comboplus(self, player, amount):
|
||||
return self.has(ItemName.ComboPlus, player, amount)
|
||||
|
||||
def kh_aircomboplus(self, player, amount):
|
||||
return self.has(ItemName.AirComboPlus, player, amount)
|
||||
|
||||
def kh_valorgenie(self, player):
|
||||
return self.has(ItemName.Genie, player) and self.has(ItemName.ValorForm, player)
|
||||
|
||||
def kh_wisdomgenie(self, player):
|
||||
return self.has(ItemName.Genie, player) and self.has(ItemName.WisdomForm, player)
|
||||
|
||||
def kh_mastergenie(self, player):
|
||||
return self.has(ItemName.Genie, player) and self.has(ItemName.MasterForm, player)
|
||||
|
||||
def kh_finalgenie(self, player):
|
||||
return self.has(ItemName.Genie, player) and self.has(ItemName.FinalForm, player)
|
||||
|
||||
def kh_rsr(self, player):
|
||||
return self.has(ItemName.Slapshot, player, 1) and self.has(ItemName.ComboMaster, player) and self.kh_reflect(
|
||||
player)
|
||||
|
||||
def kh_gapcloser(self, player):
|
||||
return self.has(ItemName.FlashStep, player, 1) or self.has(ItemName.SlideDash, player)
|
||||
|
||||
# Crowd Control and Berserk Hori will be used when I add hard logic.
|
||||
|
||||
def kh_crowdcontrol(self, player):
|
||||
return self.kh_magnera(player) and self.has(ItemName.ChickenLittle, player) \
|
||||
or self.kh_magnega(player) and self.kh_mastergenie(player)
|
||||
|
||||
def kh_berserkhori(self, player):
|
||||
return self.has(ItemName.HorizontalSlash, player, 1) and self.has(ItemName.BerserkCharge, player)
|
||||
|
||||
def kh_donaldlimit(self, player):
|
||||
return self.has(ItemName.FlareForce, player, 1) or self.has(ItemName.Fantasia, player)
|
||||
|
||||
def kh_goofylimit(self, player):
|
||||
return self.has(ItemName.TornadoFusion, player, 1) or self.has(ItemName.Teamwork, player)
|
||||
|
||||
def kh_basetools(self, player):
|
||||
# TODO: if option is easy then add reflect,gap closer and second chance&once more. #option east scom option normal adds gap closer or combo master #hard is what is right now
|
||||
return self.has(ItemName.Guard, player, 1) and self.has(ItemName.AerialRecovery, player, 1) \
|
||||
and self.has(ItemName.FinishingPlus, player, 1)
|
||||
|
||||
def kh_roxastools(self, player):
|
||||
return self.kh_basetools(player) and (
|
||||
self.has(ItemName.QuickRun, player) or self.has(ItemName.NegativeCombo, player, 2))
|
||||
|
||||
def kh_painandpanic(self, player):
|
||||
return (self.kh_goofylimit(player) or self.kh_donaldlimit(player)) and self.kh_dc_unlocked(player, 2)
|
||||
|
||||
def kh_cerberuscup(self, player):
|
||||
return self.kh_amount_of_forms(player, 2) and self.kh_thundara(player) \
|
||||
and self.kh_ag_unlocked(player, 1) and self.kh_ht_unlocked(player, 1) \
|
||||
and self.kh_pl_unlocked(player, 1)
|
||||
|
||||
def kh_titan(self, player: int):
|
||||
return self.kh_summon(player, 2) and (self.kh_thundara(player) or self.kh_magnera(player)) \
|
||||
and self.kh_oc_unlocked(player, 2)
|
||||
|
||||
def kh_gof(self, player):
|
||||
return self.kh_titan(player) and self.kh_cerberuscup(player) \
|
||||
and self.kh_painandpanic(player) and self.kh_twtnw_unlocked(player, 1)
|
||||
|
||||
def kh_dataroxas(self, player):
|
||||
return self.kh_basetools(player) and \
|
||||
((self.has(ItemName.LimitForm, player) and self.kh_amount_of_forms(player, 3) and self.has(
|
||||
ItemName.TrinityLimit, player) and self.kh_gapcloser(player))
|
||||
or (self.has(ItemName.NegativeCombo, player, 2) or self.kh_quickrun(player, 2)))
|
||||
|
||||
def kh_datamarluxia(self, player):
|
||||
return self.kh_basetools(player) and self.kh_reflera(player) \
|
||||
and ((self.kh_amount_of_forms(player, 3) and self.has(ItemName.FinalForm, player) and self.kh_fira(
|
||||
player)) or self.has(ItemName.NegativeCombo, player, 2) or self.kh_donaldlimit(player))
|
||||
|
||||
def kh_datademyx(self, player):
|
||||
return self.kh_basetools(player) and self.kh_amount_of_forms(player, 5) and self.kh_firaga(player) \
|
||||
and (self.kh_donaldlimit(player) or self.kh_blizzard(player))
|
||||
|
||||
def kh_datalexaeus(self, player):
|
||||
return self.kh_basetools(player) and self.kh_amount_of_forms(player, 3) and self.kh_reflera(player) \
|
||||
and (self.has(ItemName.NegativeCombo, player, 2) or self.kh_donaldlimit(player))
|
||||
|
||||
def kh_datasaix(self, player):
|
||||
return self.kh_basetools(player) and (self.kh_thunder(player) or self.kh_blizzard(player)) \
|
||||
and self.kh_highjump(player, 2) and self.kh_aerialdodge(player, 2) and self.kh_glide(player, 2) and self.kh_amount_of_forms(player, 3) \
|
||||
and (self.kh_rsr(player) or self.has(ItemName.NegativeCombo, player, 2) or self.has(ItemName.PeterPan,
|
||||
player))
|
||||
|
||||
def kh_dataxaldin(self, player):
|
||||
return self.kh_basetools(player) and self.kh_donaldlimit(player) and self.kh_goofylimit(player) \
|
||||
and self.kh_highjump(player, 2) and self.kh_aerialdodge(player, 2) and self.kh_glide(player,
|
||||
2) and self.kh_magnet(
|
||||
player)
|
||||
# and (self.kh_form_level_unlocked(player, 3) or self.kh_berserkhori(player))
|
||||
|
||||
def kh_dataxemnas(self, player):
|
||||
return self.kh_basetools(player) and self.kh_rsr(player) and self.kh_gapcloser(player) \
|
||||
and (self.has(ItemName.LimitForm, player) or self.has(ItemName.TrinityLimit, player))
|
||||
|
||||
def kh_dataxigbar(self, player):
|
||||
return self.kh_basetools(player) and self.kh_donaldlimit(player) and self.has(ItemName.FinalForm, player) \
|
||||
and self.kh_amount_of_forms(player, 3) and self.kh_reflera(player)
|
||||
|
||||
def kh_datavexen(self, player):
|
||||
return self.kh_basetools(player) and self.kh_donaldlimit(player) and self.has(ItemName.FinalForm, player) \
|
||||
and self.kh_amount_of_forms(player, 4) and self.kh_reflera(player) and self.kh_fira(player)
|
||||
|
||||
def kh_datazexion(self, player):
|
||||
return self.kh_basetools(player) and self.kh_donaldlimit(player) and self.has(ItemName.FinalForm, player) \
|
||||
and self.kh_amount_of_forms(player, 3) \
|
||||
and self.kh_reflera(player) and self.kh_fira(player)
|
||||
|
||||
def kh_dataaxel(self, player):
|
||||
return self.kh_basetools(player) \
|
||||
and ((self.kh_reflera(player) and self.kh_blizzara(player)) or self.has(ItemName.NegativeCombo, player, 2))
|
||||
|
||||
def kh_dataluxord(self, player):
|
||||
return self.kh_basetools(player) and self.kh_reflect(player)
|
||||
|
||||
def kh_datalarxene(self, player):
|
||||
return self.kh_basetools(player) and self.kh_reflera(player) \
|
||||
and ((self.has(ItemName.FinalForm, player) and self.kh_amount_of_forms(player, 4) and self.kh_fire(
|
||||
player))
|
||||
or (self.kh_donaldlimit(player) and self.kh_amount_of_forms(player, 2)))
|
||||
|
||||
def kh_sephi(self, player):
|
||||
return self.kh_dataxemnas(player)
|
||||
|
||||
def kh_onek(self, player):
|
||||
return self.kh_reflect(player) or self.has(ItemName.Guard, player)
|
||||
|
||||
def kh_terra(self, player):
|
||||
return self.has(ItemName.ProofofConnection, player) and self.kh_basetools(player) \
|
||||
and self.kh_dodgeroll(player, 2) and self.kh_aerialdodge(player, 2) and self.kh_glide(player, 3) \
|
||||
and ((self.kh_comboplus(player, 2) and self.has(ItemName.Explosion, player)) or self.has(
|
||||
ItemName.NegativeCombo, player, 2))
|
||||
|
||||
def kh_cor(self, player):
|
||||
return self.kh_reflect(player) \
|
||||
and self.kh_highjump(player, 2) and self.kh_quickrun(player, 2) and self.kh_aerialdodge(player, 2) \
|
||||
and (self.has(ItemName.MasterForm, player) and self.kh_fire(player)
|
||||
or (self.has(ItemName.ChickenLittle, player) and self.kh_donaldlimit(player) and self.kh_glide(player,
|
||||
2)))
|
||||
|
||||
def kh_transport(self, player):
|
||||
return self.kh_basetools(player) and self.kh_reflera(player) \
|
||||
and ((self.kh_mastergenie(player) and self.kh_magnera(player) and self.kh_donaldlimit(player))
|
||||
or (self.has(ItemName.FinalForm, player) and self.kh_amount_of_forms(player, 4) and self.kh_fira(
|
||||
player)))
|
||||
|
||||
def kh_gr2(self, player):
|
||||
return (self.has(ItemName.MasterForm, player) or self.has(ItemName.Stitch, player)) \
|
||||
and (self.kh_fire(player) or self.kh_blizzard(player) or self.kh_thunder(player))
|
||||
|
||||
def kh_xaldin(self, player):
|
||||
return self.kh_basetools(player) and (self.kh_donaldlimit(player) or self.kh_amount_of_forms(player, 1))
|
||||
|
||||
def kh_mcp(self, player):
|
||||
return self.kh_reflect(player) and (
|
||||
self.has(ItemName.MasterForm, player) or self.has(ItemName.FinalForm, player))
|
|
@ -0,0 +1,50 @@
|
|||
assets:
|
||||
- method: binarc
|
||||
multi:
|
||||
- name: msg/us/jm.bar
|
||||
- name: msg/uk/jm.bar
|
||||
name: msg/jp/jm.bar
|
||||
source:
|
||||
- method: kh2msg
|
||||
name: jm
|
||||
source:
|
||||
- language: en
|
||||
name: jm.yml
|
||||
type: list
|
||||
- method: binarc
|
||||
name: 00battle.bin
|
||||
source:
|
||||
- method: listpatch
|
||||
name: fmlv
|
||||
source:
|
||||
- name: FmlvList.yml
|
||||
type: fmlv
|
||||
type: List
|
||||
- method: listpatch
|
||||
name: lvup
|
||||
source:
|
||||
- name: LvupList.yml
|
||||
type: lvup
|
||||
type: List
|
||||
- method: listpatch
|
||||
name: bons
|
||||
source:
|
||||
- name: BonsList.yml
|
||||
type: bons
|
||||
type: List
|
||||
- method: binarc
|
||||
name: 03system.bin
|
||||
source:
|
||||
- method: listpatch
|
||||
name: trsr
|
||||
source:
|
||||
- name: TrsrList.yml
|
||||
type: trsr
|
||||
type: List
|
||||
- method: listpatch
|
||||
name: item
|
||||
source:
|
||||
- name: ItemList.yml
|
||||
type: item
|
||||
type: List
|
||||
title: Randomizer Seed
|
|
@ -0,0 +1 @@
|
|||
Pymem>=1.10.0
|
|
@ -0,0 +1,27 @@
|
|||
from . import KH2TestBase
|
||||
from ..Names import ItemName,LocationName,RegionName
|
||||
|
||||
class TestDefault(KH2TestBase):
|
||||
options = {}
|
||||
|
||||
def testEverything(self):
|
||||
self.collect_all_but([ItemName.Victory])
|
||||
self.assertBeatable(True)
|
||||
|
||||
|
||||
class TestLuckyEmblem(KH2TestBase):
|
||||
options = {
|
||||
"Goal": 1,
|
||||
}
|
||||
|
||||
def testEverything(self):
|
||||
self.collect_all_but([ItemName.LuckyEmblem])
|
||||
self.assertBeatable(True)
|
||||
|
||||
class TestHitList(KH2TestBase):
|
||||
options = {
|
||||
"Goal": 2,
|
||||
}
|
||||
def testEverything(self):
|
||||
self.collect_all_but([ItemName.Bounty])
|
||||
self.assertBeatable(True)
|
|
@ -0,0 +1,5 @@
|
|||
from test.TestBase import WorldTestBase
|
||||
|
||||
|
||||
class KH2TestBase(WorldTestBase):
|
||||
game = "Kingdom Hearts 2"
|
Loading…
Reference in New Issue