Ocarina of Time: 0.3.7 hotfixes round 2 (#1351)

* oot: repair closed forest + dungeon ER

* oot: finally skip triforce pieces in balancing

* oot: fix mq_dungeons_mode set to mq or count

* oot: force 0.3.7 client
hopefully this makes people update

* oot: temp fix for skip-child-zelda crash
eventually I want to decide on a better fix for this though

* oot: remove skip-child-zelda item inside if tree

* oot: fix classification of some thieves hideout locations in tracker

* oot: fix regional shuffle for hideout keys and ganon boss key

* oot: properly attach hints to dungeon locations

* Fix entrance shuffle flag not being set correctly due to new dungeon shuffle option format
This commit is contained in:
espeon65536 2023-01-12 12:20:49 -07:00 committed by GitHub
parent 608794cded
commit 11eebbbd32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 15 deletions

View File

@ -650,7 +650,7 @@ def __renderOoTTracker(multisave: Dict[str, Any], room: Room, locations: Dict[in
# Gather dungeon locations
area_id_ranges = {
"Overworld": ((67000, 67258), (67264, 67280), (67747, 68024), (68054, 68062)),
"Overworld": ((67000, 67263), (67269, 67280), (67747, 68024), (68054, 68062)),
"Deku Tree": ((67281, 67303), (68063, 68077)),
"Dodongo's Cavern": ((67304, 67334), (68078, 68160)),
"Jabu Jabu's Belly": ((67335, 67359), (68161, 68188)),
@ -662,7 +662,7 @@ def __renderOoTTracker(multisave: Dict[str, Any], room: Room, locations: Dict[in
"Spirit Temple": ((67533, 67582), (68566, 68625)),
"Ice Cavern": ((67583, 67596), (68626, 68649)),
"Gerudo Training Ground": ((67597, 67635), (68650, 68656)),
"Thieves' Hideout": ((67259, 67263), (68025, 68053)),
"Thieves' Hideout": ((67264, 67268), (68025, 68053)),
"Ganon's Castle": ((67636, 67673), (68657, 68705)),
}

View File

@ -1136,14 +1136,14 @@ def buildMiscItemHints(world, messages):
if world.multiworld.state.has(data['default_item'], world.player) > 0:
text = data['default_item_text'].format(area='#your pocket#')
elif item_locations:
location = item_locations[0]
location = world.hint_rng.choice(item_locations)
player_text = ''
if location.player != world.player:
player_text = world.multiworld.get_player_name(location.player) + "'s "
if location.game == 'Ocarina of Time':
area = HintArea.at(location, use_alt_hint=data['use_alt_hint']).text(world.clearer_hints, world=None)
else:
area = location.name
area = location.name
text = data['default_item_text'].format(area=(player_text + area))
elif 'default_item_fallback' in data:
text = data['default_item_fallback']

View File

@ -41,7 +41,7 @@ class OOTItem(Item):
classification = ItemClassification.useful
elif name == "Ice Trap":
classification = ItemClassification.trap
elif name == 'Gold Skulltula Token':
elif name in {'Gold Skulltula Token', 'Triforce Piece'}:
classification = ItemClassification.progression_skip_balancing
elif advancement:
classification = ItemClassification.progression

View File

@ -109,7 +109,7 @@ class OOTWorld(World):
data_version = 3
required_client_version = (0, 3, 6)
required_client_version = (0, 3, 7)
item_name_groups = {
# internal groups
@ -171,12 +171,13 @@ class OOTWorld(World):
# ER and glitched logic are not compatible; glitched takes priority
if self.logic_rules == 'glitched':
self.shuffle_interior_entrances = 'off'
self.shuffle_dungeon_entrances = 'off'
self.spawn_positions = 'off'
self.shuffle_bosses = 'off'
self.shuffle_grotto_entrances = False
self.shuffle_dungeon_entrances = False
self.shuffle_overworld_entrances = False
self.owl_drops = False
self.warp_songs = False
self.spawn_positions = 'off'
# Fix spawn positions option
new_sp = []
@ -283,8 +284,17 @@ class OOTWorld(World):
self.shuffle_special_dungeon_entrances = self.shuffle_dungeon_entrances == 'all'
self.shuffle_dungeon_entrances = self.shuffle_dungeon_entrances != 'off'
self.ensure_tod_access = (self.shuffle_interior_entrances != 'off') or self.shuffle_overworld_entrances or self.spawn_positions
self.entrance_shuffle = (self.shuffle_interior_entrances != 'off') or self.shuffle_grotto_entrances or self.shuffle_dungeon_entrances or \
self.shuffle_overworld_entrances or self.owl_drops or self.warp_songs or self.spawn_positions
self.entrance_shuffle = (
self.shuffle_interior_entrances != 'off'
or self.shuffle_bosses != 'off'
or self.shuffle_dungeon_entrances
or self.shuffle_special_dungeon_entrances
or self.spawn_positions
or self.shuffle_grotto_entrances
or self.shuffle_overworld_entrances
or self.owl_drops
or self.warp_songs
)
self.disable_trade_revert = (self.shuffle_interior_entrances != 'off') or self.shuffle_overworld_entrances
self.shuffle_special_interior_entrances = self.shuffle_interior_entrances == 'all'
@ -317,13 +327,14 @@ class OOTWorld(World):
# Determine which dungeons are MQ. Not compatible with glitched logic.
mq_dungeons = set()
all_dungeons = [d['name'] for d in dungeon_table]
if self.logic_rules != 'glitched':
if self.mq_dungeons_mode == 'mq':
mq_dungeons = dungeon_table.keys()
mq_dungeons = all_dungeons
elif self.mq_dungeons_mode == 'specific':
mq_dungeons = self.mq_dungeons_specific
elif self.mq_dungeons_mode == 'count':
mq_dungeons = self.multiworld.random.sample(dungeon_table, self.mq_dungeons_count)
mq_dungeons = self.multiworld.random.sample(all_dungeons, self.mq_dungeons_count)
else:
self.mq_dungeons_mode = 'count'
self.mq_dungeons_count = 0
@ -441,6 +452,7 @@ class OOTWorld(World):
new_region.scene = region['scene']
if 'dungeon' in region:
new_region.dungeon = region['dungeon']
new_region.set_hint_data(region['dungeon'])
if 'is_boss_room' in region:
new_region.is_boss_room = region['is_boss_room']
if 'hint' in region:
@ -842,10 +854,13 @@ class OOTWorld(World):
impa = self.multiworld.get_location("Song from Impa", self.player)
if self.shuffle_child_trade == 'skip_child_zelda':
if impa.item is None:
item_to_place = self.multiworld.random.choice(
list(item for item in self.multiworld.itempool if item.player == self.player))
candidate_items = list(item for item in self.multiworld.itempool if item.player == self.player)
if candidate_items:
item_to_place = self.multiworld.random.choice(candidate_items)
self.multiworld.itempool.remove(item_to_place)
else:
item_to_place = self.create_item("Recovery Heart")
impa.place_locked_item(item_to_place)
self.multiworld.itempool.remove(item_to_place)
# Give items to startinventory
self.multiworld.push_precollected(impa.item)
self.multiworld.push_precollected(self.create_item("Zeldas Letter"))
@ -1269,6 +1284,13 @@ def gather_locations(multiworld: MultiWorld,
'HideoutSmallKey': 'shuffle_hideoutkeys',
'GanonBossKey': 'shuffle_ganon_bosskey',
}
# Special handling for atypical item types
if item_type == 'HideoutSmallKey':
dungeon = 'Thieves Hideout'
elif item_type == 'GanonBossKey':
dungeon = 'Ganons Castle'
if isinstance(players, int):
players = {players}
fill_opts = {p: getattr(multiworld.worlds[p], type_to_setting[item_type]) for p in players}