Pokémon Red and Blue: Version 2 (#1282)

Adds Trainersanity option (Each non-scripted trainer has a location check, adding 317 locations)
Adds Randomize Pokedex option. It is required to obtain items from Oak's Aides.
Adds option to add all normal shop items to all normal shops.
Adds DeathLink option.
Adds traps.
Improves Type Chart randomization.
Items can be received during battle.
Stores start inventory in ROM. Only requests remote start inventory if patch is from v1.
Fixes logic bugs.
Various other improvements.
This commit is contained in:
Alchav 2022-12-07 18:38:34 -05:00 committed by GitHub
parent 5273812039
commit e206c065bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1775 additions and 870 deletions

View File

@ -39,6 +39,8 @@ CONNECTION_INITIAL_STATUS = "Connection has not been initiated"
DISPLAY_MSGS = True
SCRIPT_VERSION = 1
class GBCommandProcessor(ClientCommandProcessor):
def __init__(self, ctx: CommonContext):
@ -53,7 +55,6 @@ class GBCommandProcessor(ClientCommandProcessor):
class GBContext(CommonContext):
command_processor = GBCommandProcessor
game = 'Pokemon Red and Blue'
items_handling = 0b101
def __init__(self, server_address, password):
super().__init__(server_address, password)
@ -64,6 +65,10 @@ class GBContext(CommonContext):
self.gb_status = CONNECTION_INITIAL_STATUS
self.awaiting_rom = False
self.display_msgs = True
self.deathlink_pending = False
self.set_deathlink = False
self.client_compatibility_mode = 0
self.items_handling = 0b001
async def server_auth(self, password_requested: bool = False):
if password_requested and not self.password:
@ -82,6 +87,8 @@ class GBContext(CommonContext):
def on_package(self, cmd: str, args: dict):
if cmd == 'Connected':
self.locations_array = None
if 'death_link' in args['slot_data'] and args['slot_data']['death_link']:
self.set_deathlink = True
elif cmd == "RoomInfo":
self.seed_name = args['seed_name']
elif cmd == 'Print':
@ -92,6 +99,10 @@ class GBContext(CommonContext):
msg = f"Received {', '.join([self.item_names[item.item] for item in args['items']])}"
self._set_message(msg, SYSTEM_MESSAGE_ID)
def on_deathlink(self, data: dict):
self.deathlink_pending = True
super().on_deathlink(data)
def run_gui(self):
from kvui import GameManager
@ -107,13 +118,16 @@ class GBContext(CommonContext):
def get_payload(ctx: GBContext):
current_time = time.time()
return json.dumps(
ret = json.dumps(
{
"items": [item.item for item in ctx.items_received],
"messages": {f'{key[0]}:{key[1]}': value for key, value in ctx.messages.items()
if key[0] > current_time - 10}
if key[0] > current_time - 10},
"deathlink": ctx.deathlink_pending
}
)
ctx.deathlink_pending = False
return ret
async def parse_locations(data: List, ctx: GBContext):
@ -121,14 +135,8 @@ async def parse_locations(data: List, ctx: GBContext):
flags = {"EventFlag": data[:0x140], "Missable": data[0x140:0x140 + 0x20],
"Hidden": data[0x140 + 0x20: 0x140 + 0x20 + 0x0E], "Rod": data[0x140 + 0x20 + 0x0E:]}
# Check for clear problems
if len(flags['Rod']) > 1:
return
if flags["EventFlag"][1] + flags["EventFlag"][8] + flags["EventFlag"][9] + flags["EventFlag"][12] \
+ flags["EventFlag"][61] + flags["EventFlag"][62] + flags["EventFlag"][63] + flags["EventFlag"][64] \
+ flags["EventFlag"][65] + flags["EventFlag"][66] + flags["EventFlag"][67] + flags["EventFlag"][68] \
+ flags["EventFlag"][69] + flags["EventFlag"][70] != 0:
return
for flag_type, loc_map in location_map.items():
for flag, loc_id in loc_map.items():
@ -168,8 +176,15 @@ async def gb_sync_task(ctx: GBContext):
# 2. An array representing the memory values of the locations area (if in game)
data = await asyncio.wait_for(reader.readline(), timeout=5)
data_decoded = json.loads(data.decode())
#print(data_decoded)
if 'scriptVersion' not in data_decoded or data_decoded['scriptVersion'] != SCRIPT_VERSION:
msg = "You are connecting with an incompatible Lua script version. Ensure your connector Lua " \
"and PokemonClient are from the same Archipelago installation."
logger.info(msg, extra={'compact_gui': True})
ctx.gui_error('Error', msg)
error_status = CONNECTION_RESET_STATUS
ctx.client_compatibility_mode = data_decoded['clientCompatibilityVersion']
if ctx.client_compatibility_mode == 0:
ctx.items_handling = 0b101 # old patches will not have local start inventory, must be requested
if ctx.seed_name and ctx.seed_name != ''.join([chr(i) for i in data_decoded['seedName'] if i != 0]):
msg = "The server is running a different multiworld than your client is. (invalid seed_name)"
logger.info(msg, extra={'compact_gui': True})
@ -179,13 +194,20 @@ async def gb_sync_task(ctx: GBContext):
if not ctx.auth:
ctx.auth = ''.join([chr(i) for i in data_decoded['playerName'] if i != 0])
if ctx.auth == '':
logger.info("Invalid ROM detected. No player name built into the ROM.")
msg = "Invalid ROM detected. No player name built into the ROM."
logger.info(msg, extra={'compact_gui': True})
ctx.gui_error('Error', msg)
error_status = CONNECTION_RESET_STATUS
if ctx.awaiting_rom:
await ctx.server_auth(False)
if 'locations' in data_decoded and ctx.game and ctx.gb_status == CONNECTION_CONNECTED_STATUS \
and not error_status and ctx.auth:
# Not just a keep alive ping, parse
async_start(parse_locations(data_decoded['locations'], ctx))
if 'deathLink' in data_decoded and data_decoded['deathLink'] and 'DeathLink' in ctx.tags:
await ctx.send_death(ctx.auth + " is out of usable Pokémon! " + ctx.auth + " blacked out!")
if ctx.set_deathlink:
await ctx.update_death_link(True)
except asyncio.TimeoutError:
logger.debug("Read Timed Out, Reconnecting")
error_status = CONNECTION_TIMING_OUT_STATUS

View File

@ -38,7 +38,7 @@ class Version(typing.NamedTuple):
build: int
__version__ = "0.3.6"
__version__ = "0.3.7"
version_tuple = tuplize_version(__version__)
is_linux = sys.platform.startswith("linux")

View File

@ -7,18 +7,25 @@ local STATE_TENTATIVELY_CONNECTED = "Tentatively Connected"
local STATE_INITIAL_CONNECTION_MADE = "Initial Connection Made"
local STATE_UNINITIALIZED = "Uninitialized"
local SCRIPT_VERSION = 1
local APIndex = 0x1A6E
local APDeathLinkAddress = 0x00FD
local APItemAddress = 0x00FF
local EventFlagAddress = 0x1735
local MissableAddress = 0x161A
local HiddenItemsAddress = 0x16DE
local RodAddress = 0x1716
local InGame = 0x1A71
local ClientCompatibilityAddress = 0xFF00
local ItemsReceived = nil
local playerName = nil
local seedName = nil
local deathlink_rec = nil
local deathlink_send = false
local prevstate = ""
local curstate = STATE_UNINITIALIZED
local gbSocket = nil
@ -69,11 +76,10 @@ function processBlock(block)
end
local itemsBlock = block["items"]
memDomain.wram()
if itemsBlock ~= nil then-- and u8(0x116B) ~= 0x00 then
-- print(itemsBlock)
ItemsReceived = itemsBlock
if itemsBlock ~= nil then
ItemsReceived = itemsBlock
end
deathlink_rec = block["deathlink"]
end
function difference(a, b)
@ -104,14 +110,7 @@ function generateLocationsChecked()
return data
end
function generateSerialData()
memDomain.wram()
status = u8(0x1A73)
if status == 0 then
return nil
end
return uRange(0x1A76, u8(0x1A74))
end
local function arrayEqual(a1, a2)
if #a1 ~= #a2 then
return false
@ -135,7 +134,6 @@ function receive()
curstate = STATE_UNINITIALIZED
return
elseif e == 'timeout' then
print("timeout")
return
elseif e ~= nil then
print(e)
@ -157,16 +155,16 @@ function receive()
playerName = newPlayerName
seedName = newSeedName
local retTable = {}
retTable["scriptVersion"] = SCRIPT_VERSION
retTable["clientCompatibilityVersion"] = u8(ClientCompatibilityAddress)
retTable["playerName"] = playerName
retTable["seedName"] = seedName
memDomain.wram()
if u8(InGame) == 0xAC then
retTable["locations"] = generateLocationsChecked()
serialData = generateSerialData()
if serialData ~= nil then
retTable["serial"] = serialData
end
end
retTable["deathLink"] = deathlink_send
deathlink_send = false
msg = json.encode(retTable).."\n"
local ret, error = gbSocket:send(msg)
if ret == nil then
@ -197,6 +195,12 @@ function main()
receive()
if u8(InGame) == 0xAC and u8(APItemAddress) == 0x00 then
ItemIndex = u16(APIndex)
if deathlink_rec == true then
wU8(APDeathLinkAddress, 1)
elseif u8(APDeathLinkAddress) == 3 then
wU8(APDeathLinkAddress, 0)
deathlink_send = true
end
if ItemsReceived[ItemIndex + 1] ~= nil then
wU8(APItemAddress, ItemsReceived[ItemIndex + 1] - 172000000)
end
@ -212,7 +216,6 @@ function main()
print("Attempting to connect")
local client, timeout = server:accept()
if timeout == nil then
-- print('Initial Connection Made')
curstate = STATE_INITIAL_CONNECTION_MADE
gbSocket = client
gbSocket:settimeout(0)

View File

@ -39,9 +39,12 @@ class PokemonRedBlueWorld(World):
game = "Pokemon Red and Blue"
option_definitions = pokemon_rb_options
remote_items = False
data_version = 1
data_version = 3
required_client_version = (0, 3, 7)
topology_present = False
item_name_to_id = {name: data.id for name, data in item_table.items()}
location_name_to_id = {location.name: location.address for location in location_data if location.type == "Item"}
item_name_groups = item_groups
@ -77,8 +80,14 @@ class PokemonRedBlueWorld(World):
return encode_text(name, length=8, whitespace="@", safety=True)
except KeyError as e:
raise KeyError(f"Invalid character(s) in {t} name for player {self.multiworld.player_name[self.player]}") from e
self.trainer_name = encode_name(self.multiworld.trainer_name[self.player].value, "Player")
self.rival_name = encode_name(self.multiworld.rival_name[self.player].value, "Rival")
if self.multiworld.trainer_name[self.player] == "choose_in_game":
self.trainer_name = "choose_in_game"
else:
self.trainer_name = encode_name(self.multiworld.trainer_name[self.player].value, "Player")
if self.multiworld.rival_name[self.player] == "choose_in_game":
self.rival_name = "choose_in_game"
else:
self.rival_name = encode_name(self.multiworld.rival_name[self.player].value, "Rival")
if len(self.multiworld.player_name[self.player].encode()) > 16:
raise Exception(f"Player name too long for {self.multiworld.get_player_name(self.player)}. Player name cannot exceed 16 bytes for Pokémon Red and Blue.")
@ -100,26 +109,31 @@ class PokemonRedBlueWorld(World):
def create_items(self) -> None:
start_inventory = self.multiworld.start_inventory[self.player].value.copy()
if self.multiworld.randomize_pokedex[self.player] == "start_with":
start_inventory["Pokedex"] = 1
self.multiworld.push_precollected(self.create_item("Pokedex"))
locations = [location for location in location_data if location.type == "Item"]
item_pool = []
for location in locations:
if "Hidden" in location.name and not self.multiworld.randomize_hidden_items[self.player].value:
continue
if "Rock Tunnel B1F" in location.region and not self.multiworld.extra_key_items[self.player].value:
continue
if location.name == "Celadon City - Mansion Lady" and not self.multiworld.tea[self.player].value:
if not location.inclusion(self.multiworld, self.player):
continue
if location.original_item in self.multiworld.start_inventory[self.player].value and \
location.original_item in item_groups["Unique"]:
start_inventory[location.original_item] -= 1
item = self.create_filler()
elif location.original_item is None:
item = self.create_filler()
else:
item = self.create_item(location.original_item)
if (item.classification == ItemClassification.filler and self.multiworld.random.randint(1, 100)
<= self.multiworld.trap_percentage[self.player].value):
item = self.create_item(self.multiworld.random.choice([item for item in item_table if
item_table[item].classification == ItemClassification.trap]))
if location.event:
self.multiworld.get_location(location.name, self.player).place_locked_item(item)
elif ("Badge" not in item.name or self.multiworld.badgesanity[self.player].value) and \
(item.name != "Oak's Parcel" or self.multiworld.old_man[self.player].value != 1):
elif "Badge" not in item.name or self.multiworld.badgesanity[self.player].value:
item_pool.append(item)
self.multiworld.random.shuffle(item_pool)
self.multiworld.itempool += item_pool
@ -130,13 +144,7 @@ class PokemonRedBlueWorld(World):
process_static_pokemon(self)
if self.multiworld.old_man[self.player].value == 1:
item = self.create_item("Oak's Parcel")
locations = []
for location in self.multiworld.get_locations():
if location.player == self.player and location.item is None and location.can_reach(self.multiworld.state) \
and location.item_rule(item):
locations.append(location)
self.multiworld.random.choice(locations).place_locked_item(item)
self.multiworld.local_early_items[self.player]["Oak's Parcel"] = 1
if not self.multiworld.badgesanity[self.player].value:
self.multiworld.non_local_items[self.player].value -= self.item_name_groups["Badges"]
@ -178,7 +186,7 @@ class PokemonRedBlueWorld(World):
if loc.name in self.multiworld.priority_locations[self.player].value:
add_item_rule(loc, lambda i: i.advancement)
for item in reversed(self.multiworld.itempool):
if item.player == self.player and loc.item_rule(item):
if item.player == self.player and loc.can_fill(self.multiworld.state, item, False):
self.multiworld.itempool.remove(item)
state = sweep_from_pool(self.multiworld.state, self.multiworld.itempool + unplaced_items)
if state.can_reach(loc, "Location", self.player):
@ -239,19 +247,21 @@ class PokemonRedBlueWorld(World):
spoiler_handle.write(hm_move + " enabled by: " + (" " * 20)[:20 - len(hm_move)] + badge + "\n")
def write_spoiler(self, spoiler_handle):
if self.multiworld.randomize_type_matchup_types[self.player].value or \
self.multiworld.randomize_type_matchup_type_effectiveness[self.player].value:
if self.multiworld.randomize_type_chart[self.player].value:
spoiler_handle.write(f"\n\nType matchups ({self.multiworld.player_name[self.player]}):\n\n")
for matchup in self.type_chart:
spoiler_handle.write(f"{matchup[0]} deals {matchup[2] * 10}% damage to {matchup[1]}\n")
def get_filler_item_name(self) -> str:
return self.multiworld.random.choice([item for item in item_table if item_table[item].classification in
[ItemClassification.filler, ItemClassification.trap] and item not in
item_groups["Vending Machine Drinks"]])
if self.multiworld.random.randint(1, 100) <= self.multiworld.trap_percentage[self.player].value:
return self.multiworld.random.choice([item for item in item_table if
item_table[item].classification == ItemClassification.trap])
return self.multiworld.random.choice([item for item in item_table if item_table[
item].classification == ItemClassification.filler and item not in item_groups["Vending Machine Drinks"] +
item_groups["Unique"]])
def fill_slot_data(self) -> dict:
# for trackers
return {
"second_fossil_check_condition": self.multiworld.second_fossil_check_condition[self.player].value,
"require_item_finder": self.multiworld.require_item_finder[self.player].value,
@ -268,7 +278,11 @@ class PokemonRedBlueWorld(World):
"victory_road_condition": self.multiworld.victory_road_condition[self.player].value,
"viridian_gym_condition": self.multiworld.viridian_gym_condition[self.player].value,
"free_fly_map": self.fly_map_code,
"extra_badges": self.extra_badges
"extra_badges": self.extra_badges,
"type_chart": self.type_chart,
"randomize_pokedex": self.multiworld.randomize_pokedex[self.player].value,
"trainersanity": self.multiworld.trainersanity[self.player].value,
"death_link": self.multiworld.death_link[self.player].value
}

View File

@ -32,6 +32,7 @@ fossil scientist. This may require reviving a number of fossils, depending on yo
* Much of the dialogue throughout the game has been removed or shortened.
* If the Old Man is blocking your way through Viridian City, you do not have Oak's Parcel in your inventory, and you've
exhausted your money and Poké Balls, you can get a free Poké Ball from your mom.
* HM moves can be overwritten if you have the HM for it in your bag.
## What items and locations get shuffled?

View File

@ -25,8 +25,8 @@ Once Bizhawk has been installed, open Bizhawk and change the following settings:
- Under Config > Customize > Advanced, make sure the box for AutoSaveRAM is checked, and click the 5s button.
This reduces the possibility of losing save data in emulator crashes.
- Under Config > Customize, check the "Run in background" and "Accept background input" boxes. This will allow you to
continue playing in the background, even if another window is selected.
- Under Config > Customize, check the "Run in background" box. This will prevent disconnecting from the client while
BizHawk is running in the background.
It is strongly recommended to associate GB rom extensions (\*.gb) to the Bizhawk we've just installed.
To do so, we simply have to search any Gameboy rom we happened to own, right click and select "Open with...", unfold

View File

@ -16,7 +16,7 @@ item_table = {
"Bicycle": ItemData(6, ItemClassification.progression, ["Unique", "Key Items"]),
# "Flippers": ItemData(7, ItemClassification.progression),
#"Safari Ball": ItemData(8, ItemClassification.filler),
#"Pokedex": ItemData(9, ItemClassification.filler),
"Pokedex": ItemData(9, ItemClassification.progression, ["Unique", "Key Items"]),
"Moon Stone": ItemData(10, ItemClassification.useful, ["Unique", "Evolution Stones"]),
"Antidote": ItemData(11, ItemClassification.filler, ["Consumables"]),
"Burn Heal": ItemData(12, ItemClassification.filler, ["Consumables"]),
@ -99,13 +99,17 @@ item_table = {
"Mansion Key": ItemData(90, ItemClassification.progression, ["Unique", "Key Items"]),
"Hideout Key": ItemData(91, ItemClassification.progression, ["Unique", "Key Items"]),
"Safari Pass": ItemData(93, ItemClassification.progression, ["Unique", "Key Items"]),
"Poison Trap": ItemData(94, ItemClassification.trap, ["Traps"]),
"Paralyze Trap": ItemData(95, ItemClassification.trap, ["Traps"]),
"Ice Trap": ItemData(96, ItemClassification.trap, ["Traps"]),
"Fire Trap": ItemData(97, ItemClassification.trap, ["Traps"]),
"HM01 Cut": ItemData(196, ItemClassification.progression, ["Unique", "HMs"]),
"HM02 Fly": ItemData(197, ItemClassification.progression, ["Unique", "HMs"]),
"HM03 Surf": ItemData(198, ItemClassification.progression, ["Unique", "HMs"]),
"HM04 Strength": ItemData(199, ItemClassification.progression, ["Unique", "HMs"]),
"HM05 Flash": ItemData(200, ItemClassification.progression, ["Unique", "HMs"]),
"TM01 Mega Punch": ItemData(201, ItemClassification.useful, ["Unique", "TMs"]),
"TM02 Razor Wind": ItemData(202, ItemClassification.useful, ["Unique", "TMs"]),
"TM02 Razor Wind": ItemData(202, ItemClassification.filler, ["Unique", "TMs"]),
"TM03 Swords Dance": ItemData(203, ItemClassification.useful, ["Unique", "TMs"]),
"TM04 Whirlwind": ItemData(204, ItemClassification.filler, ["Unique", "TMs"]),
"TM05 Mega Kick": ItemData(205, ItemClassification.useful, ["Unique", "TMs"]),
@ -139,12 +143,12 @@ item_table = {
"TM33 Reflect": ItemData(233, ItemClassification.useful, ["Unique", "TMs"]),
"TM34 Bide": ItemData(234, ItemClassification.filler, ["Unique", "TMs"]),
"TM35 Metronome": ItemData(235, ItemClassification.useful, ["Unique", "TMs"]),
"TM36 Self Destruct": ItemData(236, ItemClassification.useful, ["Unique", "TMs"]),
"TM36 Self-Destruct": ItemData(236, ItemClassification.useful, ["Unique", "TMs"]),
"TM37 Egg Bomb": ItemData(237, ItemClassification.useful, ["Unique", "TMs"]),
"TM38 Fire Blast": ItemData(238, ItemClassification.useful, ["Unique", "TMs"]),
"TM39 Swift": ItemData(239, ItemClassification.useful, ["Unique", "TMs"]),
"TM40 Skull Bash": ItemData(240, ItemClassification.filler, ["Unique", "TMs"]),
"TM41 Soft Boiled": ItemData(241, ItemClassification.useful, ["Unique", "TMs"]),
"TM41 Soft-Boiled": ItemData(241, ItemClassification.useful, ["Unique", "TMs"]),
"TM42 Dream Eater": ItemData(242, ItemClassification.useful, ["Unique", "TMs"]),
"TM43 Sky Attack": ItemData(243, ItemClassification.filler, ["Unique", "TMs"]),
"TM44 Rest": ItemData(244, ItemClassification.useful, ["Unique", "TMs"]),

View File

@ -3,8 +3,34 @@ from BaseClasses import Location
from .rom_addresses import rom_addresses
loc_id_start = 172000000
def trainersanity(multiworld, player):
return multiworld.trainersanity[player]
def hidden_items(multiworld, player):
return multiworld.randomize_hidden_items[player].value > 0
def tea(multiworld, player):
return multiworld.tea[player]
def extra_key_items(multiworld, player):
return multiworld.extra_key_items[player]
def pokedex(multiworld, player):
return multiworld.randomize_pokedex[player].value > 0
def always_on(multiworld, player):
return True
class LocationData:
def __init__(self, region, name, original_item, rom_address=None, ram_address=None, event=False, type="Item"):
def __init__(self, region, name, original_item, rom_address=None, ram_address=None, event=False, type="Item", inclusion=always_on):
self.region = region
if "Route" in region:
region = " ".join(region.split()[:2])
@ -14,6 +40,7 @@ class LocationData:
self.ram_address = ram_address
self.event = event
self.type = type
self.inclusion = inclusion
class EventFlag:
def __init__(self, flag):
@ -42,6 +69,7 @@ class Rod:
self.bit = flag
self.flag = flag
location_data = [
LocationData("Vermilion City", "Fishing Guru", "Old Rod", rom_addresses["Rod_Vermilion_City_Fishing_Guru"], Rod(3)),
@ -49,7 +77,7 @@ location_data = [
LocationData("Route 12 South", "Fishing Guru's Brother", "Super Rod", rom_addresses["Rod_Route12_Fishing_Brother"], Rod(5)),
LocationData("Pallet Town", "Player's PC", "Potion", rom_addresses['PC_Item'], EventFlag(1),),
LocationData("Celadon City", "Mansion Lady", "Tea", rom_addresses["Event_Mansion_Lady"], EventFlag(2)),
LocationData("Celadon City", "Mansion Lady", "Tea", rom_addresses["Event_Mansion_Lady"], EventFlag(2), inclusion=tea),
LocationData("Pallet Town", "Rival's Sister", "Town Map", rom_addresses["Event_Rivals_Sister"], EventFlag(24)),
LocationData("Pallet Town", "Oak's Post-Route-22-Rival Gift", "Poke Ball", rom_addresses["Event_Oaks_Gift"], EventFlag(36)),
LocationData("Route 1", "Free Sample Man", "Potion", rom_addresses["Event_Free_Sample"], EventFlag(960)),
@ -77,7 +105,7 @@ location_data = [
LocationData("S.S. Anne 2F", "Captain", "HM01 Cut", rom_addresses["Event_SS_Anne_Captain"], EventFlag(1504)),
LocationData("Route 11 East", "Oak's Aide", "Item Finder", rom_addresses["Event_Rt11_Oaks_Aide"],
EventFlag(1151)),
LocationData("Celadon City", "Stranded Man", "TM41 Soft Boiled", rom_addresses["Event_Stranded_Man"],
LocationData("Celadon City", "Stranded Man", "TM41 Soft-Boiled", rom_addresses["Event_Stranded_Man"],
EventFlag(384)),
LocationData("Celadon City", "Thirsty Girl Gets Water", "TM13 Ice Beam",
rom_addresses["Event_Thirsty_Girl_Water"], EventFlag(396)),
@ -91,7 +119,7 @@ location_data = [
LocationData("Celadon Gym", "Erika 2", "TM21 Mega Drain", rom_addresses["Event_Celadon_Gym"], EventFlag(424)),
LocationData("Silph Co 11F", "Silph Co President", "Master Ball", rom_addresses["Event_Silph_Co_President"],
EventFlag(1933)),
LocationData("Silph Co 2F", "Woman", "TM36 Self Destruct", rom_addresses["Event_Scared_Woman"],
LocationData("Silph Co 2F", "Woman", "TM36 Self-Destruct", rom_addresses["Event_Scared_Woman"],
EventFlag(1791)),
LocationData("Route 16 North", "House Woman", "HM02 Fly", rom_addresses["Event_Rt16_House_Woman"], EventFlag(1230)),
LocationData("Route 15", "Oak's Aide", "Exp. All", rom_addresses["Event_Rt_15_Oaks_Aide"], EventFlag(1200)),
@ -299,13 +327,13 @@ location_data = [
LocationData("Victory Road 1F", "Left Item", "Rare Candy", rom_addresses["Missable_Victory_Road_1F_Item_2"],
Missable(213)),
LocationData("Rock Tunnel B1F", "Southwest Item", "Hideout Key", rom_addresses["Missable_Rock_Tunnel_B1F_Item_1"],
Missable(231)),
Missable(231), inclusion=extra_key_items),
LocationData("Rock Tunnel B1F", "West Item", "Mansion Key", rom_addresses["Missable_Rock_Tunnel_B1F_Item_2"],
Missable(232)),
Missable(232), inclusion=extra_key_items),
LocationData("Rock Tunnel B1F", "Northwest Item", "Plant Key", rom_addresses["Missable_Rock_Tunnel_B1F_Item_3"],
Missable(233)),
Missable(233), inclusion=extra_key_items),
LocationData("Rock Tunnel B1F", "North Item", "Safari Pass", rom_addresses["Missable_Rock_Tunnel_B1F_Item_4"],
Missable(234)),
Missable(234), inclusion=extra_key_items),
LocationData("Pewter Gym", "Brock 1", "Boulder Badge", rom_addresses['Badge_Pewter_Gym'], EventFlag(0x8A0)),
LocationData("Cerulean Gym", "Misty 1", "Cascade Badge", rom_addresses['Badge_Cerulean_Gym'], EventFlag(0x8A1)),
@ -316,59 +344,372 @@ location_data = [
LocationData("Cinnabar Gym", "Blaine 1", "Volcano Badge", rom_addresses['Badge_Cinnabar_Gym'], EventFlag(0x8A6)),
LocationData("Viridian Gym", "Giovanni 1", "Earth Badge", rom_addresses['Badge_Viridian_Gym'], EventFlag(0x8A7)),
LocationData("Viridian Forest", "Hidden Item Northwest by Trainer", "Potion", rom_addresses['Hidden_Item_Viridian_Forest_1'], Hidden(0)),
LocationData("Viridian Forest", "Hidden Item Entrance Tree", "Antidote", rom_addresses['Hidden_Item_Viridian_Forest_2'], Hidden(1)),
LocationData("Mt Moon B2F", "Hidden Item Dead End Before Fossils", "Moon Stone", rom_addresses['Hidden_Item_MtMoonB2F_1'], Hidden(2)),
LocationData("Route 25", "Hidden Item Fence Outside Bill's House", "Ether", rom_addresses['Hidden_Item_Route_25_1'], Hidden(3)),
LocationData("Route 9", "Hidden Item Bush By Grass", "Ether", rom_addresses['Hidden_Item_Route_9'], Hidden(4)),
LocationData("S.S. Anne 1F", "Hidden Item Kitchen Trash", "Great Ball", rom_addresses['Hidden_Item_SS_Anne_Kitchen'], Hidden(5)),
LocationData("S.S. Anne B1F", "Hidden Item Under Pillow", "Hyper Potion", rom_addresses['Hidden_Item_SS_Anne_B1F'], Hidden(6)),
LocationData("Route 10 North", "Hidden Item Behind Rock Tunnel Entrance Cuttable Tree", "Super Potion", rom_addresses['Hidden_Item_Route_10_1'], Hidden(7)),
LocationData("Route 10 South", "Hidden Item Bush", "Max Ether", rom_addresses['Hidden_Item_Route_10_2'], Hidden(8)),
LocationData("Rocket Hideout B1F", "Hidden Item Pot Plant", "PP Up", rom_addresses['Hidden_Item_Rocket_Hideout_B1F'], Hidden(9)),
LocationData("Rocket Hideout B3F", "Hidden Item Near East Item", "Nugget", rom_addresses['Hidden_Item_Rocket_Hideout_B3F'], Hidden(10)),
LocationData("Rocket Hideout B4F", "Hidden Item Behind Giovanni", "Super Potion", rom_addresses['Hidden_Item_Rocket_Hideout_B4F'], Hidden(11)),
LocationData("Pokemon Tower 5F", "Hidden Item Near West Staircase", "Elixir", rom_addresses['Hidden_Item_Pokemon_Tower_5F'], Hidden(12)),
LocationData("Route 13", "Hidden Item Dead End Bush", "PP Up", rom_addresses['Hidden_Item_Route_13_1'], Hidden(13)),
LocationData("Route 13", "Hidden Item Dead End By Water Corner", "Calcium", rom_addresses['Hidden_Item_Route_13_2'], Hidden(14)),
LocationData("Pokemon Mansion B1F", "Hidden Item Secret Key Room Corner", "Rare Candy", rom_addresses['Hidden_Item_Pokemon_Mansion_B1F'], Hidden(15)),
LocationData("Safari Zone West", "Hidden Item Secret House Statue", "Revive", rom_addresses['Hidden_Item_Safari_Zone_West'], Hidden(17)),
LocationData("Silph Co 5F", "Hidden Item Pot Plant", "Elixir", rom_addresses['Hidden_Item_Silph_Co_5F'], Hidden(18)),
LocationData("Silph Co 9F", "Hidden Item Nurse Bed (Card Key)", "Max Potion", rom_addresses['Hidden_Item_Silph_Co_9F'], Hidden(19)),
LocationData("Copycat's House", "Hidden Item Desk", "Nugget", rom_addresses['Hidden_Item_Copycats_House'], Hidden(20)),
LocationData("Cerulean Cave 1F", "Hidden Item Center Rocks", "Rare Candy", rom_addresses['Hidden_Item_Cerulean_Cave_1F'], Hidden(21)),
LocationData("Cerulean Cave B1F", "Hidden Item Northeast Rocks", "Ultra Ball", rom_addresses['Hidden_Item_Cerulean_Cave_B1F'], Hidden(22)),
LocationData("Power Plant", "Hidden Item Central Dead End", "Max Elixir", rom_addresses['Hidden_Item_Power_Plant_1'], Hidden(23)),
LocationData("Power Plant", "Hidden Item Before Zapdos", "PP Up", rom_addresses['Hidden_Item_Power_Plant_2'], Hidden(24)),
LocationData("Seafoam Islands B2F", "Hidden Item Rock", "Nugget", rom_addresses['Hidden_Item_Seafoam_Islands_B2F'], Hidden(25)),
LocationData("Seafoam Islands B4F", "Hidden Item Corner Island", "Ultra Ball", rom_addresses['Hidden_Item_Seafoam_Islands_B4F'], Hidden(26)),
LocationData("Pokemon Mansion 1F", "Hidden Item Block Near Entrance Carpet", "Moon Stone", rom_addresses['Hidden_Item_Pokemon_Mansion_1F'], Hidden(27)),
LocationData("Pokemon Mansion 3F", "Hidden Item Behind Burglar", "Max Revive", rom_addresses['Hidden_Item_Pokemon_Mansion_3F'], Hidden(28)),
LocationData("Route 23", "Hidden Item Rocks Before Final Guard", "Full Restore", rom_addresses['Hidden_Item_Route_23_1'], Hidden(29)),
LocationData("Route 23", "Hidden Item East Bush After Water", "Ultra Ball", rom_addresses['Hidden_Item_Route_23_2'], Hidden(30)),
LocationData("Route 23", "Hidden Item On Island", "Max Ether", rom_addresses['Hidden_Item_Route_23_3'], Hidden(31)),
LocationData("Victory Road 2F", "Hidden Item Rock Before Moltres", "Ultra Ball", rom_addresses['Hidden_Item_Victory_Road_2F_1'], Hidden(32)),
LocationData("Victory Road 2F", "Hidden Item Rock In Final Room", "Full Restore", rom_addresses['Hidden_Item_Victory_Road_2F_2'], Hidden(33)),
LocationData("Viridian Forest", "Hidden Item Northwest by Trainer", "Potion", rom_addresses['Hidden_Item_Viridian_Forest_1'], Hidden(0), inclusion=hidden_items),
LocationData("Viridian Forest", "Hidden Item Entrance Tree", "Antidote", rom_addresses['Hidden_Item_Viridian_Forest_2'], Hidden(1), inclusion=hidden_items),
LocationData("Mt Moon B2F", "Hidden Item Dead End Before Fossils", "Moon Stone", rom_addresses['Hidden_Item_MtMoonB2F_1'], Hidden(2), inclusion=hidden_items),
LocationData("Route 25", "Hidden Item Fence Outside Bill's House", "Ether", rom_addresses['Hidden_Item_Route_25_1'], Hidden(3), inclusion=hidden_items),
LocationData("Route 9", "Hidden Item Bush By Grass", "Ether", rom_addresses['Hidden_Item_Route_9'], Hidden(4), inclusion=hidden_items),
LocationData("S.S. Anne 1F", "Hidden Item Kitchen Trash", "Great Ball", rom_addresses['Hidden_Item_SS_Anne_Kitchen'], Hidden(5), inclusion=hidden_items),
LocationData("S.S. Anne B1F", "Hidden Item Under Pillow", "Hyper Potion", rom_addresses['Hidden_Item_SS_Anne_B1F'], Hidden(6), inclusion=hidden_items),
LocationData("Route 10 North", "Hidden Item Behind Rock Tunnel Entrance Cuttable Tree", "Super Potion", rom_addresses['Hidden_Item_Route_10_1'], Hidden(7), inclusion=hidden_items),
LocationData("Route 10 South", "Hidden Item Bush", "Max Ether", rom_addresses['Hidden_Item_Route_10_2'], Hidden(8), inclusion=hidden_items),
LocationData("Rocket Hideout B1F", "Hidden Item Pot Plant", "PP Up", rom_addresses['Hidden_Item_Rocket_Hideout_B1F'], Hidden(9), inclusion=hidden_items),
LocationData("Rocket Hideout B3F", "Hidden Item Near East Item", "Nugget", rom_addresses['Hidden_Item_Rocket_Hideout_B3F'], Hidden(10), inclusion=hidden_items),
LocationData("Rocket Hideout B4F", "Hidden Item Behind Giovanni", "Super Potion", rom_addresses['Hidden_Item_Rocket_Hideout_B4F'], Hidden(11), inclusion=hidden_items),
LocationData("Pokemon Tower 5F", "Hidden Item Near West Staircase", "Elixir", rom_addresses['Hidden_Item_Pokemon_Tower_5F'], Hidden(12), inclusion=hidden_items),
LocationData("Route 13", "Hidden Item Dead End Bush", "PP Up", rom_addresses['Hidden_Item_Route_13_1'], Hidden(13), inclusion=hidden_items),
LocationData("Route 13", "Hidden Item Dead End By Water Corner", "Calcium", rom_addresses['Hidden_Item_Route_13_2'], Hidden(14), inclusion=hidden_items),
LocationData("Pokemon Mansion B1F", "Hidden Item Secret Key Room Corner", "Rare Candy", rom_addresses['Hidden_Item_Pokemon_Mansion_B1F'], Hidden(15), inclusion=hidden_items),
LocationData("Safari Zone West", "Hidden Item Secret House Statue", "Revive", rom_addresses['Hidden_Item_Safari_Zone_West'], Hidden(17), inclusion=hidden_items),
LocationData("Silph Co 5F", "Hidden Item Pot Plant", "Elixir", rom_addresses['Hidden_Item_Silph_Co_5F'], Hidden(18), inclusion=hidden_items),
LocationData("Silph Co 9F", "Hidden Item Nurse Bed (Card Key)", "Max Potion", rom_addresses['Hidden_Item_Silph_Co_9F'], Hidden(19), inclusion=hidden_items),
LocationData("Copycat's House", "Hidden Item Desk", "Nugget", rom_addresses['Hidden_Item_Copycats_House'], Hidden(20), inclusion=hidden_items),
LocationData("Cerulean Cave 1F", "Hidden Item Center Rocks", "Rare Candy", rom_addresses['Hidden_Item_Cerulean_Cave_1F'], Hidden(21), inclusion=hidden_items),
LocationData("Cerulean Cave B1F", "Hidden Item Northeast Rocks", "Ultra Ball", rom_addresses['Hidden_Item_Cerulean_Cave_B1F'], Hidden(22), inclusion=hidden_items),
LocationData("Power Plant", "Hidden Item Central Dead End", "Max Elixir", rom_addresses['Hidden_Item_Power_Plant_1'], Hidden(23), inclusion=hidden_items),
LocationData("Power Plant", "Hidden Item Before Zapdos", "PP Up", rom_addresses['Hidden_Item_Power_Plant_2'], Hidden(24), inclusion=hidden_items),
LocationData("Seafoam Islands B2F", "Hidden Item Rock", "Nugget", rom_addresses['Hidden_Item_Seafoam_Islands_B2F'], Hidden(25), inclusion=hidden_items),
LocationData("Seafoam Islands B4F", "Hidden Item Corner Island", "Ultra Ball", rom_addresses['Hidden_Item_Seafoam_Islands_B4F'], Hidden(26), inclusion=hidden_items),
LocationData("Pokemon Mansion 1F", "Hidden Item Block Near Entrance Carpet", "Moon Stone", rom_addresses['Hidden_Item_Pokemon_Mansion_1F'], Hidden(27), inclusion=hidden_items),
LocationData("Pokemon Mansion 3F", "Hidden Item Behind Burglar", "Max Revive", rom_addresses['Hidden_Item_Pokemon_Mansion_3F'], Hidden(28), inclusion=hidden_items),
LocationData("Route 23", "Hidden Item Rocks Before Final Guard", "Full Restore", rom_addresses['Hidden_Item_Route_23_1'], Hidden(29), inclusion=hidden_items),
LocationData("Route 23", "Hidden Item East Bush After Water", "Ultra Ball", rom_addresses['Hidden_Item_Route_23_2'], Hidden(30), inclusion=hidden_items),
LocationData("Route 23", "Hidden Item On Island", "Max Ether", rom_addresses['Hidden_Item_Route_23_3'], Hidden(31), inclusion=hidden_items),
LocationData("Victory Road 2F", "Hidden Item Rock Before Moltres", "Ultra Ball", rom_addresses['Hidden_Item_Victory_Road_2F_1'], Hidden(32), inclusion=hidden_items),
LocationData("Victory Road 2F", "Hidden Item Rock In Final Room", "Full Restore", rom_addresses['Hidden_Item_Victory_Road_2F_2'], Hidden(33), inclusion=hidden_items),
LocationData("Viridian City", "Hidden Item Cuttable Tree", "Potion", rom_addresses['Hidden_Item_Viridian_City'], Hidden(35)),
LocationData("Route 11", "Hidden Item Isolated Bush Near Gate", "Potion", rom_addresses['Hidden_Item_Route_11'], Hidden(36)),
LocationData("Route 12 West", "Hidden Item Bush Near Gate", "Hyper Potion", rom_addresses['Hidden_Item_Route_12'], Hidden(37)),
LocationData("Route 17", "Hidden Item In Grass", "Rare Candy", rom_addresses['Hidden_Item_Route_17_1'], Hidden(38)),
LocationData("Route 17", "Hidden Item Near Northernmost Sign", "Full Restore", rom_addresses['Hidden_Item_Route_17_2'], Hidden(39)),
LocationData("Route 17", "Hidden Item East Center", "PP Up", rom_addresses['Hidden_Item_Route_17_3'], Hidden(40)),
LocationData("Route 17", "Hidden Item West Center", "Max Revive", rom_addresses['Hidden_Item_Route_17_4'], Hidden(41)),
LocationData("Route 17", "Hidden Item Before Final Bridge", "Max Elixir", rom_addresses['Hidden_Item_Route_17_5'], Hidden(42)),
LocationData("Underground Tunnel North-South", "Hidden Item Near Northern Stairs", "Full Restore", rom_addresses['Hidden_Item_Underground_Path_NS_1'], Hidden(43)),
LocationData("Underground Tunnel North-South", "Hidden Item Near Southern Stairs", "X Special", rom_addresses['Hidden_Item_Underground_Path_NS_2'], Hidden(44)),
LocationData("Underground Tunnel West-East", "Hidden Item West", "Nugget", rom_addresses['Hidden_Item_Underground_Path_WE_1'], Hidden(45)),
LocationData("Underground Tunnel West-East", "Hidden Item East", "Elixir", rom_addresses['Hidden_Item_Underground_Path_WE_2'], Hidden(46)),
LocationData("Celadon City", "Hidden Item Dead End Near Cuttable Tree", "PP Up", rom_addresses['Hidden_Item_Celadon_City'], Hidden(47)),
LocationData("Route 25", "Hidden Item Northeast Of Grass", "Elixir", rom_addresses['Hidden_Item_Route_25_2'], Hidden(48)),
LocationData("Mt Moon B2F", "Hidden Item Lone Rock", "Ether", rom_addresses['Hidden_Item_MtMoonB2F_2'], Hidden(49)),
LocationData("Seafoam Islands B3F", "Hidden Item Rock", "Max Elixir", rom_addresses['Hidden_Item_Seafoam_Islands_B3F'], Hidden(50)),
LocationData("Vermilion City", "Hidden Item In Water Near Fan Club", "Max Ether", rom_addresses['Hidden_Item_Vermilion_City'], Hidden(51)),
LocationData("Cerulean City", "Hidden Item Gym Badge Guy's Backyard", "Rare Candy", rom_addresses['Hidden_Item_Cerulean_City'], Hidden(52)),
LocationData("Route 4", "Hidden Item Plateau East Of Mt Moon", "Great Ball", rom_addresses['Hidden_Item_Route_4'], Hidden(53)),
LocationData("Viridian City", "Hidden Item Cuttable Tree", "Potion", rom_addresses['Hidden_Item_Viridian_City'], Hidden(35), inclusion=hidden_items),
LocationData("Route 11", "Hidden Item Isolated Bush Near Gate", "Potion", rom_addresses['Hidden_Item_Route_11'], Hidden(36), inclusion=hidden_items),
LocationData("Route 12 West", "Hidden Item Bush Near Gate", "Hyper Potion", rom_addresses['Hidden_Item_Route_12'], Hidden(37), inclusion=hidden_items),
LocationData("Route 17", "Hidden Item In Grass", "Rare Candy", rom_addresses['Hidden_Item_Route_17_1'], Hidden(38), inclusion=hidden_items),
LocationData("Route 17", "Hidden Item Near Northernmost Sign", "Full Restore", rom_addresses['Hidden_Item_Route_17_2'], Hidden(39), inclusion=hidden_items),
LocationData("Route 17", "Hidden Item East Center", "PP Up", rom_addresses['Hidden_Item_Route_17_3'], Hidden(40), inclusion=hidden_items),
LocationData("Route 17", "Hidden Item West Center", "Max Revive", rom_addresses['Hidden_Item_Route_17_4'], Hidden(41), inclusion=hidden_items),
LocationData("Route 17", "Hidden Item Before Final Bridge", "Max Elixir", rom_addresses['Hidden_Item_Route_17_5'], Hidden(42), inclusion=hidden_items),
LocationData("Underground Tunnel North-South", "Hidden Item Near Northern Stairs", "Full Restore", rom_addresses['Hidden_Item_Underground_Path_NS_1'], Hidden(43), inclusion=hidden_items),
LocationData("Underground Tunnel North-South", "Hidden Item Near Southern Stairs", "X Special", rom_addresses['Hidden_Item_Underground_Path_NS_2'], Hidden(44), inclusion=hidden_items),
LocationData("Underground Tunnel West-East", "Hidden Item West", "Nugget", rom_addresses['Hidden_Item_Underground_Path_WE_1'], Hidden(45), inclusion=hidden_items),
LocationData("Underground Tunnel West-East", "Hidden Item East", "Elixir", rom_addresses['Hidden_Item_Underground_Path_WE_2'], Hidden(46), inclusion=hidden_items),
LocationData("Celadon City", "Hidden Item Dead End Near Cuttable Tree", "PP Up", rom_addresses['Hidden_Item_Celadon_City'], Hidden(47), inclusion=hidden_items),
LocationData("Route 25", "Hidden Item Northeast Of Grass", "Elixir", rom_addresses['Hidden_Item_Route_25_2'], Hidden(48), inclusion=hidden_items),
LocationData("Mt Moon B2F", "Hidden Item Lone Rock", "Ether", rom_addresses['Hidden_Item_MtMoonB2F_2'], Hidden(49), inclusion=hidden_items),
LocationData("Seafoam Islands B3F", "Hidden Item Rock", "Max Elixir", rom_addresses['Hidden_Item_Seafoam_Islands_B3F'], Hidden(50), inclusion=hidden_items),
LocationData("Vermilion City", "Hidden Item In Water Near Fan Club", "Max Ether", rom_addresses['Hidden_Item_Vermilion_City'], Hidden(51), inclusion=hidden_items),
LocationData("Cerulean City", "Hidden Item Gym Badge Guy's Backyard", "Rare Candy", rom_addresses['Hidden_Item_Cerulean_City'], Hidden(52), inclusion=hidden_items),
LocationData("Route 4", "Hidden Item Plateau East Of Mt Moon", "Great Ball", rom_addresses['Hidden_Item_Route_4'], Hidden(53), inclusion=hidden_items),
LocationData("Pallet Town", "Oak's Parcel Reward", "Pokedex", rom_addresses["Event_Pokedex"], EventFlag(0x38), inclusion=pokedex),
LocationData("Pokemon Mansion 1F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_MANSION_1_TRAINER_0_ITEM"], EventFlag(376), inclusion=trainersanity),
LocationData("Pokemon Mansion 2F", "Burglar", None, rom_addresses["Trainersanity_EVENT_BEAT_MANSION_2_TRAINER_0_ITEM"], EventFlag(43), inclusion=trainersanity),
LocationData("Pokemon Mansion 3F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_MANSION_3_TRAINER_1_ITEM"], EventFlag(31), inclusion=trainersanity),
LocationData("Pokemon Mansion 3F", "Burglar", None, rom_addresses["Trainersanity_EVENT_BEAT_MANSION_3_TRAINER_0_ITEM"], EventFlag(42), inclusion=trainersanity),
LocationData("Pokemon Mansion B1F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_MANSION_4_TRAINER_1_ITEM"], EventFlag(29), inclusion=trainersanity),
LocationData("Pokemon Mansion B1F", "Burglar", None, rom_addresses["Trainersanity_EVENT_BEAT_MANSION_4_TRAINER_0_ITEM"], EventFlag(30), inclusion=trainersanity),
LocationData("Silph Co 11F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_11F_TRAINER_1_ITEM"], EventFlag(45), inclusion=trainersanity),
LocationData("Silph Co 11F", "Rocket 2 (Card Key)", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_11F_TRAINER_0_ITEM"], EventFlag(46), inclusion=trainersanity),
LocationData("Silph Co 10F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_10F_TRAINER_1_ITEM"], EventFlag(47), inclusion=trainersanity),
LocationData("Silph Co 10F", "Rocket", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_10F_TRAINER_0_ITEM"], EventFlag(48), inclusion=trainersanity),
LocationData("Silph Co 9F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_9F_TRAINER_2_ITEM"], EventFlag(49), inclusion=trainersanity),
LocationData("Silph Co 9F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_9F_TRAINER_1_ITEM"], EventFlag(50), inclusion=trainersanity),
LocationData("Silph Co 9F", "Rocket 2 (Card Key)", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_9F_TRAINER_0_ITEM"], EventFlag(51), inclusion=trainersanity),
LocationData("Silph Co 8F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_8F_TRAINER_0_ITEM"], EventFlag(54), inclusion=trainersanity),
LocationData("Silph Co 8F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_8F_TRAINER_2_ITEM"], EventFlag(52), inclusion=trainersanity),
LocationData("Silph Co 8F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_8F_TRAINER_1_ITEM"], EventFlag(53), inclusion=trainersanity),
LocationData("Silph Co 7F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_7F_TRAINER_2_ITEM"], EventFlag(58), inclusion=trainersanity),
LocationData("Silph Co 7F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_7F_TRAINER_0_ITEM"], EventFlag(60), inclusion=trainersanity),
LocationData("Silph Co 7F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_7F_TRAINER_1_ITEM"], EventFlag(59), inclusion=trainersanity),
LocationData("Silph Co 7F", "Rocket 3", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_7F_TRAINER_3_ITEM"], EventFlag(55), inclusion=trainersanity),
LocationData("Silph Co 6F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_6F_TRAINER_0_ITEM"], EventFlag(64), inclusion=trainersanity),
LocationData("Silph Co 6F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_6F_TRAINER_1_ITEM"], EventFlag(63), inclusion=trainersanity),
LocationData("Silph Co 6F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_6F_TRAINER_2_ITEM"], EventFlag(62), inclusion=trainersanity),
LocationData("Silph Co 5F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_5F_TRAINER_3_ITEM"], EventFlag(65), inclusion=trainersanity),
LocationData("Silph Co 5F", "Juggler", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_5F_TRAINER_2_ITEM"], EventFlag(66), inclusion=trainersanity),
LocationData("Silph Co 5F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_5F_TRAINER_1_ITEM"], EventFlag(67), inclusion=trainersanity),
LocationData("Silph Co 5F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_5F_TRAINER_0_ITEM"], EventFlag(68), inclusion=trainersanity),
LocationData("Silph Co 4F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_4F_TRAINER_2_ITEM"], EventFlag(69), inclusion=trainersanity),
LocationData("Silph Co 4F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_4F_TRAINER_0_ITEM"], EventFlag(71), inclusion=trainersanity),
LocationData("Silph Co 4F", "Scientist", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_4F_TRAINER_1_ITEM"], EventFlag(70), inclusion=trainersanity),
LocationData("Silph Co 3F", "Scientist (Card Key)", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_3F_TRAINER_1_ITEM"], EventFlag(72), inclusion=trainersanity),
LocationData("Silph Co 3F", "Rocket", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_3F_TRAINER_0_ITEM"], EventFlag(73), inclusion=trainersanity),
LocationData("Silph Co 2F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_2F_TRAINER_3_ITEM"], EventFlag(74), inclusion=trainersanity),
LocationData("Silph Co 2F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_2F_TRAINER_2_ITEM"], EventFlag(75), inclusion=trainersanity),
LocationData("Silph Co 2F", "Scientist 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_2F_TRAINER_1_ITEM"], EventFlag(76), inclusion=trainersanity),
LocationData("Silph Co 2F", "Scientist 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SILPH_CO_2F_TRAINER_0_ITEM"], EventFlag(77), inclusion=trainersanity),
LocationData("Rocket Hideout B1F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_1_TRAINER_0_ITEM"], EventFlag(99), inclusion=trainersanity),
LocationData("Rocket Hideout B1F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_1_TRAINER_1_ITEM"], EventFlag(98), inclusion=trainersanity),
LocationData("Rocket Hideout B1F", "Rocket 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_1_TRAINER_3_ITEM"], EventFlag(96), inclusion=trainersanity),
LocationData("Rocket Hideout B1F", "Rocket 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_1_TRAINER_2_ITEM"], EventFlag(97), inclusion=trainersanity),
LocationData("Rocket Hideout B1F", "Rocket 5 (Lift Key)", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_1_TRAINER_4_ITEM"], EventFlag(95), inclusion=trainersanity),
LocationData("Rocket Hideout B2F", "Rocket", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_2_TRAINER_0_ITEM"], EventFlag(94), inclusion=trainersanity),
LocationData("Rocket Hideout B3F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_3_TRAINER_1_ITEM"], EventFlag(92), inclusion=trainersanity),
LocationData("Rocket Hideout B3F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_3_TRAINER_0_ITEM"], EventFlag(93), inclusion=trainersanity),
LocationData("Rocket Hideout B4F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_4_TRAINER_2_ITEM"], EventFlag(79), inclusion=trainersanity),
LocationData("Rocket Hideout B4F", "Rocket 2 (Lift Key)", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_4_TRAINER_0_ITEM"], EventFlag(91), inclusion=trainersanity),
LocationData("Rocket Hideout B4F", "Rocket 3 (Lift Key)", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCKET_HIDEOUT_4_TRAINER_1_ITEM"], EventFlag(90), inclusion=trainersanity),
LocationData("S.S. Anne 1F", "Gentleman 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_8_TRAINER_1_ITEM"], EventFlag(121), inclusion=trainersanity),
LocationData("S.S. Anne 1F", "Gentleman 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_8_TRAINER_0_ITEM"], EventFlag(122), inclusion=trainersanity),
LocationData("S.S. Anne 1F", "Lass", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_8_TRAINER_3_ITEM"], EventFlag(117), inclusion=trainersanity),
LocationData("S.S. Anne 1F", "Youngster", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_8_TRAINER_2_ITEM"], EventFlag(120), inclusion=trainersanity),
LocationData("S.S. Anne 2F", "Fisherman", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_9_TRAINER_1_ITEM"], EventFlag(115), inclusion=trainersanity),
LocationData("S.S. Anne 2F", "Gentleman 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_9_TRAINER_0_ITEM"], EventFlag(116), inclusion=trainersanity),
LocationData("S.S. Anne 2F", "Gentleman 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_9_TRAINER_2_ITEM"], EventFlag(113), inclusion=trainersanity),
LocationData("S.S. Anne 2F", "Lass", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_9_TRAINER_3_ITEM"], EventFlag(112), inclusion=trainersanity),
LocationData("S.S. Anne 3F", "Sailor 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_5_TRAINER_1_ITEM"], EventFlag(123), inclusion=trainersanity),
LocationData("S.S. Anne 3F", "Sailor 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_5_TRAINER_0_ITEM"], EventFlag(124), inclusion=trainersanity),
LocationData("S.S. Anne B1F", "Sailor 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_10_TRAINER_1_ITEM"], EventFlag(110), inclusion=trainersanity),
LocationData("S.S. Anne B1F", "Sailor 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_10_TRAINER_0_ITEM"], EventFlag(111), inclusion=trainersanity),
LocationData("S.S. Anne B1F", "Sailor 3", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_10_TRAINER_3_ITEM"], EventFlag(108), inclusion=trainersanity),
LocationData("S.S. Anne B1F", "Sailor 4", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_10_TRAINER_2_ITEM"], EventFlag(109), inclusion=trainersanity),
LocationData("S.S. Anne B1F", "Fisherman", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_10_TRAINER_5_ITEM"], EventFlag(106), inclusion=trainersanity),
LocationData("S.S. Anne B1F", "Sailor 5", None, rom_addresses["Trainersanity_EVENT_BEAT_SS_ANNE_10_TRAINER_4_ITEM"], EventFlag(107), inclusion=trainersanity),
LocationData("Mt Moon 1F", "Bug Catcher 1", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_1_TRAINER_5_ITEM"], EventFlag(131), inclusion=trainersanity),
LocationData("Mt Moon 1F", "Lass 1", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_1_TRAINER_4_ITEM"], EventFlag(132), inclusion=trainersanity),
LocationData("Mt Moon 1F", "Super Nerd", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_1_TRAINER_3_ITEM"], EventFlag(133), inclusion=trainersanity),
LocationData("Mt Moon 1F", "Bug Catcher 2", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_1_TRAINER_6_ITEM"], EventFlag(130), inclusion=trainersanity),
LocationData("Mt Moon 1F", "Lass 2", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_1_TRAINER_2_ITEM"], EventFlag(134), inclusion=trainersanity),
LocationData("Mt Moon 1F", "Youngster", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_1_TRAINER_1_ITEM"], EventFlag(135), inclusion=trainersanity),
LocationData("Mt Moon 1F", "Hiker", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_1_TRAINER_0_ITEM"], EventFlag(136), inclusion=trainersanity),
LocationData("Mt Moon B2F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_3_TRAINER_1_ITEM"], EventFlag(127), inclusion=trainersanity),
LocationData("Mt Moon B2F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_3_TRAINER_2_ITEM"], EventFlag(126), inclusion=trainersanity),
LocationData("Mt Moon B2F", "Rocket 3", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_3_TRAINER_3_ITEM"], EventFlag(125), inclusion=trainersanity),
LocationData("Mt Moon B2F", "Rocket 4", None, rom_addresses["Trainersanity_EVENT_BEAT_MT_MOON_3_TRAINER_0_ITEM"], EventFlag(128), inclusion=trainersanity),
LocationData("Viridian Forest", "Bug Catcher 1", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_FOREST_TRAINER_0_ITEM"], EventFlag(139), inclusion=trainersanity),
LocationData("Viridian Forest", "Bug Catcher 2", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_FOREST_TRAINER_1_ITEM"], EventFlag(138), inclusion=trainersanity),
LocationData("Viridian Forest", "Bug Catcher 3", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_FOREST_TRAINER_2_ITEM"], EventFlag(137), inclusion=trainersanity),
LocationData("Route 25", "Hiker 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_6_ITEM"], EventFlag(142), inclusion=trainersanity),
LocationData("Route 25", "Youngster 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_0_ITEM"], EventFlag(148), inclusion=trainersanity),
LocationData("Route 25", "Hiker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_8_ITEM"], EventFlag(140), inclusion=trainersanity),
LocationData("Route 25", "Youngster 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_1_ITEM"], EventFlag(147), inclusion=trainersanity),
LocationData("Route 25", "Lass 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_3_ITEM"], EventFlag(145), inclusion=trainersanity),
LocationData("Route 25", "Hiker 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_7_ITEM"], EventFlag(141), inclusion=trainersanity),
LocationData("Route 25", "Jr. Trainer M", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_2_ITEM"], EventFlag(146), inclusion=trainersanity),
LocationData("Route 25", "Youngster 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_4_ITEM"], EventFlag(144), inclusion=trainersanity),
LocationData("Route 25", "Lass 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_25_TRAINER_5_ITEM"], EventFlag(143), inclusion=trainersanity),
LocationData("Route 24", "Bug Catcher", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_24_TRAINER_5_ITEM"], EventFlag(149), inclusion=trainersanity),
LocationData("Route 24", "Lass 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_24_TRAINER_4_ITEM"], EventFlag(150), inclusion=trainersanity),
LocationData("Route 24", "Youngster", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_24_TRAINER_3_ITEM"], EventFlag(151), inclusion=trainersanity),
LocationData("Route 24", "Lass 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_24_TRAINER_2_ITEM"], EventFlag(153), inclusion=trainersanity),
LocationData("Route 24", "Jr. Trainer M 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_24_TRAINER_1_ITEM"], EventFlag(154), inclusion=trainersanity),
LocationData("Route 24", "Jr. Trainer M 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_24_TRAINER_0_ITEM"], EventFlag(155), inclusion=trainersanity),
LocationData("Route 21", "Fisherman 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_0_ITEM"], EventFlag(174), inclusion=trainersanity),
LocationData("Route 21", "Fisherman 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_1_ITEM"], EventFlag(173), inclusion=trainersanity),
LocationData("Route 21", "Cue Ball", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_3_ITEM"], EventFlag(171), inclusion=trainersanity),
LocationData("Route 21", "Swimmer 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_2_ITEM"], EventFlag(172), inclusion=trainersanity),
LocationData("Route 21", "Fisherman 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_7_ITEM"], EventFlag(166), inclusion=trainersanity),
LocationData("Route 21", "Fisherman 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_8_ITEM"], EventFlag(165), inclusion=trainersanity),
LocationData("Route 21", "Swimmer 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_4_ITEM"], EventFlag(170), inclusion=trainersanity),
LocationData("Route 21", "Swimmer 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_6_ITEM"], EventFlag(168), inclusion=trainersanity),
LocationData("Route 21", "Swimmer 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_21_TRAINER_5_ITEM"], EventFlag(169), inclusion=trainersanity),
LocationData("Route 20 West", "Beauty 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_9_ITEM"], EventFlag(175), inclusion=trainersanity),
LocationData("Route 20 West", "Jr. Trainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_8_ITEM"], EventFlag(176), inclusion=trainersanity),
LocationData("Route 20 West", "Beauty 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_7_ITEM"], EventFlag(177), inclusion=trainersanity),
LocationData("Route 20 West", "Cooltrainer M", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_6_ITEM"], EventFlag(178), inclusion=trainersanity),
LocationData("Route 20 West", "Swimmer 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_4_ITEM"], EventFlag(180), inclusion=trainersanity),
LocationData("Route 20 West", "Jr. Trainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_3_ITEM"], EventFlag(181), inclusion=trainersanity),
LocationData("Route 20 East", "Beauty 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_2_ITEM"], EventFlag(182), inclusion=trainersanity),
LocationData("Route 20 East", "Beauty 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_1_ITEM"], EventFlag(183), inclusion=trainersanity),
LocationData("Route 20 East", "Swimmer 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_5_ITEM"], EventFlag(179), inclusion=trainersanity),
LocationData("Route 20 East", "Swimmer 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_20_TRAINER_0_ITEM"], EventFlag(184), inclusion=trainersanity),
LocationData("Route 19", "Swimmer 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_0_ITEM"], EventFlag(199), inclusion=trainersanity),
LocationData("Route 19", "Swimmer 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_1_ITEM"], EventFlag(198), inclusion=trainersanity),
LocationData("Route 19", "Swimmer 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_5_ITEM"], EventFlag(194), inclusion=trainersanity),
LocationData("Route 19", "Swimmer 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_2_ITEM"], EventFlag(197), inclusion=trainersanity),
LocationData("Route 19", "Swimmer 5", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_3_ITEM"], EventFlag(196), inclusion=trainersanity),
LocationData("Route 19", "Swimmer 6", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_4_ITEM"], EventFlag(195), inclusion=trainersanity),
LocationData("Route 19", "Swimmer 7", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_8_ITEM"], EventFlag(188), inclusion=trainersanity),
LocationData("Route 19", "Beauty 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_7_ITEM"], EventFlag(189), inclusion=trainersanity),
LocationData("Route 19", "Beauty 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_6_ITEM"], EventFlag(193), inclusion=trainersanity),
LocationData("Route 19", "Beauty 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_19_TRAINER_9_ITEM"], EventFlag(185), inclusion=trainersanity),
LocationData("Route 18", "Bird Keeper 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_18_TRAINER_2_ITEM"], EventFlag(200), inclusion=trainersanity),
LocationData("Route 18", "Bird Keeper 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_18_TRAINER_1_ITEM"], EventFlag(201), inclusion=trainersanity),
LocationData("Route 18", "Bird Keeper 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_18_TRAINER_0_ITEM"], EventFlag(202), inclusion=trainersanity),
LocationData("Route 17", "Cue Ball 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_1_ITEM"], EventFlag(211), inclusion=trainersanity),
LocationData("Route 17", "Biker 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_2_ITEM"], EventFlag(210), inclusion=trainersanity),
LocationData("Route 17", "Cue Ball 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_0_ITEM"], EventFlag(212), inclusion=trainersanity),
LocationData("Route 17", "Biker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_3_ITEM"], EventFlag(209), inclusion=trainersanity),
LocationData("Route 17", "Biker 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_4_ITEM"], EventFlag(208), inclusion=trainersanity),
LocationData("Route 17", "Cue Ball 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_5_ITEM"], EventFlag(207), inclusion=trainersanity),
LocationData("Route 17", "Cue Ball 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_6_ITEM"], EventFlag(206), inclusion=trainersanity),
LocationData("Route 17", "Biker 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_8_ITEM"], EventFlag(204), inclusion=trainersanity),
LocationData("Route 17", "Cue Ball 5", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_7_ITEM"], EventFlag(205), inclusion=trainersanity),
LocationData("Route 17", "Biker 5", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_17_TRAINER_9_ITEM"], EventFlag(203), inclusion=trainersanity),
LocationData("Route 16 West", "Biker", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_16_TRAINER_0_ITEM"], EventFlag(219), inclusion=trainersanity),
LocationData("Route 16 West", "Cue Ball 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_16_TRAINER_1_ITEM"], EventFlag(218), inclusion=trainersanity),
LocationData("Route 16 West", "Cue Ball 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_16_TRAINER_2_ITEM"], EventFlag(217), inclusion=trainersanity),
LocationData("Route 16 West", "Biker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_16_TRAINER_3_ITEM"], EventFlag(216), inclusion=trainersanity),
LocationData("Route 16 West", "Cue Ball 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_16_TRAINER_4_ITEM"], EventFlag(215), inclusion=trainersanity),
LocationData("Route 16 West", "Biker 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_16_TRAINER_5_ITEM"], EventFlag(214), inclusion=trainersanity),
LocationData("Route 15", "Jr. Trainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_8_ITEM"], EventFlag(221), inclusion=trainersanity),
LocationData("Route 15", "Beauty 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_4_ITEM"], EventFlag(225), inclusion=trainersanity),
LocationData("Route 15", "Jr. Trainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_1_ITEM"], EventFlag(228), inclusion=trainersanity),
LocationData("Route 15", "Biker 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_6_ITEM"], EventFlag(223), inclusion=trainersanity),
LocationData("Route 15", "Biker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_7_ITEM"], EventFlag(222), inclusion=trainersanity),
LocationData("Route 15", "Jr. Trainer F 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_0_ITEM"], EventFlag(229), inclusion=trainersanity),
LocationData("Route 15", "Beauty 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_5_ITEM"], EventFlag(224), inclusion=trainersanity),
LocationData("Route 15", "Bird Keeper 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_3_ITEM"], EventFlag(226), inclusion=trainersanity),
LocationData("Route 15", "Bird Keeper 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_2_ITEM"], EventFlag(227), inclusion=trainersanity),
LocationData("Route 15", "Jr. Trainer F 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_15_TRAINER_9_ITEM"], EventFlag(220), inclusion=trainersanity),
LocationData("Route 14", "Bird Keeper 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_0_ITEM"], EventFlag(244), inclusion=trainersanity),
LocationData("Route 14", "Bird Keeper 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_1_ITEM"], EventFlag(240), inclusion=trainersanity),
LocationData("Route 14", "Bird Keeper 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_2_ITEM"], EventFlag(237), inclusion=trainersanity),
LocationData("Route 14", "Bird Keeper 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_3_ITEM"], EventFlag(236), inclusion=trainersanity),
LocationData("Route 14", "Biker 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_8_ITEM"], EventFlag(231), inclusion=trainersanity),
LocationData("Route 14", "Bird Keeper 5", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_4_ITEM"], EventFlag(235), inclusion=trainersanity),
LocationData("Route 14", "Biker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_9_ITEM"], EventFlag(230), inclusion=trainersanity),
LocationData("Route 14", "Biker 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_7_ITEM"], EventFlag(232), inclusion=trainersanity),
LocationData("Route 14", "Biker 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_6_ITEM"], EventFlag(233), inclusion=trainersanity),
LocationData("Route 14", "Bird Keeper 6", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_14_TRAINER_5_ITEM"], EventFlag(234), inclusion=trainersanity),
LocationData("Route 13 East", "Jr. Trainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_4_ITEM"], EventFlag(253), inclusion=trainersanity),
LocationData("Route 13 East", "Bird Keeper 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_0_ITEM"], EventFlag(257), inclusion=trainersanity),
LocationData("Route 13 East", "Jr. Trainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_1_ITEM"], EventFlag(256), inclusion=trainersanity),
LocationData("Route 13", "Beauty 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_6_ITEM"], EventFlag(248), inclusion=trainersanity),
LocationData("Route 13", "Beauty 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_7_ITEM"], EventFlag(247), inclusion=trainersanity),
LocationData("Route 13", "Jr. Trainer F 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_2_ITEM"], EventFlag(255), inclusion=trainersanity),
LocationData("Route 13", "Jr. Trainer F 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_3_ITEM"], EventFlag(254), inclusion=trainersanity),
LocationData("Route 13", "Bird Keeper 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_9_ITEM"], EventFlag(245), inclusion=trainersanity),
LocationData("Route 13", "Bird Keeper 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_5_ITEM"], EventFlag(252), inclusion=trainersanity),
LocationData("Route 13", "Biker", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_13_TRAINER_8_ITEM"], EventFlag(246), inclusion=trainersanity),
LocationData("Route 12 North", "Fisherman 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_12_TRAINER_0_ITEM"], EventFlag(277), inclusion=trainersanity),
LocationData("Route 12 North", "Fisherman 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_12_TRAINER_1_ITEM"], EventFlag(276), inclusion=trainersanity),
LocationData("Route 12 North", "Fisherman 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_12_TRAINER_4_ITEM"], EventFlag(269), inclusion=trainersanity),
LocationData("Route 12 North", "Fisherman 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_12_TRAINER_5_ITEM"], EventFlag(268), inclusion=trainersanity),
LocationData("Route 12 South", "Rocker", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_12_TRAINER_3_ITEM"], EventFlag(270), inclusion=trainersanity),
LocationData("Route 12 South", "Jr. Trainer M", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_12_TRAINER_2_ITEM"], EventFlag(272), inclusion=trainersanity),
LocationData("Route 12 Grass", "Fisherman 5", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_12_TRAINER_6_ITEM"], EventFlag(264), inclusion=trainersanity),
LocationData("Route 11", "Youngster 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_2_ITEM"], EventFlag(286), inclusion=trainersanity),
LocationData("Route 11", "Gambler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_0_ITEM"], EventFlag(288), inclusion=trainersanity),
LocationData("Route 11", "Youngster 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_9_ITEM"], EventFlag(278), inclusion=trainersanity),
LocationData("Route 11", "Youngster 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_4_ITEM"], EventFlag(284), inclusion=trainersanity),
LocationData("Route 11", "Gambler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_1_ITEM"], EventFlag(287), inclusion=trainersanity),
LocationData("Route 11", "Gambler 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_6_ITEM"], EventFlag(282), inclusion=trainersanity),
LocationData("Route 11", "Engineer 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_3_ITEM"], EventFlag(285), inclusion=trainersanity),
LocationData("Route 11", "Engineer 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_8_ITEM"], EventFlag(280), inclusion=trainersanity),
LocationData("Route 11", "Youngster 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_7_ITEM"], EventFlag(281), inclusion=trainersanity),
LocationData("Route 11", "Gambler 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_11_TRAINER_5_ITEM"], EventFlag(283), inclusion=trainersanity),
LocationData("Rock Tunnel 1F", "PokeManiac", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_1_TRAINER_3_ITEM"], EventFlag(302), inclusion=trainersanity),
LocationData("Rock Tunnel 1F", "Hiker 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_1_TRAINER_0_ITEM"], EventFlag(305), inclusion=trainersanity),
LocationData("Rock Tunnel 1F", "Hiker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_1_TRAINER_1_ITEM"], EventFlag(304), inclusion=trainersanity),
LocationData("Rock Tunnel 1F", "Hiker 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_1_TRAINER_2_ITEM"], EventFlag(303), inclusion=trainersanity),
LocationData("Rock Tunnel 1F", "Jr. Trainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_1_TRAINER_4_ITEM"], EventFlag(301), inclusion=trainersanity),
LocationData("Rock Tunnel 1F", "Jr. Trainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_1_TRAINER_6_ITEM"], EventFlag(299), inclusion=trainersanity),
LocationData("Rock Tunnel 1F", "Jr. Trainer F 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_1_TRAINER_5_ITEM"], EventFlag(300), inclusion=trainersanity),
LocationData("Rock Tunnel B1F", "PokeManiac 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_2_TRAINER_7_ITEM"], EventFlag(5), inclusion=trainersanity),
LocationData("Rock Tunnel B1F", "Jr. Trainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_2_TRAINER_5_ITEM"], EventFlag(8), inclusion=trainersanity),
LocationData("Rock Tunnel B1F", "PokeManiac 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_2_TRAINER_3_ITEM"], EventFlag(10), inclusion=trainersanity),
LocationData("Rock Tunnel B1F", "Hiker 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_2_TRAINER_6_ITEM"], EventFlag(7), inclusion=trainersanity),
LocationData("Rock Tunnel B1F", "Hiker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_2_TRAINER_4_ITEM"], EventFlag(9), inclusion=trainersanity),
LocationData("Rock Tunnel B1F", "Jr. Trainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_2_TRAINER_0_ITEM"], EventFlag(13), inclusion=trainersanity),
LocationData("Rock Tunnel B1F", "Hiker 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_2_TRAINER_1_ITEM"], EventFlag(12), inclusion=trainersanity),
LocationData("Rock Tunnel B1F", "PokeManiac 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROCK_TUNNEL_2_TRAINER_2_ITEM"], EventFlag(11), inclusion=trainersanity),
LocationData("Route 10 North", "Jr. Trainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_10_TRAINER_3_ITEM"], EventFlag(308), inclusion=trainersanity),
LocationData("Route 10 North", "PokeManiac", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_10_TRAINER_0_ITEM"], EventFlag(311), inclusion=trainersanity),
LocationData("Route 10 South", "J.r Trainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_10_TRAINER_5_ITEM"], EventFlag(306), inclusion=trainersanity),
LocationData("Route 10 South", "Hiker 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_10_TRAINER_1_ITEM"], EventFlag(310), inclusion=trainersanity),
LocationData("Route 10 South", "Hiker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_10_TRAINER_4_ITEM"], EventFlag(307), inclusion=trainersanity),
LocationData("Route 10 South", "Super Nerd", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_10_TRAINER_2_ITEM"], EventFlag(309), inclusion=trainersanity),
LocationData("Route 9", "Jr. Trainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_0_ITEM"], EventFlag(320), inclusion=trainersanity),
LocationData("Route 9", "Hiker 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_4_ITEM"], EventFlag(316), inclusion=trainersanity),
LocationData("Route 9", "Jr. Trainer M 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_1_ITEM"], EventFlag(319), inclusion=trainersanity),
LocationData("Route 9", "Bug Catcher 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_6_ITEM"], EventFlag(314), inclusion=trainersanity),
LocationData("Route 9", "Hiker 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_7_ITEM"], EventFlag(313), inclusion=trainersanity),
LocationData("Route 9", "Bug Catcher 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_8_ITEM"], EventFlag(312), inclusion=trainersanity),
LocationData("Route 9", "Jr. Trainer M 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_2_ITEM"], EventFlag(318), inclusion=trainersanity),
LocationData("Route 9", "Hiker 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_5_ITEM"], EventFlag(315), inclusion=trainersanity),
LocationData("Route 9", "Jr. Trainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_9_TRAINER_3_ITEM"], EventFlag(317), inclusion=trainersanity),
LocationData("Route 8", "Lass 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_8_ITEM"], EventFlag(321), inclusion=trainersanity),
LocationData("Route 8", "Gambler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_7_ITEM"], EventFlag(322), inclusion=trainersanity),
LocationData("Route 8", "Super Nerd 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_2_ITEM"], EventFlag(327), inclusion=trainersanity),
LocationData("Route 8", "Lass 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_3_ITEM"], EventFlag(326), inclusion=trainersanity),
LocationData("Route 8", "Super Nerd 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_4_ITEM"], EventFlag(325), inclusion=trainersanity),
LocationData("Route 8", "Lass 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_5_ITEM"], EventFlag(324), inclusion=trainersanity),
LocationData("Route 8", "Lass 4", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_6_ITEM"], EventFlag(323), inclusion=trainersanity),
LocationData("Route 8", "Gambler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_1_ITEM"], EventFlag(328), inclusion=trainersanity),
LocationData("Route 8", "Super Nerd 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_8_TRAINER_0_ITEM"], EventFlag(329), inclusion=trainersanity),
LocationData("Route 6", "Bug Catcher 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_6_TRAINER_2_ITEM"], EventFlag(333), inclusion=trainersanity),
LocationData("Route 6", "Jr. Trainer M 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_6_TRAINER_1_ITEM"], EventFlag(334), inclusion=trainersanity),
LocationData("Route 6", "Jr. Trainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_6_TRAINER_0_ITEM"], EventFlag(335), inclusion=trainersanity),
LocationData("Route 6", "Bug Catcher 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_6_TRAINER_5_ITEM"], EventFlag(330), inclusion=trainersanity),
LocationData("Route 6", "Jr. Trainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_6_TRAINER_4_ITEM"], EventFlag(331), inclusion=trainersanity),
LocationData("Route 6", "Jr. Trainer M 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_6_TRAINER_3_ITEM"], EventFlag(332), inclusion=trainersanity),
LocationData("Route 4", "Cooltrainer F", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_4_TRAINER_0_ITEM"], EventFlag(336), inclusion=trainersanity),
LocationData("Route 3", "Lass 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_3_TRAINER_2_ITEM"], EventFlag(345), inclusion=trainersanity),
LocationData("Route 3", "Bug Catcher 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_3_TRAINER_0_ITEM"], EventFlag(347), inclusion=trainersanity),
LocationData("Route 3", "Youngster 1", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_3_TRAINER_1_ITEM"], EventFlag(346), inclusion=trainersanity),
LocationData("Route 3", "Bug Catcher 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_3_TRAINER_3_ITEM"], EventFlag(344), inclusion=trainersanity),
LocationData("Route 3", "Lass 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_3_TRAINER_4_ITEM"], EventFlag(341), inclusion=trainersanity),
LocationData("Route 3", "Youngster 2", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_3_TRAINER_5_ITEM"], EventFlag(340), inclusion=trainersanity),
LocationData("Route 3", "Bug Catcher 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_3_TRAINER_6_ITEM"], EventFlag(339), inclusion=trainersanity),
LocationData("Route 3", "Lass 3", None, rom_addresses["Trainersanity_EVENT_BEAT_ROUTE_3_TRAINER_7_ITEM"], EventFlag(338), inclusion=trainersanity),
LocationData("Saffron Gym", "Psychic 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SAFFRON_GYM_TRAINER_5_ITEM"], EventFlag(349), inclusion=trainersanity),
LocationData("Saffron Gym", "Psychic 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SAFFRON_GYM_TRAINER_3_ITEM"], EventFlag(351), inclusion=trainersanity),
LocationData("Saffron Gym", "Psychic 3", None, rom_addresses["Trainersanity_EVENT_BEAT_SAFFRON_GYM_TRAINER_1_ITEM"], EventFlag(360), inclusion=trainersanity),
LocationData("Saffron Gym", "Channeler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_SAFFRON_GYM_TRAINER_0_ITEM"], EventFlag(361), inclusion=trainersanity),
LocationData("Saffron Gym", "Psychic 4", None, rom_addresses["Trainersanity_EVENT_BEAT_SAFFRON_GYM_TRAINER_6_ITEM"], EventFlag(348), inclusion=trainersanity),
LocationData("Saffron Gym", "Channeler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_SAFFRON_GYM_TRAINER_2_ITEM"], EventFlag(357), inclusion=trainersanity),
LocationData("Saffron Gym", "Channeler 3", None, rom_addresses["Trainersanity_EVENT_BEAT_SAFFRON_GYM_TRAINER_4_ITEM"], EventFlag(350), inclusion=trainersanity),
LocationData("Fighting Dojo", "Blackbelt 1", None, rom_addresses["Trainersanity_EVENT_BEAT_FIGHTING_DOJO_TRAINER_3_ITEM"], EventFlag(363), inclusion=trainersanity),
LocationData("Fighting Dojo", "Blackbelt 2", None, rom_addresses["Trainersanity_EVENT_BEAT_FIGHTING_DOJO_TRAINER_1_ITEM"], EventFlag(365), inclusion=trainersanity),
LocationData("Fighting Dojo", "Blackbelt 3", None, rom_addresses["Trainersanity_EVENT_BEAT_FIGHTING_DOJO_TRAINER_2_ITEM"], EventFlag(364), inclusion=trainersanity),
LocationData("Fighting Dojo", "Blackbelt 4", None, rom_addresses["Trainersanity_EVENT_BEAT_FIGHTING_DOJO_TRAINER_0_ITEM"], EventFlag(366), inclusion=trainersanity),
LocationData("Fuchsia Gym", "Juggler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_FUCHSIA_GYM_TRAINER_2_ITEM"], EventFlag(380), inclusion=trainersanity),
LocationData("Fuchsia Gym", "Juggler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_FUCHSIA_GYM_TRAINER_0_ITEM"], EventFlag(382), inclusion=trainersanity),
LocationData("Fuchsia Gym", "Juggler 3", None, rom_addresses["Trainersanity_EVENT_BEAT_FUCHSIA_GYM_TRAINER_1_ITEM"], EventFlag(381), inclusion=trainersanity),
LocationData("Fuchsia Gym", "Tamer 1", None, rom_addresses["Trainersanity_EVENT_BEAT_FUCHSIA_GYM_TRAINER_4_ITEM"], EventFlag(378), inclusion=trainersanity),
LocationData("Fuchsia Gym", "Tamer 2", None, rom_addresses["Trainersanity_EVENT_BEAT_FUCHSIA_GYM_TRAINER_3_ITEM"], EventFlag(379), inclusion=trainersanity),
LocationData("Fuchsia Gym", "Juggler 4", None, rom_addresses["Trainersanity_EVENT_BEAT_FUCHSIA_GYM_TRAINER_5_ITEM"], EventFlag(377), inclusion=trainersanity),
LocationData("Celadon Gym", "Lass 1", None, rom_addresses["Trainersanity_EVENT_BEAT_CELADON_GYM_TRAINER_0_ITEM"], EventFlag(391), inclusion=trainersanity),
LocationData("Celadon Gym", "Beauty 1", None, rom_addresses["Trainersanity_EVENT_BEAT_CELADON_GYM_TRAINER_1_ITEM"], EventFlag(390), inclusion=trainersanity),
LocationData("Celadon Gym", "Beauty 2", None, rom_addresses["Trainersanity_EVENT_BEAT_CELADON_GYM_TRAINER_3_ITEM"], EventFlag(388), inclusion=trainersanity),
LocationData("Celadon Gym", "Jr. Trainer F", None, rom_addresses["Trainersanity_EVENT_BEAT_CELADON_GYM_TRAINER_2_ITEM"], EventFlag(389), inclusion=trainersanity),
LocationData("Celadon Gym", "Lass 2", None, rom_addresses["Trainersanity_EVENT_BEAT_CELADON_GYM_TRAINER_4_ITEM"], EventFlag(387), inclusion=trainersanity),
LocationData("Celadon Gym", "Cool Trainer F", None, rom_addresses["Trainersanity_EVENT_BEAT_CELADON_GYM_TRAINER_6_ITEM"], EventFlag(385), inclusion=trainersanity),
LocationData("Celadon Gym", "Beauty 3", None, rom_addresses["Trainersanity_EVENT_BEAT_CELADON_GYM_TRAINER_5_ITEM"], EventFlag(386), inclusion=trainersanity),
LocationData("Vermilion Gym", "Sailor", None, rom_addresses["Trainersanity_EVENT_BEAT_VERMILION_GYM_TRAINER_2_ITEM"], EventFlag(394), inclusion=trainersanity),
LocationData("Vermilion Gym", "Rocker", None, rom_addresses["Trainersanity_EVENT_BEAT_VERMILION_GYM_TRAINER_1_ITEM"], EventFlag(395), inclusion=trainersanity),
LocationData("Vermilion Gym", "Gentleman", None, rom_addresses["Trainersanity_EVENT_BEAT_VERMILION_GYM_TRAINER_0_ITEM"], EventFlag(400), inclusion=trainersanity),
LocationData("Pokemon Tower 3F", "Channeler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_3_TRAINER_0_ITEM"], EventFlag(417), inclusion=trainersanity),
LocationData("Pokemon Tower 3F", "Channeler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_3_TRAINER_1_ITEM"], EventFlag(416), inclusion=trainersanity),
LocationData("Pokemon Tower 3F", "Channeler 3", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_3_TRAINER_2_ITEM"], EventFlag(415), inclusion=trainersanity),
LocationData("Pokemon Tower 4F", "Channeler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_4_TRAINER_1_ITEM"], EventFlag(413), inclusion=trainersanity),
LocationData("Pokemon Tower 4F", "Channeler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_4_TRAINER_2_ITEM"], EventFlag(412), inclusion=trainersanity),
LocationData("Pokemon Tower 4F", "Channeler 3", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_4_TRAINER_0_ITEM"], EventFlag(414), inclusion=trainersanity),
LocationData("Pokemon Tower 5F", "Channeler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_5_TRAINER_1_ITEM"], EventFlag(410), inclusion=trainersanity),
LocationData("Pokemon Tower 5F", "Channeler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_5_TRAINER_0_ITEM"], EventFlag(411), inclusion=trainersanity),
LocationData("Pokemon Tower 5F", "Channeler 3", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_5_TRAINER_2_ITEM"], EventFlag(409), inclusion=trainersanity),
LocationData("Pokemon Tower 5F", "Channeler 4", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_5_TRAINER_3_ITEM"], EventFlag(408), inclusion=trainersanity),
LocationData("Pokemon Tower 6F", "Channeler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_6_TRAINER_0_ITEM"], EventFlag(407), inclusion=trainersanity),
LocationData("Pokemon Tower 6F", "Channeler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_6_TRAINER_2_ITEM"], EventFlag(405), inclusion=trainersanity),
LocationData("Pokemon Tower 6F", "Channeler 3", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_6_TRAINER_1_ITEM"], EventFlag(406), inclusion=trainersanity),
LocationData("Pokemon Tower 7F", "Rocket 1", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_7_TRAINER_0_ITEM"], EventFlag(403), inclusion=trainersanity),
LocationData("Pokemon Tower 7F", "Rocket 2", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_7_TRAINER_1_ITEM"], EventFlag(402), inclusion=trainersanity),
LocationData("Pokemon Tower 7F", "Rocket 3", None, rom_addresses["Trainersanity_EVENT_BEAT_POKEMONTOWER_7_TRAINER_2_ITEM"], EventFlag(401), inclusion=trainersanity),
LocationData("Cerulean Gym", "Swimmer", None, rom_addresses["Trainersanity_EVENT_BEAT_CERULEAN_GYM_TRAINER_1_ITEM"], EventFlag(420), inclusion=trainersanity),
LocationData("Cerulean Gym", "Jr. Trainer F", None, rom_addresses["Trainersanity_EVENT_BEAT_CERULEAN_GYM_TRAINER_0_ITEM"], EventFlag(421), inclusion=trainersanity),
LocationData("Pewter Gym", "Jr. Trainer M", None, rom_addresses["Trainersanity_EVENT_BEAT_PEWTER_GYM_TRAINER_0_ITEM"], EventFlag(434), inclusion=trainersanity),
LocationData("Viridian Gym", "Tamer 1", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_GYM_TRAINER_6_ITEM"], EventFlag(436), inclusion=trainersanity),
LocationData("Viridian Gym", "Blackbelt 1", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_GYM_TRAINER_3_ITEM"], EventFlag(439), inclusion=trainersanity),
LocationData("Viridian Gym", "Cooltrainer M 1", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_GYM_TRAINER_7_ITEM"], EventFlag(435), inclusion=trainersanity),
LocationData("Viridian Gym", "Cooltrainer M 2", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_GYM_TRAINER_0_ITEM"], EventFlag(446), inclusion=trainersanity),
LocationData("Viridian Gym", "Blackbelt 2", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_GYM_TRAINER_1_ITEM"], EventFlag(445), inclusion=trainersanity),
LocationData("Viridian Gym", "Tamer 2", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_GYM_TRAINER_2_ITEM"], EventFlag(440), inclusion=trainersanity),
LocationData("Viridian Gym", "Cooltrainer M 3", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_GYM_TRAINER_5_ITEM"], EventFlag(437), inclusion=trainersanity),
LocationData("Viridian Gym", "Blackbelt 3", None, rom_addresses["Trainersanity_EVENT_BEAT_VIRIDIAN_GYM_TRAINER_4_ITEM"], EventFlag(438), inclusion=trainersanity),
LocationData("Victory Road 1F", "Cooltrainer F", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_1_TRAINER_0_ITEM"], EventFlag(15), inclusion=trainersanity),
LocationData("Victory Road 1F", "Cooltrainer M", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_1_TRAINER_1_ITEM"], EventFlag(14), inclusion=trainersanity),
LocationData("Victory Road 2F", "Blackbelt", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_2_TRAINER_0_ITEM"], EventFlag(162), inclusion=trainersanity),
LocationData("Victory Road 2F", "Juggler 1", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_2_TRAINER_1_ITEM"], EventFlag(161), inclusion=trainersanity),
LocationData("Victory Road 2F", "Tamer", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_2_TRAINER_2_ITEM"], EventFlag(160), inclusion=trainersanity),
LocationData("Victory Road 2F", "Juggler 2", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_2_TRAINER_4_ITEM"], EventFlag(158), inclusion=trainersanity),
LocationData("Victory Road 2F", "PokeManiac", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_2_TRAINER_3_ITEM"], EventFlag(159), inclusion=trainersanity),
LocationData("Victory Road 3F", "Cooltrainer M 1", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_3_TRAINER_0_ITEM"], EventFlag(103), inclusion=trainersanity),
LocationData("Victory Road 3F", "Cooltrainer F 1", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_3_TRAINER_3_ITEM"], EventFlag(100), inclusion=trainersanity),
LocationData("Victory Road 3F", "Cooltrainer M 2", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_3_TRAINER_2_ITEM"], EventFlag(101), inclusion=trainersanity),
LocationData("Victory Road 3F", "Cooltrainer F 2", None, rom_addresses["Trainersanity_EVENT_BEAT_VICTORY_ROAD_3_TRAINER_1_ITEM"], EventFlag(102), inclusion=trainersanity),
LocationData("Indigo Plateau", "Lorelei", None, rom_addresses["Trainersanity_EVENT_BEAT_LORELEIS_ROOM_TRAINER_0_ITEM"], EventFlag(21), inclusion=trainersanity),
LocationData("Indigo Plateau", "Bruno", None, rom_addresses["Trainersanity_EVENT_BEAT_BRUNOS_ROOM_TRAINER_0_ITEM"], EventFlag(20), inclusion=trainersanity),
LocationData("Indigo Plateau", "Agatha", None, rom_addresses["Trainersanity_EVENT_BEAT_AGATHAS_ROOM_TRAINER_0_ITEM"], EventFlag(19), inclusion=trainersanity),
LocationData("Indigo Plateau", "Lance", None, rom_addresses["Trainersanity_EVENT_BEAT_LANCES_ROOM_TRAINER_0_ITEM"], EventFlag(18), inclusion=trainersanity),
LocationData("Indigo Plateau", "Become Champion", "Become Champion", event=True),
LocationData("Pokemon Tower 7F", "Fuji Saved", "Fuji Saved", event=True),
@ -977,25 +1318,25 @@ location_data = [
event=True, type="Wild Encounter"),
LocationData("Route 13", "Wild Pokemon - 10", ["Gloom", "Weepinbell"], rom_addresses["Wild_Route13"] + 19, None,
event=True, type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 1", ["Oddish", "Bellsprout"], rom_addresses["Wild_Route14"] + 1, None,
LocationData("Route 14 Grass", "Wild Pokemon - 1", ["Oddish", "Bellsprout"], rom_addresses["Wild_Route14"] + 1, None,
event=True, type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 2", "Pidgey", rom_addresses["Wild_Route14"] + 3, None, event=True,
LocationData("Route 14 Grass", "Wild Pokemon - 2", "Pidgey", rom_addresses["Wild_Route14"] + 3, None, event=True,
type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 3", "Ditto", rom_addresses["Wild_Route14"] + 5, None, event=True,
LocationData("Route 14 Grass", "Wild Pokemon - 3", "Ditto", rom_addresses["Wild_Route14"] + 5, None, event=True,
type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 4", "Venonat", rom_addresses["Wild_Route14"] + 7, None, event=True,
LocationData("Route 14 Grass", "Wild Pokemon - 4", "Venonat", rom_addresses["Wild_Route14"] + 7, None, event=True,
type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 5", ["Oddish", "Bellsprout"], rom_addresses["Wild_Route14"] + 9, None,
LocationData("Route 14 Grass", "Wild Pokemon - 5", ["Oddish", "Bellsprout"], rom_addresses["Wild_Route14"] + 9, None,
event=True, type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 6", "Venonat", rom_addresses["Wild_Route14"] + 11, None, event=True,
LocationData("Route 14 Grass", "Wild Pokemon - 6", "Venonat", rom_addresses["Wild_Route14"] + 11, None, event=True,
type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 7", ["Oddish", "Bellsprout"], rom_addresses["Wild_Route14"] + 13, None,
LocationData("Route 14 Grass", "Wild Pokemon - 7", ["Oddish", "Bellsprout"], rom_addresses["Wild_Route14"] + 13, None,
event=True, type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 8", ["Gloom", "Weepinbell"], rom_addresses["Wild_Route14"] + 15, None,
LocationData("Route 14 Grass", "Wild Pokemon - 8", ["Gloom", "Weepinbell"], rom_addresses["Wild_Route14"] + 15, None,
event=True, type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 9", "Pidgeotto", rom_addresses["Wild_Route14"] + 17, None, event=True,
LocationData("Route 14 Grass", "Wild Pokemon - 9", "Pidgeotto", rom_addresses["Wild_Route14"] + 17, None, event=True,
type="Wild Encounter"),
LocationData("Route 14", "Wild Pokemon - 10", "Pidgeotto", rom_addresses["Wild_Route14"] + 19, None, event=True,
LocationData("Route 14 Grass", "Wild Pokemon - 10", "Pidgeotto", rom_addresses["Wild_Route14"] + 19, None, event=True,
type="Wild Encounter"),
LocationData("Route 15", "Wild Pokemon - 1", ["Oddish", "Bellsprout"], rom_addresses["Wild_Route15"] + 1, None,
event=True, type="Wild Encounter"),
@ -1653,9 +1994,9 @@ location_data = [
LocationData("Route 16", "Sleeping Pokemon", "Snorlax", rom_addresses["Static_Encounter_Snorlax_B"],
None, event=True, type="Missable Pokemon"),
LocationData("Saffron City", "Fighting Dojo Gift 1", "Hitmonlee", rom_addresses["Gift_Hitmonlee"],
LocationData("Fighting Dojo", "Gift 1", "Hitmonlee", rom_addresses["Gift_Hitmonlee"],
None, event=True, type="Missable Pokemon"),
LocationData("Saffron City", "Fighting Dojo Gift 2", "Hitmonchan", rom_addresses["Gift_Hitmonchan"],
LocationData("Fighting Dojo", "Gift 2", "Hitmonchan", rom_addresses["Gift_Hitmonchan"],
None, event=True, type="Missable Pokemon"),
LocationData("Pallet Town", "Starter 1", "Charmander", [rom_addresses["Starter1_A"],
@ -1697,6 +2038,7 @@ location_data = [
None, event=True, type="Legendary Pokemon"),
LocationData("Vermilion City", "Legendary Pokemon", "Mew", rom_addresses["Static_Encounter_Mew"],
None, event=True, type="Legendary Pokemon"),
]
for i, location in enumerate(location_data):

View File

@ -59,6 +59,15 @@ class PokemonLogic(LogicMixin):
return len([item for item in ["Boulder Badge", "Cascade Badge", "Thunder Badge", "Rainbow Badge", "Marsh Badge",
"Soul Badge", "Volcano Badge", "Earth Badge"] if self.has(item, player)]) >= count
def pokemon_rb_oaks_aide(self, count, player):
if self.multiworld.randomize_pokedex[player].value > 0:
if not self.has("Pokedex", player):
return False
else:
if not self.has("Oak's Parcel", player):
return False
return self.pokemon_rb_has_pokemon(count, player)
def pokemon_rb_has_pokemon(self, count, player):
obtained_pokemon = set()
for pokemon in poke_data.pokemon_data.keys():

View File

@ -1,5 +1,5 @@
from Options import Toggle, Choice, Range, SpecialRange, FreeText, TextChoice
from Options import Toggle, Choice, Range, SpecialRange, TextChoice, DeathLink
class GameVersion(Choice):
@ -10,23 +10,25 @@ class GameVersion(Choice):
default = "random"
class TrainerName(FreeText):
"""Your trainer name. Cannot exceed 7 characters.
See the setup guide on archipelago.gg for a list of allowed characters."""
class TrainerName(TextChoice):
"""Your trainer name. If not set to choose_in_game, must be a name not exceeding 7 characters, and the prompt to
name your character in-game will be skipped. See the setup guide on archipelago.gg for a list of allowed characters."""
display_name = "Trainer Name"
default = "ASH"
option_choose_in_game = -1
default = -1
class RivalName(FreeText):
"""Your rival's name. Cannot exceed 7 characters.
See the setup guide on archipelago.gg for a list of allowed characters."""
class RivalName(TextChoice):
"""Your rival's name. If not set to choose_in_game, must be a name not exceeding 7 characters, and the prompt to
name your rival in-game will be skipped. See the setup guide on archipelago.gg for a list of allowed characters."""
display_name = "Rival's Name"
default = "GARY"
option_choose_in_game = -1
default = -1
class Goal(Choice):
"""If Professor Oak is selected, your victory condition will require challenging and defeating Oak after becoming"""
"""Champion and defeating or capturing the Pokemon at the end of Cerulean Cave."""
"""If Professor Oak is selected, your victory condition will require challenging and defeating Oak after becoming
Champion and defeating or capturing the Pokemon at the end of Cerulean Cave."""
display_name = "Goal"
option_pokemon_league = 0
option_professor_oak = 1
@ -59,8 +61,8 @@ class ViridianGymCondition(Range):
class CeruleanCaveCondition(Range):
"""Number of badges, HMs, and key items (not counting items you can lose) required to access Cerulean Cave."""
"""If extra_key_items is turned on, the number chosen will be increased by 4."""
"""Number of badges, HMs, and key items (not counting items you can lose) required to access Cerulean Cave.
If extra_key_items is turned on, the number chosen will be increased by 4."""
display_name = "Cerulean Cave Condition"
range_start = 0
range_end = 25
@ -97,8 +99,8 @@ class BadgesNeededForHMMoves(Choice):
class OldMan(Choice):
"""With Open Viridian City, the Old Man will let you through without needing to turn in Oak's Parcel."""
"""Early Parcel will ensure Oak's Parcel is available at the beginning of your game."""
"""With Open Viridian City, the Old Man will let you through without needing to turn in Oak's Parcel.
Early Parcel will ensure Oak's Parcel is available at the beginning of your game."""
display_name = "Old Man"
option_vanilla = 0
option_early_parcel = 1
@ -106,6 +108,15 @@ class OldMan(Choice):
default = 1
class RandomizePokedex(Choice):
"""Randomize the location of the Pokedex, or start with it. It is required to receive items from Oak's Aides."""
display_name = "Randomize Pokedex"
option_vanilla = 0
option_randomize = 1
option_start_with = 2
default = 0
class Tea(Toggle):
"""Adds a Tea item to the item pool which the Saffron guards require instead of the vending machine drinks.
Adds a location check to the Celadon Mansion 1F, where Tea is acquired in FireRed and LeafGreen."""
@ -144,6 +155,14 @@ class RandomizeHiddenItems(Choice):
default = 0
class TrainerSanity(Toggle):
"""Add a location check to every trainer in the game, which can be obtained by talking to a trainer after defeating
them. Does not affect gym leaders and some scripted event battles (including all Rival, Giovanni, and
Cinnabar Gym battles)."""
display_name = "Trainersanity"
default = 0
class FreeFlyLocation(Toggle):
"""One random fly destination will be unlocked by default."""
display_name = "Free Fly Location"
@ -180,7 +199,7 @@ class OaksAidRt15(Range):
class ExpModifier(SpecialRange):
"""Modifier for EXP gained. When specifying a number, exp is multiplied by this amount and divided by 16."""
display_name = "Exp Modifier"
range_start = 0
range_start = 1
range_end = 255
default = 16
special_range_names = {
@ -330,6 +349,13 @@ class StartWithFourMoves(Toggle):
default = 0
class SameTypeAttackBonus(Toggle):
"""Here you can disable Same Type Attack Bonus, so that a move matching a Pokemon's type has no benefit.
If disabled, all moves will gain 25% extra damage, instead of same type moves gaining 50% extra damage."""
display_name = "Same Type Attack Bonus"
default = 1
class TMCompatibility(Choice):
"""Randomize which Pokemon can learn each TM. prefer_types: 90% chance if Pokemon's type matches the move,
50% chance if move is Normal type and the Pokemon is not, and 25% chance otherwise. Pokemon will retain the same
@ -379,31 +405,54 @@ class SecondaryTypeChance(SpecialRange):
}
class RandomizeTypeChartTypes(Choice):
"""The game's type chart consists of 3 columns: attacking type, defending type, and type effectiveness.
Matchups that have regular type effectiveness are not in the chart. Shuffle will shuffle the attacking types
across the attacking type column and the defending types across the defending type column (so for example Normal
type will still have exactly 2 types that it receives non-regular damage from, and 2 types it deals non-regular
damage to). Randomize will randomize each type in both columns to any random type."""
display_name = "Randomize Type Chart Types"
class RandomizeTypeChart(Choice):
"""Randomize the type chart. If 'randomize' is chosen, the matchup weight options will determine the weights.
If the numbers chosen across the 4 settings add up to exactly 225, they will be the exact numbers of those matchups.
Otherwise, the normal super effective, and not very effective matchup settings will be used as weights.
The immunities option will always be the exact amount of immunity matchups.
If 'chaos' is chosen, the matchup settings will be ignored and every type matchup will be given a random damage
modifier anywhere between 0 to 200% damage, in 10% increments."""
display_name = "Randomize Type Chart"
option_vanilla = 0
option_shuffle = 1
option_randomize = 2
option_randomize = 1
option_chaos = 2
default = 0
class RandomizeTypeChartTypeEffectiveness(Choice):
"""The game's type chart consists of 3 columns: attacking type, defending type, and type effectiveness.
Matchups that have regular type effectiveness are not in the chart. Shuffle will shuffle the type effectiveness
across the type effectiveness column (so for example there will always be 6 type immunities). Randomize will
randomize each entry in the table to no effect, not very effective, or super effective; with no effect occurring
at a low chance. Chaos will randomize the values to anywhere between 0% and 200% damage, in 10% increments."""
display_name = "Randomize Type Chart Type Effectiveness"
option_vanilla = 0
option_shuffle = 1
option_randomize = 2
option_chaos = 3
default = 0
class NormalMatchups(Range):
"""If 'randomize' is chosen for randomize_type_chart, this will be the weight for neutral matchups.
No effect if 'chaos' is chosen"""
display_name = "Normal Matchups"
default = 143
range_start = 0
range_end = 225
class SuperEffectiveMatchups(Range):
"""If 'randomize' is chosen for randomize_type_chart, this will be the weight for super effective matchups.
No effect if 'chaos' is chosen"""
display_name = "Super Effective Matchups"
default = 38
range_start = 0
range_end = 225
class NotVeryEffectiveMatchups(Range):
"""If 'randomize' is chosen for randomize_type_chart, this will be the weight for not very effective matchups.
No effect if 'chaos' is chosen"""
display_name = "Not Very Effective Matchups"
default = 38
range_start = 0
range_end = 225
class ImmunityMatchups(Range):
"""If 'randomize' is chosen for randomize_type_chart, this will be the exact number of immunities.
No effect if 'chaos' is chosen"""
display_name = "Immunity Matchups"
default = 6
range_start = 0
range_end = 100
class SafariZoneNormalBattles(Toggle):
@ -425,6 +474,23 @@ class ReusableTMs(Toggle):
default = 0
class BetterShops(Choice):
"""Change every town's Pokemart to contain all normal Pokemart items. Additionally, you can add the Master Ball
to these shops."""
display_name = "Better Shops"
option_off = 0
option_on = 1
option_add_master_ball = 2
default = 0
class MasterBallPrice(Range):
"""Price for Master Balls. Can only be bought if better_shops is set to add_master_ball, but this will affect the
sell price regardless. Vanilla is 0"""
range_end = 999999
default = 5000
class StartingMoney(Range):
"""The amount of money you start with."""
display_name = "Starting Money"
@ -433,6 +499,21 @@ class StartingMoney(Range):
range_end = 999999
class LoseMoneyOnBlackout(Toggle):
"""Lose half your money when blacking out, as in vanilla."""
display_name = "Lose Money on Blackout"
default = 1
class TrapPercentage(Range):
"""Chance for each filler item to be replaced with trap items: Poison Trap, Paralyze Trap, Ice Trap, and
Fire Trap. These traps apply the status to your entire party! Keep in mind that trainersanity vastly increases the
number of filler items. Make sure to stock up on Ice Heals!"""
display_name = "Trap Percentage"
range_end = 100
default = 0
pokemon_rb_options = {
"game_version": GameVersion,
"trainer_name": TrainerName,
@ -445,11 +526,13 @@ pokemon_rb_options = {
"second_fossil_check_condition": SecondFossilCheckCondition,
"badgesanity": BadgeSanity,
"old_man": OldMan,
"randomize_pokedex": RandomizePokedex,
"tea": Tea,
"extra_key_items": ExtraKeyItems,
"extra_strength_boulders": ExtraStrengthBoulders,
"require_item_finder": RequireItemFinder,
"randomize_hidden_items": RandomizeHiddenItems,
"trainersanity": TrainerSanity,
"badges_needed_for_hm_moves": BadgesNeededForHMMoves,
"free_fly_location": FreeFlyLocation,
"oaks_aide_rt_2": OaksAidRt2,
@ -470,14 +553,23 @@ pokemon_rb_options = {
"trainer_legendaries": TrainerLegendaries,
"randomize_pokemon_movesets": RandomizePokemonMovesets,
"start_with_four_moves": StartWithFourMoves,
"same_type_attack_bonus": SameTypeAttackBonus,
"tm_compatibility": TMCompatibility,
"hm_compatibility": HMCompatibility,
"randomize_pokemon_types": RandomizePokemonTypes,
"secondary_type_chance": SecondaryTypeChance,
"randomize_type_matchup_types": RandomizeTypeChartTypes,
"randomize_type_matchup_type_effectiveness": RandomizeTypeChartTypeEffectiveness,
"randomize_type_chart": RandomizeTypeChart,
"normal_matchups": NormalMatchups,
"super_effective_matchups": SuperEffectiveMatchups,
"not_very_effective_matchups": NotVeryEffectiveMatchups,
"immunity_matchups": ImmunityMatchups,
"safari_zone_normal_battles": SafariZoneNormalBattles,
"normalize_encounter_chances": NormalizeEncounterChances,
"reusable_tms": ReusableTMs,
"better_shops": BetterShops,
"master_ball_price": MasterBallPrice,
"starting_money": StartingMoney,
"lose_money_on_blackout": LoseMoneyOnBlackout,
"trap_percentage": TrapPercentage,
"death_link": DeathLink
}

View File

@ -1,19 +1,15 @@
from BaseClasses import MultiWorld, Region, Entrance, RegionType, LocationProgressType
from worlds.generic.Rules import add_item_rule
from .locations import location_data, PokemonRBLocation
def create_region(world: MultiWorld, player: int, name: str, locations_per_region=None, exits=None):
ret = Region(name, RegionType.Generic, name, player, world)
for location in locations_per_region.get(name, []):
if (world.randomize_hidden_items[player].value or "Hidden" not in location.name) and \
(world.extra_key_items[player].value or name != "Rock Tunnel B1F" or "Item" not in location.name) and \
(world.tea[player].value or location.name != "Celadon City - Mansion Lady"):
location.parent_region = ret
ret.locations.append(location)
if world.randomize_hidden_items[player].value == 2 and "Hidden" in location.name:
location.progress_type = LocationProgressType.EXCLUDED
location.parent_region = ret
ret.locations.append(location)
if world.randomize_hidden_items[player] == "exclude" and "Hidden" in location.name:
location.progress_type = LocationProgressType.EXCLUDED
if exits:
for exit in exits:
ret.exits.append(Entrance(player, exit, ret))
@ -21,265 +17,275 @@ def create_region(world: MultiWorld, player: int, name: str, locations_per_regio
return ret
def create_regions(world: MultiWorld, player: int):
def create_regions(multiworld: MultiWorld, player: int):
locations_per_region = {}
for location in location_data:
locations_per_region.setdefault(location.region, [])
locations_per_region[location.region].append(PokemonRBLocation(player, location.name, location.address,
if location.inclusion(multiworld, player):
locations_per_region[location.region].append(PokemonRBLocation(player, location.name, location.address,
location.rom_address))
regions = [
create_region(world, player, "Menu", locations_per_region),
create_region(world, player, "Anywhere", locations_per_region),
create_region(world, player, "Fossil", locations_per_region),
create_region(world, player, "Pallet Town", locations_per_region),
create_region(world, player, "Route 1", locations_per_region),
create_region(world, player, "Viridian City", locations_per_region),
create_region(world, player, "Viridian City North", locations_per_region),
create_region(world, player, "Viridian Gym", locations_per_region),
create_region(world, player, "Route 2", locations_per_region),
create_region(world, player, "Route 2 East", locations_per_region),
create_region(world, player, "Diglett's Cave", locations_per_region),
create_region(world, player, "Route 22", locations_per_region),
create_region(world, player, "Route 23", locations_per_region),
create_region(world, player, "Viridian Forest", locations_per_region),
create_region(world, player, "Pewter City", locations_per_region),
create_region(world, player, "Pewter Gym", locations_per_region),
create_region(world, player, "Route 3", locations_per_region),
create_region(world, player, "Mt Moon 1F", locations_per_region),
create_region(world, player, "Mt Moon B1F", locations_per_region),
create_region(world, player, "Mt Moon B2F", locations_per_region),
create_region(world, player, "Route 4", locations_per_region),
create_region(world, player, "Cerulean City", locations_per_region),
create_region(world, player, "Cerulean Gym", locations_per_region),
create_region(world, player, "Route 24", locations_per_region),
create_region(world, player, "Route 25", locations_per_region),
create_region(world, player, "Route 9", locations_per_region),
create_region(world, player, "Route 10 North", locations_per_region),
create_region(world, player, "Rock Tunnel 1F", locations_per_region),
create_region(world, player, "Rock Tunnel B1F", locations_per_region),
create_region(world, player, "Power Plant", locations_per_region),
create_region(world, player, "Route 10 South", locations_per_region),
create_region(world, player, "Lavender Town", locations_per_region),
create_region(world, player, "Pokemon Tower 1F", locations_per_region),
create_region(world, player, "Pokemon Tower 2F", locations_per_region),
create_region(world, player, "Pokemon Tower 3F", locations_per_region),
create_region(world, player, "Pokemon Tower 4F", locations_per_region),
create_region(world, player, "Pokemon Tower 5F", locations_per_region),
create_region(world, player, "Pokemon Tower 6F", locations_per_region),
create_region(world, player, "Pokemon Tower 7F", locations_per_region),
create_region(world, player, "Route 5", locations_per_region),
create_region(world, player, "Saffron City", locations_per_region),
create_region(world, player, "Saffron Gym", locations_per_region),
create_region(world, player, "Copycat's House", locations_per_region),
create_region(world, player, "Underground Tunnel North-South", locations_per_region),
create_region(world, player, "Route 6", locations_per_region),
create_region(world, player, "Vermilion City", locations_per_region),
create_region(world, player, "Vermilion Gym", locations_per_region),
create_region(world, player, "S.S. Anne 1F", locations_per_region),
create_region(world, player, "S.S. Anne B1F", locations_per_region),
create_region(world, player, "S.S. Anne 2F", locations_per_region),
create_region(world, player, "Route 11", locations_per_region),
create_region(world, player, "Route 11 East", locations_per_region),
create_region(world, player, "Route 12 North", locations_per_region),
create_region(world, player, "Route 12 South", locations_per_region),
create_region(world, player, "Route 12 Grass", locations_per_region),
create_region(world, player, "Route 12 West", locations_per_region),
create_region(world, player, "Route 7", locations_per_region),
create_region(world, player, "Underground Tunnel West-East", locations_per_region),
create_region(world, player, "Route 8", locations_per_region),
create_region(world, player, "Route 8 Grass", locations_per_region),
create_region(world, player, "Celadon City", locations_per_region),
create_region(world, player, "Celadon Prize Corner", locations_per_region),
create_region(world, player, "Celadon Gym", locations_per_region),
create_region(world, player, "Route 16", locations_per_region),
create_region(world, player, "Route 16 North", locations_per_region),
create_region(world, player, "Route 17", locations_per_region),
create_region(world, player, "Route 18", locations_per_region),
create_region(world, player, "Fuchsia City", locations_per_region),
create_region(world, player, "Fuchsia Gym", locations_per_region),
create_region(world, player, "Safari Zone Gate", locations_per_region),
create_region(world, player, "Safari Zone Center", locations_per_region),
create_region(world, player, "Safari Zone East", locations_per_region),
create_region(world, player, "Safari Zone North", locations_per_region),
create_region(world, player, "Safari Zone West", locations_per_region),
create_region(world, player, "Route 15", locations_per_region),
create_region(world, player, "Route 14", locations_per_region),
create_region(world, player, "Route 13", locations_per_region),
create_region(world, player, "Route 19", locations_per_region),
create_region(world, player, "Route 20 East", locations_per_region),
create_region(world, player, "Route 20 West", locations_per_region),
create_region(world, player, "Seafoam Islands 1F", locations_per_region),
create_region(world, player, "Seafoam Islands B1F", locations_per_region),
create_region(world, player, "Seafoam Islands B2F", locations_per_region),
create_region(world, player, "Seafoam Islands B3F", locations_per_region),
create_region(world, player, "Seafoam Islands B4F", locations_per_region),
create_region(world, player, "Cinnabar Island", locations_per_region),
create_region(world, player, "Cinnabar Gym", locations_per_region),
create_region(world, player, "Route 21", locations_per_region),
create_region(world, player, "Silph Co 1F", locations_per_region),
create_region(world, player, "Silph Co 2F", locations_per_region),
create_region(world, player, "Silph Co 3F", locations_per_region),
create_region(world, player, "Silph Co 4F", locations_per_region),
create_region(world, player, "Silph Co 5F", locations_per_region),
create_region(world, player, "Silph Co 6F", locations_per_region),
create_region(world, player, "Silph Co 7F", locations_per_region),
create_region(world, player, "Silph Co 8F", locations_per_region),
create_region(world, player, "Silph Co 9F", locations_per_region),
create_region(world, player, "Silph Co 10F", locations_per_region),
create_region(world, player, "Silph Co 11F", locations_per_region),
create_region(world, player, "Rocket Hideout B1F", locations_per_region),
create_region(world, player, "Rocket Hideout B2F", locations_per_region),
create_region(world, player, "Rocket Hideout B3F", locations_per_region),
create_region(world, player, "Rocket Hideout B4F", locations_per_region),
create_region(world, player, "Pokemon Mansion 1F", locations_per_region),
create_region(world, player, "Pokemon Mansion 2F", locations_per_region),
create_region(world, player, "Pokemon Mansion 3F", locations_per_region),
create_region(world, player, "Pokemon Mansion B1F", locations_per_region),
create_region(world, player, "Victory Road 1F", locations_per_region),
create_region(world, player, "Victory Road 2F", locations_per_region),
create_region(world, player, "Victory Road 3F", locations_per_region),
create_region(world, player, "Indigo Plateau", locations_per_region),
create_region(world, player, "Cerulean Cave 1F", locations_per_region),
create_region(world, player, "Cerulean Cave 2F", locations_per_region),
create_region(world, player, "Cerulean Cave B1F", locations_per_region),
create_region(world, player, "Evolution", locations_per_region),
create_region(multiworld, player, "Menu", locations_per_region),
create_region(multiworld, player, "Anywhere", locations_per_region),
create_region(multiworld, player, "Fossil", locations_per_region),
create_region(multiworld, player, "Pallet Town", locations_per_region),
create_region(multiworld, player, "Route 1", locations_per_region),
create_region(multiworld, player, "Viridian City", locations_per_region),
create_region(multiworld, player, "Viridian City North", locations_per_region),
create_region(multiworld, player, "Viridian Gym", locations_per_region),
create_region(multiworld, player, "Route 2", locations_per_region),
create_region(multiworld, player, "Route 2 East", locations_per_region),
create_region(multiworld, player, "Diglett's Cave", locations_per_region),
create_region(multiworld, player, "Route 22", locations_per_region),
create_region(multiworld, player, "Route 23", locations_per_region),
create_region(multiworld, player, "Viridian Forest", locations_per_region),
create_region(multiworld, player, "Pewter City", locations_per_region),
create_region(multiworld, player, "Pewter Gym", locations_per_region),
create_region(multiworld, player, "Route 3", locations_per_region),
create_region(multiworld, player, "Mt Moon 1F", locations_per_region),
create_region(multiworld, player, "Mt Moon B1F", locations_per_region),
create_region(multiworld, player, "Mt Moon B2F", locations_per_region),
create_region(multiworld, player, "Route 4", locations_per_region),
create_region(multiworld, player, "Cerulean City", locations_per_region),
create_region(multiworld, player, "Cerulean Gym", locations_per_region),
create_region(multiworld, player, "Route 24", locations_per_region),
create_region(multiworld, player, "Route 25", locations_per_region),
create_region(multiworld, player, "Route 9", locations_per_region),
create_region(multiworld, player, "Route 10 North", locations_per_region),
create_region(multiworld, player, "Rock Tunnel 1F", locations_per_region),
create_region(multiworld, player, "Rock Tunnel B1F", locations_per_region),
create_region(multiworld, player, "Power Plant", locations_per_region),
create_region(multiworld, player, "Route 10 South", locations_per_region),
create_region(multiworld, player, "Lavender Town", locations_per_region),
create_region(multiworld, player, "Pokemon Tower 1F", locations_per_region),
create_region(multiworld, player, "Pokemon Tower 2F", locations_per_region),
create_region(multiworld, player, "Pokemon Tower 3F", locations_per_region),
create_region(multiworld, player, "Pokemon Tower 4F", locations_per_region),
create_region(multiworld, player, "Pokemon Tower 5F", locations_per_region),
create_region(multiworld, player, "Pokemon Tower 6F", locations_per_region),
create_region(multiworld, player, "Pokemon Tower 7F", locations_per_region),
create_region(multiworld, player, "Route 5", locations_per_region),
create_region(multiworld, player, "Saffron City", locations_per_region),
create_region(multiworld, player, "Fighting Dojo", locations_per_region),
create_region(multiworld, player, "Saffron Gym", locations_per_region),
create_region(multiworld, player, "Copycat's House", locations_per_region),
create_region(multiworld, player, "Underground Tunnel North-South", locations_per_region),
create_region(multiworld, player, "Route 6", locations_per_region),
create_region(multiworld, player, "Vermilion City", locations_per_region),
create_region(multiworld, player, "Vermilion Gym", locations_per_region),
create_region(multiworld, player, "S.S. Anne 1F", locations_per_region),
create_region(multiworld, player, "S.S. Anne B1F", locations_per_region),
create_region(multiworld, player, "S.S. Anne 2F", locations_per_region),
create_region(multiworld, player, "S.S. Anne 3F", locations_per_region),
create_region(multiworld, player, "Route 11", locations_per_region),
create_region(multiworld, player, "Route 11 East", locations_per_region),
create_region(multiworld, player, "Route 12 North", locations_per_region),
create_region(multiworld, player, "Route 12 South", locations_per_region),
create_region(multiworld, player, "Route 12 Grass", locations_per_region),
create_region(multiworld, player, "Route 12 West", locations_per_region),
create_region(multiworld, player, "Route 7", locations_per_region),
create_region(multiworld, player, "Underground Tunnel West-East", locations_per_region),
create_region(multiworld, player, "Route 8", locations_per_region),
create_region(multiworld, player, "Route 8 Grass", locations_per_region),
create_region(multiworld, player, "Celadon City", locations_per_region),
create_region(multiworld, player, "Celadon Prize Corner", locations_per_region),
create_region(multiworld, player, "Celadon Gym", locations_per_region),
create_region(multiworld, player, "Route 16", locations_per_region),
create_region(multiworld, player, "Route 16 West", locations_per_region),
create_region(multiworld, player, "Route 16 North", locations_per_region),
create_region(multiworld, player, "Route 17", locations_per_region),
create_region(multiworld, player, "Route 18", locations_per_region),
create_region(multiworld, player, "Fuchsia City", locations_per_region),
create_region(multiworld, player, "Fuchsia Gym", locations_per_region),
create_region(multiworld, player, "Safari Zone Gate", locations_per_region),
create_region(multiworld, player, "Safari Zone Center", locations_per_region),
create_region(multiworld, player, "Safari Zone East", locations_per_region),
create_region(multiworld, player, "Safari Zone North", locations_per_region),
create_region(multiworld, player, "Safari Zone West", locations_per_region),
create_region(multiworld, player, "Route 15", locations_per_region),
create_region(multiworld, player, "Route 14", locations_per_region),
create_region(multiworld, player, "Route 14 Grass", locations_per_region),
create_region(multiworld, player, "Route 13", locations_per_region),
create_region(multiworld, player, "Route 13 East", locations_per_region),
create_region(multiworld, player, "Route 19", locations_per_region),
create_region(multiworld, player, "Route 20 East", locations_per_region),
create_region(multiworld, player, "Route 20 West", locations_per_region),
create_region(multiworld, player, "Seafoam Islands 1F", locations_per_region),
create_region(multiworld, player, "Seafoam Islands B1F", locations_per_region),
create_region(multiworld, player, "Seafoam Islands B2F", locations_per_region),
create_region(multiworld, player, "Seafoam Islands B3F", locations_per_region),
create_region(multiworld, player, "Seafoam Islands B4F", locations_per_region),
create_region(multiworld, player, "Cinnabar Island", locations_per_region),
create_region(multiworld, player, "Cinnabar Gym", locations_per_region),
create_region(multiworld, player, "Route 21", locations_per_region),
create_region(multiworld, player, "Silph Co 1F", locations_per_region),
create_region(multiworld, player, "Silph Co 2F", locations_per_region),
create_region(multiworld, player, "Silph Co 3F", locations_per_region),
create_region(multiworld, player, "Silph Co 4F", locations_per_region),
create_region(multiworld, player, "Silph Co 5F", locations_per_region),
create_region(multiworld, player, "Silph Co 6F", locations_per_region),
create_region(multiworld, player, "Silph Co 7F", locations_per_region),
create_region(multiworld, player, "Silph Co 8F", locations_per_region),
create_region(multiworld, player, "Silph Co 9F", locations_per_region),
create_region(multiworld, player, "Silph Co 10F", locations_per_region),
create_region(multiworld, player, "Silph Co 11F", locations_per_region),
create_region(multiworld, player, "Rocket Hideout B1F", locations_per_region),
create_region(multiworld, player, "Rocket Hideout B2F", locations_per_region),
create_region(multiworld, player, "Rocket Hideout B3F", locations_per_region),
create_region(multiworld, player, "Rocket Hideout B4F", locations_per_region),
create_region(multiworld, player, "Pokemon Mansion 1F", locations_per_region),
create_region(multiworld, player, "Pokemon Mansion 2F", locations_per_region),
create_region(multiworld, player, "Pokemon Mansion 3F", locations_per_region),
create_region(multiworld, player, "Pokemon Mansion B1F", locations_per_region),
create_region(multiworld, player, "Victory Road 1F", locations_per_region),
create_region(multiworld, player, "Victory Road 2F", locations_per_region),
create_region(multiworld, player, "Victory Road 3F", locations_per_region),
create_region(multiworld, player, "Indigo Plateau", locations_per_region),
create_region(multiworld, player, "Cerulean Cave 1F", locations_per_region),
create_region(multiworld, player, "Cerulean Cave 2F", locations_per_region),
create_region(multiworld, player, "Cerulean Cave B1F", locations_per_region),
]
world.regions += regions
connect(world, player, "Menu", "Anywhere", one_way=True)
connect(world, player, "Menu", "Pallet Town", one_way=True)
connect(world, player, "Menu", "Fossil", lambda state: state.pokemon_rb_fossil_checks(
multiworld.regions += regions
connect(multiworld, player, "Menu", "Anywhere", one_way=True)
connect(multiworld, player, "Menu", "Pallet Town", one_way=True)
connect(multiworld, player, "Menu", "Fossil", lambda state: state.pokemon_rb_fossil_checks(
state.multiworld.second_fossil_check_condition[player].value, player), one_way=True)
connect(world, player, "Pallet Town", "Route 1")
connect(world, player, "Route 1", "Viridian City")
connect(world, player, "Viridian City", "Route 22")
connect(world, player, "Route 22", "Route 23",
connect(multiworld, player, "Pallet Town", "Route 1")
connect(multiworld, player, "Route 1", "Viridian City")
connect(multiworld, player, "Viridian City", "Route 22")
connect(multiworld, player, "Route 22", "Route 23",
lambda state: state.pokemon_rb_has_badges(state.multiworld.victory_road_condition[player].value, player) and
state.pokemon_rb_can_surf(player))
connect(world, player, "Viridian City North", "Viridian Gym", lambda state:
connect(multiworld, player, "Viridian City North", "Viridian Gym", lambda state:
state.pokemon_rb_has_badges(state.multiworld.viridian_gym_condition[player].value, player), one_way=True)
connect(world, player, "Route 2", "Route 2 East", lambda state: state.pokemon_rb_can_cut(player))
connect(world, player, "Route 2 East", "Diglett's Cave", lambda state: state.pokemon_rb_can_cut(player))
connect(world, player, "Route 2", "Viridian City North")
connect(world, player, "Route 2", "Viridian Forest")
connect(world, player, "Route 2", "Pewter City")
connect(world, player, "Pewter City", "Pewter Gym", one_way=True)
connect(world, player, "Pewter City", "Route 3")
connect(world, player, "Route 4", "Route 3", one_way=True)
connect(world, player, "Mt Moon 1F", "Mt Moon B1F", one_way=True)
connect(world, player, "Mt Moon B1F", "Mt Moon B2F", one_way=True)
connect(world, player, "Mt Moon B1F", "Route 4", one_way=True)
connect(world, player, "Route 4", "Cerulean City")
connect(world, player, "Cerulean City", "Cerulean Gym", one_way=True)
connect(world, player, "Cerulean City", "Route 24", one_way=True)
connect(world, player, "Route 24", "Route 25", one_way=True)
connect(world, player, "Cerulean City", "Route 9", lambda state: state.pokemon_rb_can_cut(player))
connect(world, player, "Route 9", "Route 10 North")
connect(world, player, "Route 10 North", "Rock Tunnel 1F", lambda state: state.pokemon_rb_can_flash(player))
connect(world, player, "Route 10 North", "Power Plant", lambda state: state.pokemon_rb_can_surf(player) and
(state.has("Plant Key", player) or not state.multiworld.extra_key_items[player].value), one_way=True)
connect(world, player, "Rock Tunnel 1F", "Route 10 South", lambda state: state.pokemon_rb_can_flash(player))
connect(world, player, "Rock Tunnel 1F", "Rock Tunnel B1F")
connect(world, player, "Lavender Town", "Pokemon Tower 1F", one_way=True)
connect(world, player, "Lavender Town", "Pokemon Tower 1F", one_way=True)
connect(world, player, "Pokemon Tower 1F", "Pokemon Tower 2F", one_way=True)
connect(world, player, "Pokemon Tower 2F", "Pokemon Tower 3F", one_way=True)
connect(world, player, "Pokemon Tower 3F", "Pokemon Tower 4F", one_way=True)
connect(world, player, "Pokemon Tower 4F", "Pokemon Tower 5F", one_way=True)
connect(world, player, "Pokemon Tower 5F", "Pokemon Tower 6F", one_way=True)
connect(world, player, "Pokemon Tower 6F", "Pokemon Tower 7F", lambda state: state.has("Silph Scope", player))
connect(world, player, "Cerulean City", "Route 5")
connect(world, player, "Route 5", "Saffron City", lambda state: state.pokemon_rb_can_pass_guards(player))
connect(world, player, "Route 5", "Underground Tunnel North-South")
connect(world, player, "Route 6", "Underground Tunnel North-South")
connect(world, player, "Route 6", "Saffron City", lambda state: state.pokemon_rb_can_pass_guards(player))
connect(world, player, "Route 7", "Saffron City", lambda state: state.pokemon_rb_can_pass_guards(player))
connect(world, player, "Route 8", "Saffron City", lambda state: state.pokemon_rb_can_pass_guards(player))
connect(world, player, "Saffron City", "Copycat's House", lambda state: state.has("Silph Co Liberated", player), one_way=True)
connect(world, player, "Saffron City", "Saffron Gym", lambda state: state.has("Silph Co Liberated", player), one_way=True)
connect(world, player, "Route 6", "Vermilion City")
connect(world, player, "Vermilion City", "Vermilion Gym", lambda state: state.pokemon_rb_can_surf(player) or state.pokemon_rb_can_cut(player), one_way=True)
connect(world, player, "Vermilion City", "S.S. Anne 1F", lambda state: state.has("S.S. Ticket", player), one_way=True)
connect(world, player, "S.S. Anne 1F", "S.S. Anne 2F", one_way=True)
connect(world, player, "S.S. Anne 1F", "S.S. Anne B1F", one_way=True)
connect(world, player, "Vermilion City", "Route 11")
connect(world, player, "Vermilion City", "Diglett's Cave")
connect(world, player, "Route 12 West", "Route 11 East", lambda state: state.pokemon_rb_can_strength(player) or not state.multiworld.extra_strength_boulders[player].value)
connect(world, player, "Route 12 North", "Route 12 South", lambda state: state.has("Poke Flute", player) or state.pokemon_rb_can_surf( player))
connect(world, player, "Route 12 West", "Route 12 North", lambda state: state.has("Poke Flute", player))
connect(world, player, "Route 12 West", "Route 12 South", lambda state: state.has("Poke Flute", player))
connect(world, player, "Route 12 South", "Route 12 Grass", lambda state: state.pokemon_rb_can_cut(player))
connect(world, player, "Route 12 North", "Lavender Town")
connect(world, player, "Route 7", "Lavender Town")
connect(world, player, "Route 10 South", "Lavender Town")
connect(world, player, "Route 7", "Underground Tunnel West-East")
connect(world, player, "Route 8", "Underground Tunnel West-East")
connect(world, player, "Route 8", "Celadon City")
connect(world, player, "Route 8", "Route 8 Grass", lambda state: state.pokemon_rb_can_cut(player), one_way=True)
connect(world, player, "Route 7", "Celadon City")
connect(world, player, "Celadon City", "Celadon Gym", lambda state: state.pokemon_rb_can_cut(player), one_way=True)
connect(world, player, "Celadon City", "Celadon Prize Corner")
connect(world, player, "Celadon City", "Route 16")
connect(world, player, "Route 16", "Route 16 North", lambda state: state.pokemon_rb_can_cut(player), one_way=True)
connect(world, player, "Route 16", "Route 17", lambda state: state.has("Poke Flute", player) and state.has("Bicycle", player))
connect(world, player, "Route 17", "Route 18", lambda state: state.has("Bicycle", player))
connect(world, player, "Fuchsia City", "Fuchsia Gym", one_way=True)
connect(world, player, "Fuchsia City", "Route 18")
connect(world, player, "Fuchsia City", "Safari Zone Gate", one_way=True)
connect(world, player, "Safari Zone Gate", "Safari Zone Center", lambda state: state.has("Safari Pass", player) or not state.multiworld.extra_key_items[player].value, one_way=True)
connect(world, player, "Safari Zone Center", "Safari Zone East", one_way=True)
connect(world, player, "Safari Zone Center", "Safari Zone West", one_way=True)
connect(world, player, "Safari Zone Center", "Safari Zone North", one_way=True)
connect(world, player, "Fuchsia City", "Route 15")
connect(world, player, "Route 15", "Route 14")
connect(world, player, "Route 14", "Route 13")
connect(world, player, "Route 13", "Route 12 South", lambda state: state.pokemon_rb_can_strength(player) or state.pokemon_rb_can_surf(player) or not state.multiworld.extra_strength_boulders[player].value)
connect(world, player, "Fuchsia City", "Route 19", lambda state: state.pokemon_rb_can_surf(player))
connect(world, player, "Route 20 East", "Route 19")
connect(world, player, "Route 20 West", "Cinnabar Island", lambda state: state.pokemon_rb_can_surf(player))
connect(world, player, "Route 20 West", "Seafoam Islands 1F")
connect(world, player, "Route 20 East", "Seafoam Islands 1F", one_way=True)
connect(world, player, "Seafoam Islands 1F", "Route 20 East", lambda state: state.pokemon_rb_can_strength(player), one_way=True)
connect(world, player, "Viridian City", "Viridian City North", lambda state: state.has("Oak's Parcel", player) or state.multiworld.old_man[player].value == 2 or state.pokemon_rb_can_cut(player))
connect(world, player, "Route 3", "Mt Moon 1F", one_way=True)
connect(world, player, "Route 11", "Route 11 East", lambda state: state.pokemon_rb_can_strength(player))
connect(world, player, "Cinnabar Island", "Cinnabar Gym", lambda state: state.has("Secret Key", player), one_way=True)
connect(world, player, "Cinnabar Island", "Pokemon Mansion 1F", lambda state: state.has("Mansion Key", player) or not state.multiworld.extra_key_items[player].value, one_way=True)
connect(world, player, "Seafoam Islands 1F", "Seafoam Islands B1F", one_way=True)
connect(world, player, "Seafoam Islands B1F", "Seafoam Islands B2F", one_way=True)
connect(world, player, "Seafoam Islands B2F", "Seafoam Islands B3F", one_way=True)
connect(world, player, "Seafoam Islands B3F", "Seafoam Islands B4F", one_way=True)
connect(world, player, "Route 21", "Cinnabar Island", lambda state: state.pokemon_rb_can_surf(player))
connect(world, player, "Pallet Town", "Route 21", lambda state: state.pokemon_rb_can_surf(player))
connect(world, player, "Saffron City", "Silph Co 1F", lambda state: state.has("Fuji Saved", player), one_way=True)
connect(world, player, "Silph Co 1F", "Silph Co 2F", one_way=True)
connect(world, player, "Silph Co 2F", "Silph Co 3F", one_way=True)
connect(world, player, "Silph Co 3F", "Silph Co 4F", one_way=True)
connect(world, player, "Silph Co 4F", "Silph Co 5F", one_way=True)
connect(world, player, "Silph Co 5F", "Silph Co 6F", one_way=True)
connect(world, player, "Silph Co 6F", "Silph Co 7F", one_way=True)
connect(world, player, "Silph Co 7F", "Silph Co 8F", one_way=True)
connect(world, player, "Silph Co 8F", "Silph Co 9F", one_way=True)
connect(world, player, "Silph Co 9F", "Silph Co 10F", one_way=True)
connect(world, player, "Silph Co 10F", "Silph Co 11F", one_way=True)
connect(world, player, "Celadon City", "Rocket Hideout B1F", lambda state: state.has("Hideout Key", player) or not state.multiworld.extra_key_items[player].value, one_way=True)
connect(world, player, "Rocket Hideout B1F", "Rocket Hideout B2F", one_way=True)
connect(world, player, "Rocket Hideout B2F", "Rocket Hideout B3F", one_way=True)
connect(world, player, "Rocket Hideout B3F", "Rocket Hideout B4F", one_way=True)
connect(world, player, "Pokemon Mansion 1F", "Pokemon Mansion 2F", one_way=True)
connect(world, player, "Pokemon Mansion 2F", "Pokemon Mansion 3F", one_way=True)
connect(world, player, "Pokemon Mansion 1F", "Pokemon Mansion B1F", one_way=True)
connect(world, player, "Route 23", "Victory Road 1F", lambda state: state.pokemon_rb_can_strength(player), one_way=True)
connect(world, player, "Victory Road 1F", "Victory Road 2F", one_way=True)
connect(world, player, "Victory Road 2F", "Victory Road 3F", one_way=True)
connect(world, player, "Victory Road 2F", "Indigo Plateau", lambda state: state.pokemon_rb_has_badges(state.multiworld.elite_four_condition[player], player), one_way=True)
connect(world, player, "Cerulean City", "Cerulean Cave 1F", lambda state:
connect(multiworld, player, "Route 2", "Route 2 East", lambda state: state.pokemon_rb_can_cut(player))
connect(multiworld, player, "Route 2 East", "Diglett's Cave", lambda state: state.pokemon_rb_can_cut(player))
connect(multiworld, player, "Route 2", "Viridian City North")
connect(multiworld, player, "Route 2", "Viridian Forest")
connect(multiworld, player, "Route 2", "Pewter City")
connect(multiworld, player, "Pewter City", "Pewter Gym", one_way=True)
connect(multiworld, player, "Pewter City", "Route 3")
connect(multiworld, player, "Route 4", "Route 3", one_way=True)
connect(multiworld, player, "Mt Moon 1F", "Mt Moon B1F", one_way=True)
connect(multiworld, player, "Mt Moon B1F", "Mt Moon B2F", one_way=True)
connect(multiworld, player, "Mt Moon B1F", "Route 4", one_way=True)
connect(multiworld, player, "Route 4", "Cerulean City")
connect(multiworld, player, "Cerulean City", "Cerulean Gym", one_way=True)
connect(multiworld, player, "Cerulean City", "Route 24", one_way=True)
connect(multiworld, player, "Route 24", "Route 25", one_way=True)
connect(multiworld, player, "Cerulean City", "Route 9", lambda state: state.pokemon_rb_can_cut(player))
connect(multiworld, player, "Route 9", "Route 10 North")
connect(multiworld, player, "Route 10 North", "Rock Tunnel 1F", lambda state: state.pokemon_rb_can_flash(player))
connect(multiworld, player, "Route 10 North", "Power Plant", lambda state: state.pokemon_rb_can_surf(player) and
(state.has("Plant Key", player) or not state.multiworld.extra_key_items[player].value), one_way=True)
connect(multiworld, player, "Rock Tunnel 1F", "Route 10 South", lambda state: state.pokemon_rb_can_flash(player))
connect(multiworld, player, "Rock Tunnel 1F", "Rock Tunnel B1F")
connect(multiworld, player, "Lavender Town", "Pokemon Tower 1F", one_way=True)
connect(multiworld, player, "Lavender Town", "Pokemon Tower 1F", one_way=True)
connect(multiworld, player, "Pokemon Tower 1F", "Pokemon Tower 2F", one_way=True)
connect(multiworld, player, "Pokemon Tower 2F", "Pokemon Tower 3F", one_way=True)
connect(multiworld, player, "Pokemon Tower 3F", "Pokemon Tower 4F", one_way=True)
connect(multiworld, player, "Pokemon Tower 4F", "Pokemon Tower 5F", one_way=True)
connect(multiworld, player, "Pokemon Tower 5F", "Pokemon Tower 6F", one_way=True)
connect(multiworld, player, "Pokemon Tower 6F", "Pokemon Tower 7F", lambda state: state.has("Silph Scope", player))
connect(multiworld, player, "Cerulean City", "Route 5")
connect(multiworld, player, "Route 5", "Saffron City", lambda state: state.pokemon_rb_can_pass_guards(player))
connect(multiworld, player, "Saffron City", "Fighting Dojo", one_way=True)
connect(multiworld, player, "Route 5", "Underground Tunnel North-South")
connect(multiworld, player, "Route 6", "Underground Tunnel North-South")
connect(multiworld, player, "Route 6", "Saffron City", lambda state: state.pokemon_rb_can_pass_guards(player))
connect(multiworld, player, "Route 7", "Saffron City", lambda state: state.pokemon_rb_can_pass_guards(player))
connect(multiworld, player, "Route 8", "Saffron City", lambda state: state.pokemon_rb_can_pass_guards(player))
connect(multiworld, player, "Saffron City", "Copycat's House", lambda state: state.has("Silph Co Liberated", player), one_way=True)
connect(multiworld, player, "Saffron City", "Saffron Gym", lambda state: state.has("Silph Co Liberated", player), one_way=True)
connect(multiworld, player, "Route 6", "Vermilion City")
connect(multiworld, player, "Vermilion City", "Vermilion Gym", lambda state: state.pokemon_rb_can_surf(player) or state.pokemon_rb_can_cut(player), one_way=True)
connect(multiworld, player, "Vermilion City", "S.S. Anne 1F", lambda state: state.has("S.S. Ticket", player), one_way=True)
connect(multiworld, player, "S.S. Anne 1F", "S.S. Anne 2F", one_way=True)
connect(multiworld, player, "S.S. Anne 2F", "S.S. Anne 3F", one_way=True)
connect(multiworld, player, "S.S. Anne 1F", "S.S. Anne B1F", one_way=True)
connect(multiworld, player, "Vermilion City", "Route 11")
connect(multiworld, player, "Vermilion City", "Diglett's Cave")
connect(multiworld, player, "Route 12 West", "Route 11 East", lambda state: state.pokemon_rb_can_strength(player) or not state.multiworld.extra_strength_boulders[player].value)
connect(multiworld, player, "Route 12 North", "Route 12 South", lambda state: state.has("Poke Flute", player) or state.pokemon_rb_can_surf(player))
connect(multiworld, player, "Route 12 West", "Route 12 North", lambda state: state.has("Poke Flute", player))
connect(multiworld, player, "Route 12 West", "Route 12 South", lambda state: state.has("Poke Flute", player))
connect(multiworld, player, "Route 12 South", "Route 12 Grass", lambda state: state.pokemon_rb_can_cut(player))
connect(multiworld, player, "Route 12 North", "Lavender Town")
connect(multiworld, player, "Route 7", "Lavender Town")
connect(multiworld, player, "Route 10 South", "Lavender Town")
connect(multiworld, player, "Route 7", "Underground Tunnel West-East")
connect(multiworld, player, "Route 8", "Underground Tunnel West-East")
connect(multiworld, player, "Route 8", "Celadon City")
connect(multiworld, player, "Route 8", "Route 8 Grass", lambda state: state.pokemon_rb_can_cut(player), one_way=True)
connect(multiworld, player, "Route 7", "Celadon City")
connect(multiworld, player, "Celadon City", "Celadon Gym", lambda state: state.pokemon_rb_can_cut(player), one_way=True)
connect(multiworld, player, "Celadon City", "Celadon Prize Corner")
connect(multiworld, player, "Celadon City", "Route 16")
connect(multiworld, player, "Route 16", "Route 16 North", lambda state: state.pokemon_rb_can_cut(player), one_way=True)
connect(multiworld, player, "Route 16", "Route 16 West", lambda state: state.has("Poke Flute", player) and state.has("Bicycle", player))
connect(multiworld, player, "Route 17", "Route 16 West")
connect(multiworld, player, "Route 17", "Route 18", lambda state: state.has("Bicycle", player))
connect(multiworld, player, "Fuchsia City", "Fuchsia Gym", one_way=True)
connect(multiworld, player, "Fuchsia City", "Route 18")
connect(multiworld, player, "Fuchsia City", "Safari Zone Gate", one_way=True)
connect(multiworld, player, "Safari Zone Gate", "Safari Zone Center", lambda state: state.has("Safari Pass", player) or not state.multiworld.extra_key_items[player].value, one_way=True)
connect(multiworld, player, "Safari Zone Center", "Safari Zone East", one_way=True)
connect(multiworld, player, "Safari Zone Center", "Safari Zone West", one_way=True)
connect(multiworld, player, "Safari Zone Center", "Safari Zone North", one_way=True)
connect(multiworld, player, "Fuchsia City", "Route 15")
connect(multiworld, player, "Route 15", "Route 14")
connect(multiworld, player, "Route 14", "Route 14 Grass", lambda state: state.pokemon_rb_can_cut(player), one_way=True)
connect(multiworld, player, "Route 14", "Route 13")
connect(multiworld, player, "Route 13", "Route 13 East", lambda state: state.pokemon_rb_can_strength(player) or state.pokemon_rb_can_surf(player) or not state.multiworld.extra_strength_boulders[player].value)
connect(multiworld, player, "Route 12 South", "Route 13 East")
connect(multiworld, player, "Fuchsia City", "Route 19", lambda state: state.pokemon_rb_can_surf(player))
connect(multiworld, player, "Route 20 East", "Route 19")
connect(multiworld, player, "Route 20 West", "Cinnabar Island", lambda state: state.pokemon_rb_can_surf(player))
connect(multiworld, player, "Route 20 West", "Seafoam Islands 1F")
connect(multiworld, player, "Route 20 East", "Seafoam Islands 1F", one_way=True)
connect(multiworld, player, "Seafoam Islands 1F", "Route 20 East", lambda state: state.pokemon_rb_can_strength(player), one_way=True)
connect(multiworld, player, "Viridian City", "Viridian City North", lambda state: state.has("Oak's Parcel", player) or state.multiworld.old_man[player].value == 2 or state.pokemon_rb_can_cut(player))
connect(multiworld, player, "Route 3", "Mt Moon 1F", one_way=True)
connect(multiworld, player, "Route 11", "Route 11 East", lambda state: state.pokemon_rb_can_strength(player))
connect(multiworld, player, "Cinnabar Island", "Cinnabar Gym", lambda state: state.has("Secret Key", player), one_way=True)
connect(multiworld, player, "Cinnabar Island", "Pokemon Mansion 1F", lambda state: state.has("Mansion Key", player) or not state.multiworld.extra_key_items[player].value, one_way=True)
connect(multiworld, player, "Seafoam Islands 1F", "Seafoam Islands B1F", one_way=True)
connect(multiworld, player, "Seafoam Islands B1F", "Seafoam Islands B2F", one_way=True)
connect(multiworld, player, "Seafoam Islands B2F", "Seafoam Islands B3F", one_way=True)
connect(multiworld, player, "Seafoam Islands B3F", "Seafoam Islands B4F", one_way=True)
connect(multiworld, player, "Route 21", "Cinnabar Island", lambda state: state.pokemon_rb_can_surf(player))
connect(multiworld, player, "Pallet Town", "Route 21", lambda state: state.pokemon_rb_can_surf(player))
connect(multiworld, player, "Saffron City", "Silph Co 1F", lambda state: state.has("Fuji Saved", player), one_way=True)
connect(multiworld, player, "Silph Co 1F", "Silph Co 2F", one_way=True)
connect(multiworld, player, "Silph Co 2F", "Silph Co 3F", one_way=True)
connect(multiworld, player, "Silph Co 3F", "Silph Co 4F", one_way=True)
connect(multiworld, player, "Silph Co 4F", "Silph Co 5F", one_way=True)
connect(multiworld, player, "Silph Co 5F", "Silph Co 6F", one_way=True)
connect(multiworld, player, "Silph Co 6F", "Silph Co 7F", one_way=True)
connect(multiworld, player, "Silph Co 7F", "Silph Co 8F", one_way=True)
connect(multiworld, player, "Silph Co 8F", "Silph Co 9F", one_way=True)
connect(multiworld, player, "Silph Co 9F", "Silph Co 10F", one_way=True)
connect(multiworld, player, "Silph Co 10F", "Silph Co 11F", one_way=True)
connect(multiworld, player, "Celadon City", "Rocket Hideout B1F", lambda state: state.has("Hideout Key", player) or not state.multiworld.extra_key_items[player].value, one_way=True)
connect(multiworld, player, "Rocket Hideout B1F", "Rocket Hideout B2F", one_way=True)
connect(multiworld, player, "Rocket Hideout B2F", "Rocket Hideout B3F", one_way=True)
connect(multiworld, player, "Rocket Hideout B3F", "Rocket Hideout B4F", one_way=True)
connect(multiworld, player, "Pokemon Mansion 1F", "Pokemon Mansion 2F", one_way=True)
connect(multiworld, player, "Pokemon Mansion 2F", "Pokemon Mansion 3F", one_way=True)
connect(multiworld, player, "Pokemon Mansion 1F", "Pokemon Mansion B1F", one_way=True)
connect(multiworld, player, "Route 23", "Victory Road 1F", lambda state: state.pokemon_rb_can_strength(player), one_way=True)
connect(multiworld, player, "Victory Road 1F", "Victory Road 2F", one_way=True)
connect(multiworld, player, "Victory Road 2F", "Victory Road 3F", one_way=True)
connect(multiworld, player, "Victory Road 2F", "Indigo Plateau", lambda state: state.pokemon_rb_has_badges(state.multiworld.elite_four_condition[player], player), one_way=True)
connect(multiworld, player, "Cerulean City", "Cerulean Cave 1F", lambda state:
state.pokemon_rb_cerulean_cave(state.multiworld.cerulean_cave_condition[player].value + (state.multiworld.extra_key_items[player].value * 4), player) and
state.pokemon_rb_can_surf(player), one_way=True)
connect(world, player, "Cerulean Cave 1F", "Cerulean Cave 2F", one_way=True)
connect(world, player, "Cerulean Cave 1F", "Cerulean Cave B1F", lambda state: state.pokemon_rb_can_surf(player), one_way=True)
if world.worlds[player].fly_map != "Pallet Town":
connect(world, player, "Menu", world.worlds[player].fly_map, lambda state: state.pokemon_rb_can_fly(player), one_way=True,
name="Fly to " + world.worlds[player].fly_map)
connect(multiworld, player, "Cerulean Cave 1F", "Cerulean Cave 2F", one_way=True)
connect(multiworld, player, "Cerulean Cave 1F", "Cerulean Cave B1F", lambda state: state.pokemon_rb_can_surf(player), one_way=True)
if multiworld.worlds[player].fly_map != "Pallet Town":
connect(multiworld, player, "Menu", multiworld.worlds[player].fly_map, lambda state: state.pokemon_rb_can_fly(player), one_way=True,
name="Fly to " + multiworld.worlds[player].fly_map)
def connect(world: MultiWorld, player: int, source: str, target: str, rule: callable = lambda state: True, one_way=False, name=None):

View File

@ -7,6 +7,7 @@ from Patch import APDeltaPatch
from .text import encode_text
from .rom_addresses import rom_addresses
from .locations import location_data
from .items import item_table
import worlds.pokemon_rb.poke_data as poke_data
@ -386,6 +387,9 @@ def generate_output(self, output_directory: str):
data[rom_addresses["Guard_Drink_List"] + 1] = 0
data[rom_addresses["Guard_Drink_List"] + 2] = 0
data[rom_addresses["Fossils_Needed_For_Second_Item"]] = (
self.multiworld.second_fossil_check_condition[self.player].value)
if self.multiworld.extra_key_items[self.player].value:
data[rom_addresses['Options']] |= 4
data[rom_addresses["Option_Blind_Trainers"]] = round(self.multiworld.blind_trainers[self.player].value * 2.55)
@ -406,9 +410,7 @@ def generate_output(self, output_directory: str):
if self.multiworld.old_man[self.player].value == 2:
data[rom_addresses['Option_Old_Man']] = 0x11
data[rom_addresses['Option_Old_Man_Lying']] = 0x15
money = str(self.multiworld.starting_money[self.player].value)
while len(money) < 6:
money = "0" + money
money = str(self.multiworld.starting_money[self.player].value).zfill(6)
data[rom_addresses["Starting_Money_High"]] = int(money[:2], 16)
data[rom_addresses["Starting_Money_Middle"]] = int(money[2:4], 16)
data[rom_addresses["Starting_Money_Low"]] = int(money[4:], 16)
@ -417,6 +419,10 @@ def generate_output(self, output_directory: str):
data[rom_addresses["Text_Badges_Needed"]] = encode_text(
str(max(self.multiworld.victory_road_condition[self.player].value,
self.multiworld.elite_four_condition[self.player].value)))[0]
write_bytes(data, encode_text(
" ".join(self.multiworld.get_location("Route 3 - Pokemon For Sale", self.player).item.name.upper().split()[1:])),
rom_addresses["Text_Magikarp_Salesman"])
if self.multiworld.badges_needed_for_hm_moves[self.player].value == 0:
for hm_move in poke_data.hm_moves:
write_bytes(data, bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
@ -441,61 +447,80 @@ def generate_output(self, output_directory: str):
if badge not in written_badges:
write_bytes(data, encode_text("Nothing"), rom_addresses["Badge_Text_" + badge.replace(" ", "_")])
chart = deepcopy(poke_data.type_chart)
if self.multiworld.randomize_type_matchup_types[self.player].value == 1:
attacking_types = []
defending_types = []
for matchup in chart:
attacking_types.append(matchup[0])
defending_types.append(matchup[1])
random.shuffle(attacking_types)
random.shuffle(defending_types)
if self.multiworld.randomize_type_chart[self.player] == "vanilla":
chart = deepcopy(poke_data.type_chart)
elif self.multiworld.randomize_type_chart[self.player] == "randomize":
types = poke_data.type_names.values()
matchups = []
while len(attacking_types) > 0:
if [attacking_types[0], defending_types[0]] not in matchups:
matchups.append([attacking_types.pop(0), defending_types.pop(0)])
else:
matchup = matchups.pop(0)
attacking_types.append(matchup[0])
defending_types.append(matchup[1])
random.shuffle(attacking_types)
random.shuffle(defending_types)
for matchup, chart_row in zip(matchups, chart):
chart_row[0] = matchup[0]
chart_row[1] = matchup[1]
elif self.multiworld.randomize_type_matchup_types[self.player].value == 2:
used_matchups = []
for matchup in chart:
matchup[0] = random.choice(list(poke_data.type_names.values()))
matchup[1] = random.choice(list(poke_data.type_names.values()))
while [matchup[0], matchup[1]] in used_matchups:
matchup[0] = random.choice(list(poke_data.type_names.values()))
matchup[1] = random.choice(list(poke_data.type_names.values()))
used_matchups.append([matchup[0], matchup[1]])
if self.multiworld.randomize_type_matchup_type_effectiveness[self.player].value == 1:
effectiveness_list = []
for matchup in chart:
effectiveness_list.append(matchup[2])
random.shuffle(effectiveness_list)
for (matchup, effectiveness) in zip(chart, effectiveness_list):
matchup[2] = effectiveness
elif self.multiworld.randomize_type_matchup_type_effectiveness[self.player].value == 2:
for matchup in chart:
matchup[2] = random.choice([0] + ([5, 20] * 5))
elif self.multiworld.randomize_type_matchup_type_effectiveness[self.player].value == 3:
for matchup in chart:
matchup[2] = random.choice([i for i in range(0, 21) if i != 10])
type_loc = rom_addresses["Type_Chart"]
for matchup in chart:
data[type_loc] = poke_data.type_ids[matchup[0]]
data[type_loc + 1] = poke_data.type_ids[matchup[1]]
data[type_loc + 2] = matchup[2]
type_loc += 3
for type1 in types:
for type2 in types:
matchups.append([type1, type2])
self.multiworld.random.shuffle(matchups)
immunities = self.multiworld.immunity_matchups[self.player].value
super_effectives = self.multiworld.super_effective_matchups[self.player].value
not_very_effectives = self.multiworld.not_very_effective_matchups[self.player].value
normals = self.multiworld.normal_matchups[self.player].value
while super_effectives + not_very_effectives + normals < 225 - immunities:
super_effectives += self.multiworld.super_effective_matchups[self.player].value
not_very_effectives += self.multiworld.not_very_effective_matchups[self.player].value
normals += self.multiworld.normal_matchups[self.player].value
if super_effectives + not_very_effectives + normals > 225 - immunities:
total = super_effectives + not_very_effectives + normals
excess = total - (225 - immunities)
subtract_amounts = (int((excess / (super_effectives + not_very_effectives + normals)) * super_effectives),
int((excess / (super_effectives + not_very_effectives + normals)) * not_very_effectives),
int((excess / (super_effectives + not_very_effectives + normals)) * normals))
super_effectives -= subtract_amounts[0]
not_very_effectives -= subtract_amounts[1]
normals -= subtract_amounts[2]
while super_effectives + not_very_effectives + normals > 225 - immunities:
r = self.multiworld.random.randint(0, 2)
if r == 0:
super_effectives -= 1
elif r == 1:
not_very_effectives -= 1
else:
normals -= 1
chart = []
for matchup_list, matchup_value in zip([immunities, normals, super_effectives, not_very_effectives],
[0, 10, 20, 5]):
for _ in range(matchup_list):
matchup = matchups.pop()
matchup.append(matchup_value)
chart.append(matchup)
elif self.multiworld.randomize_type_chart[self.player] == "chaos":
types = poke_data.type_names.values()
matchups = []
for type1 in types:
for type2 in types:
matchups.append([type1, type2])
chart = []
values = list(range(21))
self.multiworld.random.shuffle(matchups)
self.multiworld.random.shuffle(values)
for matchup in matchups:
value = values.pop(0)
values.append(value)
matchup.append(value)
chart.append(matchup)
# sort so that super-effective matchups occur first, to prevent dual "not very effective" / "super effective"
# matchups from leading to damage being ultimately divided by 2 and then multiplied by 2, which can lead to
# damage being reduced by 1 which leads to a "not very effective" message appearing due to my changes
# to the way effectiveness messages are generated.
self.type_chart = sorted(chart, key=lambda matchup: 0 - matchup[2])
chart = sorted(chart, key=lambda matchup: -matchup[2])
type_loc = rom_addresses["Type_Chart"]
for matchup in chart:
if matchup[2] != 10: # don't needlessly divide damage by 10 and multiply by 10
data[type_loc] = poke_data.type_ids[matchup[0]]
data[type_loc + 1] = poke_data.type_ids[matchup[1]]
data[type_loc + 2] = matchup[2]
type_loc += 3
data[type_loc] = 0xFF
data[type_loc + 1] = 0xFF
data[type_loc + 2] = 0xFF
self.type_chart = chart
if self.multiworld.normalize_encounter_chances[self.player].value:
chances = [25, 51, 77, 103, 129, 155, 180, 205, 230, 255]
@ -525,9 +550,9 @@ def generate_output(self, output_directory: str):
for i, move in enumerate(self.learnsets[mon]):
data[(address + 1) + i * 2] = poke_data.moves[move]["id"]
data[rom_addresses["Option_Aide_Rt2"]] = self.multiworld.oaks_aide_rt_2[self.player]
data[rom_addresses["Option_Aide_Rt11"]] = self.multiworld.oaks_aide_rt_11[self.player]
data[rom_addresses["Option_Aide_Rt15"]] = self.multiworld.oaks_aide_rt_15[self.player]
data[rom_addresses["Option_Aide_Rt2"]] = self.multiworld.oaks_aide_rt_2[self.player].value
data[rom_addresses["Option_Aide_Rt11"]] = self.multiworld.oaks_aide_rt_11[self.player].value
data[rom_addresses["Option_Aide_Rt15"]] = self.multiworld.oaks_aide_rt_15[self.player].value
if self.multiworld.safari_zone_normal_battles[self.player].value == 1:
data[rom_addresses["Option_Safari_Zone_Battle_Type"]] = 255
@ -535,6 +560,31 @@ def generate_output(self, output_directory: str):
if self.multiworld.reusable_tms[self.player].value:
data[rom_addresses["Option_Reusable_TMs"]] = 0xC9
data[rom_addresses["Option_Trainersanity"]] = self.multiworld.trainersanity[self.player].value
data[rom_addresses["Option_Trainersanity2"]] = self.multiworld.trainersanity[self.player].value
data[rom_addresses["Option_Always_Half_STAB"]] = int(not self.multiworld.same_type_attack_bonus[self.player].value)
if self.multiworld.better_shops[self.player].value:
inventory = ["Poke Ball", "Great Ball", "Ultra Ball"]
if self.multiworld.better_shops[self.player].value == 2:
inventory.append("Master Ball")
inventory += ["Potion", "Super Potion", "Hyper Potion", "Max Potion", "Full Restore", "Antidote", "Awakening",
"Burn Heal", "Ice Heal", "Paralyze Heal", "Full Heal", "Repel", "Super Repel", "Max Repel",
"Escape Rope"]
shop_data = bytearray([0xFE, len(inventory)])
shop_data += bytearray([item_table[item].id - 172000000 for item in inventory])
shop_data.append(0xFF)
for shop in range(1, 10):
write_bytes(data, shop_data, rom_addresses[f"Shop{shop}"])
price = str(self.multiworld.master_ball_price[self.player].value).zfill(6)
price = bytearray([int(price[:2], 16), int(price[2:4], 16), int(price[4:], 16)])
write_bytes(data, price, rom_addresses["Price_Master_Ball"]) # Money values in Red and Blue are weird
for item in reversed(self.multiworld.precollected_items[self.player]):
if data[rom_addresses["Start_Inventory"] + item.code - 172000000] < 255:
data[rom_addresses["Start_Inventory"] + item.code - 172000000] += 1
process_trainer_data(self, data)
mons = [mon["id"] for mon in poke_data.pokemon_data.values()]
@ -558,9 +608,16 @@ def generate_output(self, output_directory: str):
slot_name.replace(">", " ")
write_bytes(data, encode_text(slot_name, 16, True, True), rom_addresses['Title_Slot_Name'])
write_bytes(data, self.trainer_name, rom_addresses['Player_Name'])
write_bytes(data, self.rival_name, rom_addresses['Rival_Name'])
if self.trainer_name == "choose_in_game":
data[rom_addresses["Skip_Player_Name"]] = 0
else:
write_bytes(data, self.trainer_name, rom_addresses['Player_Name'])
if self.rival_name == "choose_in_game":
data[rom_addresses["Skip_Rival_Name"]] = 0
else:
write_bytes(data, self.rival_name, rom_addresses['Rival_Name'])
data[0xFF00] = 1 # client compatibility version
write_bytes(data, self.multiworld.seed_name.encode(), 0xFFDB)
write_bytes(data, self.multiworld.player_name[self.player].encode(), 0xFFF0)

File diff suppressed because it is too large Load Diff

View File

@ -3,25 +3,27 @@ from ..generic.Rules import add_item_rule, add_rule
def set_rules(world, player):
add_item_rule(world.get_location("Pallet Town - Player's PC", player),
lambda i: i.player == player and "Badge" not in i.name)
lambda i: i.player == player and "Badge" not in i.name and "Trap" not in i.name and
i.name != "Pokedex")
access_rules = {
"Pallet Town - Rival's Sister": lambda state: state.has("Oak's Parcel", player),
"Pallet Town - Oak's Post-Route-22-Rival Gift": lambda state: state.has("Oak's Parcel", player),
"Viridian City - Sleepy Guy": lambda state: state.pokemon_rb_can_cut(player) or state.pokemon_rb_can_surf(player),
"Route 2 - Oak's Aide": lambda state: state.pokemon_rb_has_pokemon(state.multiworld.oaks_aide_rt_2[player].value + 5, player),
"Route 2 - Oak's Aide": lambda state: state.pokemon_rb_oaks_aide(state.multiworld.oaks_aide_rt_2[player].value + 5, player),
"Pewter City - Museum": lambda state: state.pokemon_rb_can_cut(player),
"Cerulean City - Bicycle Shop": lambda state: state.has("Bike Voucher", player),
"Lavender Town - Mr. Fuji": lambda state: state.has("Fuji Saved", player),
"Vermilion Gym - Lt. Surge 1": lambda state: state.pokemon_rb_can_cut(player or state.pokemon_rb_can_surf(player)),
"Vermilion Gym - Lt. Surge 2": lambda state: state.pokemon_rb_can_cut(player or state.pokemon_rb_can_surf(player)),
"Route 11 - Oak's Aide": lambda state: state.pokemon_rb_has_pokemon(state.multiworld.oaks_aide_rt_11[player].value + 5, player),
"Route 11 - Oak's Aide": lambda state: state.pokemon_rb_oaks_aide(state.multiworld.oaks_aide_rt_11[player].value + 5, player),
"Celadon City - Stranded Man": lambda state: state.pokemon_rb_can_surf(player),
"Silph Co 11F - Silph Co President": lambda state: state.has("Card Key", player),
"Fuchsia City - Safari Zone Warden": lambda state: state.has("Gold Teeth", player),
"Route 12 - Island Item": lambda state: state.pokemon_rb_can_surf(player),
"Route 12 - Item Behind Cuttable Tree": lambda state: state.pokemon_rb_can_cut(player),
"Route 15 - Oak's Aide": lambda state: state.pokemon_rb_oaks_aide(state.multiworld.oaks_aide_rt_15[player].value + 5, player),
"Route 15 - Item": lambda state: state.pokemon_rb_can_cut(player),
"Route 25 - Item": lambda state: state.pokemon_rb_can_cut(player),
"Fuchsia City - Warden's House Item": lambda state: state.pokemon_rb_can_strength(player),
@ -85,10 +87,23 @@ def set_rules(world, player):
"Route 12 - Sleeping Pokemon": lambda state: state.has("Poke Flute", player),
"Route 16 - Sleeping Pokemon": lambda state: state.has("Poke Flute", player),
"Seafoam Islands B4F - Legendary Pokemon": lambda state: state.pokemon_rb_can_strength(player),
"Vermilion City - Legendary Pokemon": lambda state: state.pokemon_rb_can_surf(player) and state.has("S.S. Ticket", player)
}
"Vermilion City - Legendary Pokemon": lambda state: state.pokemon_rb_can_surf(player) and state.has("S.S. Ticket", player),
hidden_item_access_rules = {
# Pokédex check
"Pallet Town - Oak's Parcel Reward": lambda state: state.has("Oak's Parcel", player),
# trainers
"Route 4 - Cooltrainer F": lambda state: state.pokemon_rb_can_surf(player),
"Route 15 - Jr. Trainer F 1": lambda state: state.pokemon_rb_can_cut(player),
"Silph Co 11F - Rocket 2 (Card Key)": lambda state: state.has("Card Key", player),
"Silph Co 9F - Rocket 2 (Card Key)": lambda state: state.has("Card Key", player),
"Silph Co 3F - Scientist (Card Key)": lambda state: state.has("Card Key", player),
"Route 10 North - Pokemaniac": lambda state: state.pokemon_rb_can_surf(player),
"Rocket Hideout B1F - Rocket 5 (Lift Key)": lambda state: state.has("Lift Key", player),
"Rocket Hideout B4F - Rocket 2 (Lift Key)": lambda state: state.has("Lift Key", player),
"Rocket Hideout B4F - Rocket 3 (Lift Key)": lambda state: state.has("Lift Key", player),
# hidden items
"Viridian Forest - Hidden Item Northwest by Trainer": lambda state: state.pokemon_rb_can_get_hidden_items(
player),
"Viridian Forest - Hidden Item Entrance Tree": lambda state: state.pokemon_rb_can_get_hidden_items(player),
@ -159,8 +174,6 @@ def set_rules(world, player):
player),
"Route 4 - Hidden Item Plateau East Of Mt Moon": lambda state: state.pokemon_rb_can_get_hidden_items(player),
}
for loc, rule in access_rules.items():
add_rule(world.get_location(loc, player), rule)
if world.randomize_hidden_items[player].value != 0:
for loc, rule in hidden_item_access_rules.items():
add_rule(world.get_location(loc, player), rule)
for loc in world.get_locations(player):
if loc.name in access_rules:
add_rule(loc, access_rules[loc.name])