Pokémon Red and Blue: 0.4.5 Fixes (#3106)
This commit is contained in:
parent
1fc2c5ed4b
commit
7e660dbd23
|
@ -18,7 +18,7 @@ from .options import pokemon_rb_options
|
||||||
from .rom_addresses import rom_addresses
|
from .rom_addresses import rom_addresses
|
||||||
from .text import encode_text
|
from .text import encode_text
|
||||||
from .rom import generate_output, get_base_rom_bytes, get_base_rom_path, RedDeltaPatch, BlueDeltaPatch
|
from .rom import generate_output, get_base_rom_bytes, get_base_rom_path, RedDeltaPatch, BlueDeltaPatch
|
||||||
from .pokemon import process_pokemon_data, process_move_data
|
from .pokemon import process_pokemon_data, process_move_data, verify_hm_moves
|
||||||
from .encounters import process_pokemon_locations, process_trainer_data
|
from .encounters import process_pokemon_locations, process_trainer_data
|
||||||
from .rules import set_rules
|
from .rules import set_rules
|
||||||
from .level_scaling import level_scaling
|
from .level_scaling import level_scaling
|
||||||
|
@ -279,12 +279,12 @@ class PokemonRedBlueWorld(World):
|
||||||
def fill_hook(self, progitempool, usefulitempool, filleritempool, fill_locations):
|
def fill_hook(self, progitempool, usefulitempool, filleritempool, fill_locations):
|
||||||
if not self.multiworld.badgesanity[self.player]:
|
if not self.multiworld.badgesanity[self.player]:
|
||||||
# Door Shuffle options besides Simple place badges during door shuffling
|
# Door Shuffle options besides Simple place badges during door shuffling
|
||||||
if not self.multiworld.door_shuffle[self.player] not in ("off", "simple"):
|
if self.multiworld.door_shuffle[self.player] in ("off", "simple"):
|
||||||
badges = [item for item in progitempool if "Badge" in item.name and item.player == self.player]
|
badges = [item for item in progitempool if "Badge" in item.name and item.player == self.player]
|
||||||
for badge in badges:
|
for badge in badges:
|
||||||
self.multiworld.itempool.remove(badge)
|
self.multiworld.itempool.remove(badge)
|
||||||
progitempool.remove(badge)
|
progitempool.remove(badge)
|
||||||
for _ in range(5):
|
for attempt in range(6):
|
||||||
badgelocs = [
|
badgelocs = [
|
||||||
self.multiworld.get_location(loc, self.player) for loc in [
|
self.multiworld.get_location(loc, self.player) for loc in [
|
||||||
"Pewter Gym - Brock Prize", "Cerulean Gym - Misty Prize",
|
"Pewter Gym - Brock Prize", "Cerulean Gym - Misty Prize",
|
||||||
|
@ -293,6 +293,12 @@ class PokemonRedBlueWorld(World):
|
||||||
"Cinnabar Gym - Blaine Prize", "Viridian Gym - Giovanni Prize"
|
"Cinnabar Gym - Blaine Prize", "Viridian Gym - Giovanni Prize"
|
||||||
] if self.multiworld.get_location(loc, self.player).item is None]
|
] if self.multiworld.get_location(loc, self.player).item is None]
|
||||||
state = self.multiworld.get_all_state(False)
|
state = self.multiworld.get_all_state(False)
|
||||||
|
# Give it two tries to place badges with wild Pokemon and learnsets as-is.
|
||||||
|
# If it can't, then try with all Pokemon collected, and we'll try to fix HM move availability after.
|
||||||
|
if attempt > 1:
|
||||||
|
for mon in poke_data.pokemon_data.keys():
|
||||||
|
state.collect(self.create_item(mon), True)
|
||||||
|
state.sweep_for_events()
|
||||||
self.multiworld.random.shuffle(badges)
|
self.multiworld.random.shuffle(badges)
|
||||||
self.multiworld.random.shuffle(badgelocs)
|
self.multiworld.random.shuffle(badgelocs)
|
||||||
badgelocs_copy = badgelocs.copy()
|
badgelocs_copy = badgelocs.copy()
|
||||||
|
@ -312,6 +318,7 @@ class PokemonRedBlueWorld(World):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise FillError(f"Failed to place badges for player {self.player}")
|
raise FillError(f"Failed to place badges for player {self.player}")
|
||||||
|
verify_hm_moves(self.multiworld, self, self.player)
|
||||||
|
|
||||||
if self.multiworld.key_items_only[self.player]:
|
if self.multiworld.key_items_only[self.player]:
|
||||||
return
|
return
|
||||||
|
@ -355,97 +362,14 @@ class PokemonRedBlueWorld(World):
|
||||||
for location in self.multiworld.get_locations(self.player):
|
for location in self.multiworld.get_locations(self.player):
|
||||||
if location.name in locs:
|
if location.name in locs:
|
||||||
location.show_in_spoiler = False
|
location.show_in_spoiler = False
|
||||||
|
verify_hm_moves(self.multiworld, self, self.player)
|
||||||
def intervene(move, test_state):
|
|
||||||
move_bit = pow(2, poke_data.hm_moves.index(move) + 2)
|
|
||||||
viable_mons = [mon for mon in self.local_poke_data if self.local_poke_data[mon]["tms"][6] & move_bit]
|
|
||||||
if self.multiworld.randomize_wild_pokemon[self.player] and viable_mons:
|
|
||||||
accessible_slots = [loc for loc in self.multiworld.get_reachable_locations(test_state, self.player) if
|
|
||||||
loc.type == "Wild Encounter"]
|
|
||||||
|
|
||||||
def number_of_zones(mon):
|
|
||||||
zones = set()
|
|
||||||
for loc in [slot for slot in accessible_slots if slot.item.name == mon]:
|
|
||||||
zones.add(loc.name.split(" - ")[0])
|
|
||||||
return len(zones)
|
|
||||||
|
|
||||||
placed_mons = [slot.item.name for slot in accessible_slots]
|
|
||||||
|
|
||||||
if self.multiworld.area_1_to_1_mapping[self.player]:
|
|
||||||
placed_mons.sort(key=lambda i: number_of_zones(i))
|
|
||||||
else:
|
|
||||||
# this sort method doesn't work if you reference the same list being sorted in the lambda
|
|
||||||
placed_mons_copy = placed_mons.copy()
|
|
||||||
placed_mons.sort(key=lambda i: placed_mons_copy.count(i))
|
|
||||||
|
|
||||||
placed_mon = placed_mons.pop()
|
|
||||||
replace_mon = self.multiworld.random.choice(viable_mons)
|
|
||||||
replace_slot = self.multiworld.random.choice([slot for slot in accessible_slots if slot.item.name
|
|
||||||
== placed_mon])
|
|
||||||
if self.multiworld.area_1_to_1_mapping[self.player]:
|
|
||||||
zone = " - ".join(replace_slot.name.split(" - ")[:-1])
|
|
||||||
replace_slots = [slot for slot in accessible_slots if slot.name.startswith(zone) and slot.item.name
|
|
||||||
== placed_mon]
|
|
||||||
for replace_slot in replace_slots:
|
|
||||||
replace_slot.item = self.create_item(replace_mon)
|
|
||||||
else:
|
|
||||||
replace_slot.item = self.create_item(replace_mon)
|
|
||||||
else:
|
|
||||||
tms_hms = self.local_tms + poke_data.hm_moves
|
|
||||||
flag = tms_hms.index(move)
|
|
||||||
mon_list = [mon for mon in poke_data.pokemon_data.keys() if test_state.has(mon, self.player)]
|
|
||||||
self.multiworld.random.shuffle(mon_list)
|
|
||||||
mon_list.sort(key=lambda mon: self.local_move_data[move]["type"] not in
|
|
||||||
[self.local_poke_data[mon]["type1"], self.local_poke_data[mon]["type2"]])
|
|
||||||
for mon in mon_list:
|
|
||||||
if test_state.has(mon, self.player):
|
|
||||||
self.local_poke_data[mon]["tms"][int(flag / 8)] |= 1 << (flag % 8)
|
|
||||||
break
|
|
||||||
|
|
||||||
last_intervene = None
|
|
||||||
while True:
|
|
||||||
intervene_move = None
|
|
||||||
test_state = self.multiworld.get_all_state(False)
|
|
||||||
if not logic.can_learn_hm(test_state, "Surf", self.player):
|
|
||||||
intervene_move = "Surf"
|
|
||||||
elif not logic.can_learn_hm(test_state, "Strength", self.player):
|
|
||||||
intervene_move = "Strength"
|
|
||||||
# cut may not be needed if accessibility is minimal, unless you need all 8 badges and badgesanity is off,
|
|
||||||
# as you will require cut to access celadon gyn
|
|
||||||
elif ((not logic.can_learn_hm(test_state, "Cut", self.player)) and
|
|
||||||
(self.multiworld.accessibility[self.player] != "minimal" or ((not
|
|
||||||
self.multiworld.badgesanity[self.player]) and max(
|
|
||||||
self.multiworld.elite_four_badges_condition[self.player],
|
|
||||||
self.multiworld.route_22_gate_condition[self.player],
|
|
||||||
self.multiworld.victory_road_condition[self.player])
|
|
||||||
> 7) or (self.multiworld.door_shuffle[self.player] not in ("off", "simple")))):
|
|
||||||
intervene_move = "Cut"
|
|
||||||
elif ((not logic.can_learn_hm(test_state, "Flash", self.player))
|
|
||||||
and self.multiworld.dark_rock_tunnel_logic[self.player]
|
|
||||||
and (self.multiworld.accessibility[self.player] != "minimal"
|
|
||||||
or self.multiworld.door_shuffle[self.player])):
|
|
||||||
intervene_move = "Flash"
|
|
||||||
# If no Pokémon can learn Fly, then during door shuffle it would simply not treat the free fly maps
|
|
||||||
# as reachable, and if on no door shuffle or simple, fly is simply never necessary.
|
|
||||||
# We only intervene if a Pokémon is able to learn fly but none are reachable, as that would have been
|
|
||||||
# considered in door shuffle.
|
|
||||||
elif ((not logic.can_learn_hm(test_state, "Fly", self.player))
|
|
||||||
and self.multiworld.door_shuffle[self.player] not in
|
|
||||||
("off", "simple") and [self.fly_map, self.town_map_fly_map] != ["Pallet Town", "Pallet Town"]):
|
|
||||||
intervene_move = "Fly"
|
|
||||||
if intervene_move:
|
|
||||||
if intervene_move == last_intervene:
|
|
||||||
raise Exception(f"Caught in infinite loop attempting to ensure {intervene_move} is available to player {self.player}")
|
|
||||||
intervene(intervene_move, test_state)
|
|
||||||
last_intervene = intervene_move
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
# Delete evolution events for Pokémon that are not in logic in an all_state so that accessibility check does not
|
# Delete evolution events for Pokémon that are not in logic in an all_state so that accessibility check does not
|
||||||
# fail. Re-use test_state from previous final loop.
|
# fail. Re-use test_state from previous final loop.
|
||||||
|
all_state = self.multiworld.get_all_state(False)
|
||||||
evolutions_region = self.multiworld.get_region("Evolution", self.player)
|
evolutions_region = self.multiworld.get_region("Evolution", self.player)
|
||||||
for location in evolutions_region.locations.copy():
|
for location in evolutions_region.locations.copy():
|
||||||
if not test_state.can_reach(location, player=self.player):
|
if not all_state.can_reach(location, player=self.player):
|
||||||
evolutions_region.locations.remove(location)
|
evolutions_region.locations.remove(location)
|
||||||
|
|
||||||
if self.multiworld.old_man[self.player] == "early_parcel":
|
if self.multiworld.old_man[self.player] == "early_parcel":
|
||||||
|
|
|
@ -31,7 +31,7 @@ DATA_LOCATIONS = {
|
||||||
"CrashCheck2": (0x1617, 1),
|
"CrashCheck2": (0x1617, 1),
|
||||||
# Progressive keys, should never be above 10. Just before Dexsanity flags.
|
# Progressive keys, should never be above 10. Just before Dexsanity flags.
|
||||||
"CrashCheck3": (0x1A70, 1),
|
"CrashCheck3": (0x1A70, 1),
|
||||||
# Route 18 script value. Should never be above 2. Just before Hidden items flags.
|
# Route 18 Gate script value. Should never be above 3. Just before Hidden items flags.
|
||||||
"CrashCheck4": (0x16DD, 1),
|
"CrashCheck4": (0x16DD, 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ class PokemonRBClient(BizHawkClient):
|
||||||
or data["CrashCheck1"][0] & 0xF0 or data["CrashCheck1"][1] & 0xFF
|
or data["CrashCheck1"][0] & 0xF0 or data["CrashCheck1"][1] & 0xFF
|
||||||
or data["CrashCheck2"][0]
|
or data["CrashCheck2"][0]
|
||||||
or data["CrashCheck3"][0] > 10
|
or data["CrashCheck3"][0] > 10
|
||||||
or data["CrashCheck4"][0] > 2):
|
or data["CrashCheck4"][0] > 3):
|
||||||
# Should mean game crashed
|
# Should mean game crashed
|
||||||
logger.warning("Pokémon Red/Blue game may have crashed. Disconnecting from server.")
|
logger.warning("Pokémon Red/Blue game may have crashed. Disconnecting from server.")
|
||||||
self.game_state = False
|
self.game_state = False
|
||||||
|
|
|
@ -175,7 +175,7 @@ location_data = [
|
||||||
LocationData("Route 2-SE", "South Item", "Moon Stone", rom_addresses["Missable_Route_2_Item_1"],
|
LocationData("Route 2-SE", "South Item", "Moon Stone", rom_addresses["Missable_Route_2_Item_1"],
|
||||||
Missable(25)),
|
Missable(25)),
|
||||||
LocationData("Route 2-SE", "North Item", "HP Up", rom_addresses["Missable_Route_2_Item_2"], Missable(26)),
|
LocationData("Route 2-SE", "North Item", "HP Up", rom_addresses["Missable_Route_2_Item_2"], Missable(26)),
|
||||||
LocationData("Route 4-E", "Item", "TM04 Whirlwind", rom_addresses["Missable_Route_4_Item"], Missable(27)),
|
LocationData("Route 4-C", "Item", "TM04 Whirlwind", rom_addresses["Missable_Route_4_Item"], Missable(27)),
|
||||||
LocationData("Route 9", "Item", "TM30 Teleport", rom_addresses["Missable_Route_9_Item"], Missable(28)),
|
LocationData("Route 9", "Item", "TM30 Teleport", rom_addresses["Missable_Route_9_Item"], Missable(28)),
|
||||||
LocationData("Route 12-N", "Island Item", "TM16 Pay Day", rom_addresses["Missable_Route_12_Item_1"], Missable(30)),
|
LocationData("Route 12-N", "Island Item", "TM16 Pay Day", rom_addresses["Missable_Route_12_Item_1"], Missable(30)),
|
||||||
LocationData("Route 12-Grass", "Item Behind Cuttable Tree", "Iron", rom_addresses["Missable_Route_12_Item_2"], Missable(31)),
|
LocationData("Route 12-Grass", "Item Behind Cuttable Tree", "Iron", rom_addresses["Missable_Route_12_Item_2"], Missable(31)),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from . import poke_data
|
from . import poke_data, logic
|
||||||
from .rom_addresses import rom_addresses
|
from .rom_addresses import rom_addresses
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,7 +135,6 @@ def process_pokemon_data(self):
|
||||||
learnsets = deepcopy(poke_data.learnsets)
|
learnsets = deepcopy(poke_data.learnsets)
|
||||||
tms_hms = self.local_tms + poke_data.hm_moves
|
tms_hms = self.local_tms + poke_data.hm_moves
|
||||||
|
|
||||||
|
|
||||||
compat_hms = set()
|
compat_hms = set()
|
||||||
|
|
||||||
for mon, mon_data in local_poke_data.items():
|
for mon, mon_data in local_poke_data.items():
|
||||||
|
@ -323,19 +322,20 @@ def process_pokemon_data(self):
|
||||||
mon_data["tms"][int(flag / 8)] &= ~(1 << (flag % 8))
|
mon_data["tms"][int(flag / 8)] &= ~(1 << (flag % 8))
|
||||||
|
|
||||||
hm_verify = ["Surf", "Strength"]
|
hm_verify = ["Surf", "Strength"]
|
||||||
if self.multiworld.accessibility[self.player] == "locations" or ((not
|
if self.multiworld.accessibility[self.player] != "minimal" or ((not
|
||||||
self.multiworld.badgesanity[self.player]) and max(self.multiworld.elite_four_badges_condition[self.player],
|
self.multiworld.badgesanity[self.player]) and max(self.multiworld.elite_four_badges_condition[self.player],
|
||||||
self.multiworld.route_22_gate_condition[self.player], self.multiworld.victory_road_condition[self.player])
|
self.multiworld.route_22_gate_condition[self.player], self.multiworld.victory_road_condition[self.player])
|
||||||
> 7) or (self.multiworld.door_shuffle[self.player] not in ("off", "simple")):
|
> 7) or (self.multiworld.door_shuffle[self.player] not in ("off", "simple")):
|
||||||
hm_verify += ["Cut"]
|
hm_verify += ["Cut"]
|
||||||
if self.multiworld.accessibility[self.player] == "locations" or (not
|
if self.multiworld.accessibility[self.player] != "minimal" or (not
|
||||||
self.multiworld.dark_rock_tunnel_logic[self.player]) and ((self.multiworld.trainersanity[self.player] or
|
self.multiworld.dark_rock_tunnel_logic[self.player]) and ((self.multiworld.trainersanity[self.player] or
|
||||||
self.multiworld.extra_key_items[self.player])
|
self.multiworld.extra_key_items[self.player])
|
||||||
or self.multiworld.door_shuffle[self.player]):
|
or self.multiworld.door_shuffle[self.player]):
|
||||||
hm_verify += ["Flash"]
|
hm_verify += ["Flash"]
|
||||||
# Fly does not need to be verified. Full/Insanity door shuffle connects reachable regions to unreachable regions,
|
# Fly does not need to be verified. Full/Insanity/Decoupled door shuffle connects reachable regions to unreachable
|
||||||
# so if Fly is available and can be learned, the towns you can fly to would be reachable, but if no Pokémon can
|
# regions, so if Fly is available and can be learned, the towns you can fly to would be considered reachable for
|
||||||
# learn it this simply would not occur
|
# door shuffle purposes, but if no Pokémon can learn it, that connection would just be out of logic and it would
|
||||||
|
# ensure connections to those towns.
|
||||||
|
|
||||||
for hm_move in hm_verify:
|
for hm_move in hm_verify:
|
||||||
if hm_move not in compat_hms:
|
if hm_move not in compat_hms:
|
||||||
|
@ -346,3 +346,90 @@ def process_pokemon_data(self):
|
||||||
|
|
||||||
self.local_poke_data = local_poke_data
|
self.local_poke_data = local_poke_data
|
||||||
self.learnsets = learnsets
|
self.learnsets = learnsets
|
||||||
|
|
||||||
|
|
||||||
|
def verify_hm_moves(multiworld, world, player):
|
||||||
|
def intervene(move, test_state):
|
||||||
|
move_bit = pow(2, poke_data.hm_moves.index(move) + 2)
|
||||||
|
viable_mons = [mon for mon in world.local_poke_data if world.local_poke_data[mon]["tms"][6] & move_bit]
|
||||||
|
if multiworld.randomize_wild_pokemon[player] and viable_mons:
|
||||||
|
accessible_slots = [loc for loc in multiworld.get_reachable_locations(test_state, player) if
|
||||||
|
loc.type == "Wild Encounter"]
|
||||||
|
|
||||||
|
def number_of_zones(mon):
|
||||||
|
zones = set()
|
||||||
|
for loc in [slot for slot in accessible_slots if slot.item.name == mon]:
|
||||||
|
zones.add(loc.name.split(" - ")[0])
|
||||||
|
return len(zones)
|
||||||
|
|
||||||
|
placed_mons = [slot.item.name for slot in accessible_slots]
|
||||||
|
|
||||||
|
if multiworld.area_1_to_1_mapping[player]:
|
||||||
|
placed_mons.sort(key=lambda i: number_of_zones(i))
|
||||||
|
else:
|
||||||
|
# this sort method doesn't work if you reference the same list being sorted in the lambda
|
||||||
|
placed_mons_copy = placed_mons.copy()
|
||||||
|
placed_mons.sort(key=lambda i: placed_mons_copy.count(i))
|
||||||
|
|
||||||
|
placed_mon = placed_mons.pop()
|
||||||
|
replace_mon = multiworld.random.choice(viable_mons)
|
||||||
|
replace_slot = multiworld.random.choice([slot for slot in accessible_slots if slot.item.name
|
||||||
|
== placed_mon])
|
||||||
|
if multiworld.area_1_to_1_mapping[player]:
|
||||||
|
zone = " - ".join(replace_slot.name.split(" - ")[:-1])
|
||||||
|
replace_slots = [slot for slot in accessible_slots if slot.name.startswith(zone) and slot.item.name
|
||||||
|
== placed_mon]
|
||||||
|
for replace_slot in replace_slots:
|
||||||
|
replace_slot.item = world.create_item(replace_mon)
|
||||||
|
else:
|
||||||
|
replace_slot.item = world.create_item(replace_mon)
|
||||||
|
else:
|
||||||
|
tms_hms = world.local_tms + poke_data.hm_moves
|
||||||
|
flag = tms_hms.index(move)
|
||||||
|
mon_list = [mon for mon in poke_data.pokemon_data.keys() if test_state.has(mon, player)]
|
||||||
|
multiworld.random.shuffle(mon_list)
|
||||||
|
mon_list.sort(key=lambda mon: world.local_move_data[move]["type"] not in
|
||||||
|
[world.local_poke_data[mon]["type1"], world.local_poke_data[mon]["type2"]])
|
||||||
|
for mon in mon_list:
|
||||||
|
if test_state.has(mon, player):
|
||||||
|
world.local_poke_data[mon]["tms"][int(flag / 8)] |= 1 << (flag % 8)
|
||||||
|
break
|
||||||
|
|
||||||
|
last_intervene = None
|
||||||
|
while True:
|
||||||
|
intervene_move = None
|
||||||
|
test_state = multiworld.get_all_state(False)
|
||||||
|
if not logic.can_learn_hm(test_state, "Surf", player):
|
||||||
|
intervene_move = "Surf"
|
||||||
|
elif not logic.can_learn_hm(test_state, "Strength", player):
|
||||||
|
intervene_move = "Strength"
|
||||||
|
# cut may not be needed if accessibility is minimal, unless you need all 8 badges and badgesanity is off,
|
||||||
|
# as you will require cut to access celadon gyn
|
||||||
|
elif ((not logic.can_learn_hm(test_state, "Cut", player)) and
|
||||||
|
(multiworld.accessibility[player] != "minimal" or ((not
|
||||||
|
multiworld.badgesanity[player]) and max(
|
||||||
|
multiworld.elite_four_badges_condition[player],
|
||||||
|
multiworld.route_22_gate_condition[player],
|
||||||
|
multiworld.victory_road_condition[player])
|
||||||
|
> 7) or (multiworld.door_shuffle[player] not in ("off", "simple")))):
|
||||||
|
intervene_move = "Cut"
|
||||||
|
elif ((not logic.can_learn_hm(test_state, "Flash", player))
|
||||||
|
and multiworld.dark_rock_tunnel_logic[player]
|
||||||
|
and (multiworld.accessibility[player] != "minimal"
|
||||||
|
or multiworld.door_shuffle[player])):
|
||||||
|
intervene_move = "Flash"
|
||||||
|
# If no Pokémon can learn Fly, then during door shuffle it would simply not treat the free fly maps
|
||||||
|
# as reachable, and if on no door shuffle or simple, fly is simply never necessary.
|
||||||
|
# We only intervene if a Pokémon is able to learn fly but none are reachable, as that would have been
|
||||||
|
# considered in door shuffle.
|
||||||
|
elif ((not logic.can_learn_hm(test_state, "Fly", player))
|
||||||
|
and multiworld.door_shuffle[player] not in
|
||||||
|
("off", "simple") and [world.fly_map, world.town_map_fly_map] != ["Pallet Town", "Pallet Town"]):
|
||||||
|
intervene_move = "Fly"
|
||||||
|
if intervene_move:
|
||||||
|
if intervene_move == last_intervene:
|
||||||
|
raise Exception(f"Caught in infinite loop attempting to ensure {intervene_move} is available to player {player}")
|
||||||
|
intervene(intervene_move, test_state)
|
||||||
|
last_intervene = intervene_move
|
||||||
|
else:
|
||||||
|
break
|
|
@ -1948,7 +1948,7 @@ def create_regions(self):
|
||||||
for entrance in reversed(region.exits):
|
for entrance in reversed(region.exits):
|
||||||
if isinstance(entrance, PokemonRBWarp):
|
if isinstance(entrance, PokemonRBWarp):
|
||||||
region.exits.remove(entrance)
|
region.exits.remove(entrance)
|
||||||
multiworld.regions.entrance_cache[self.player] = cache
|
multiworld.regions.entrance_cache[self.player] = cache.copy()
|
||||||
if badge_locs:
|
if badge_locs:
|
||||||
for loc in badge_locs:
|
for loc in badge_locs:
|
||||||
loc.item = None
|
loc.item = None
|
||||||
|
|
Loading…
Reference in New Issue