Merged in DR v1.2.0.18
This commit is contained in:
@@ -1963,7 +1963,7 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_cu
|
||||
if flex_map[dungeon] > 0:
|
||||
queue.append(dungeon)
|
||||
# time to re-assign
|
||||
reassign_big_key_doors(bk_map, world, player)
|
||||
reassign_big_key_doors(bk_map, used_doors, world, player)
|
||||
for name, big_list in bk_map.items():
|
||||
used_doors.update(flatten_pair_list(big_list))
|
||||
return used_doors
|
||||
@@ -2048,7 +2048,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, all_
|
||||
else:
|
||||
builder.key_doors_num -= 1
|
||||
# time to re-assign
|
||||
reassign_key_doors(small_map, world, player)
|
||||
reassign_key_doors(small_map, used_doors, world, player)
|
||||
for dungeon_name in pool:
|
||||
if world.keyshuffle[player] != 'universal':
|
||||
builder = world.dungeon_layouts[player][dungeon_name]
|
||||
@@ -2130,7 +2130,7 @@ def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, all_
|
||||
suggestion_map[dungeon] = pair
|
||||
queue.append(dungeon)
|
||||
# time to re-assign
|
||||
reassign_bd_doors(bd_map, world, player)
|
||||
reassign_bd_doors(bd_map, used_doors, world, player)
|
||||
for name, pair in bd_map.items():
|
||||
used_doors.update(flatten_pair_list(pair[0]))
|
||||
used_doors.update(flatten_pair_list(pair[1]))
|
||||
@@ -2540,7 +2540,7 @@ def find_current_bk_doors(builder):
|
||||
return current_doors
|
||||
|
||||
|
||||
def reassign_big_key_doors(bk_map, world, player):
|
||||
def reassign_big_key_doors(bk_map, used_doors, world, player):
|
||||
logger = logging.getLogger('')
|
||||
for name, big_doors in bk_map.items():
|
||||
flat_proposal = flatten_pair_list(big_doors)
|
||||
@@ -2548,11 +2548,12 @@ def reassign_big_key_doors(bk_map, world, player):
|
||||
queue = deque(find_current_bk_doors(builder))
|
||||
while len(queue) > 0:
|
||||
d = queue.pop()
|
||||
if d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal:
|
||||
if (d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal
|
||||
and d not in used_doors and d.dest not in used_doors):
|
||||
if not d.entranceFlag:
|
||||
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
|
||||
d.bigKey = False
|
||||
elif d.type is DoorType.Normal and d not in flat_proposal:
|
||||
elif d.type is DoorType.Normal and d not in flat_proposal and d not in used_doors:
|
||||
if not d.entranceFlag:
|
||||
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
|
||||
d.bigKey = False
|
||||
@@ -2796,7 +2797,7 @@ def find_valid_bd_combination(builder, suggested, world, player):
|
||||
return bomb_proposal, dash_proposal, ttl_needed
|
||||
|
||||
|
||||
def reassign_bd_doors(bd_map, world, player):
|
||||
def reassign_bd_doors(bd_map, used_doors, world, player):
|
||||
for name, pair in bd_map.items():
|
||||
flat_bomb_proposal = flatten_pair_list(pair[0])
|
||||
flat_dash_proposal = flatten_pair_list(pair[1])
|
||||
@@ -2809,10 +2810,10 @@ def reassign_bd_doors(bd_map, world, player):
|
||||
queue = deque(find_current_bd_doors(builder, world))
|
||||
while len(queue) > 0:
|
||||
d = queue.pop()
|
||||
if d.type is DoorType.Interior and not_in_proposal(d):
|
||||
if d.type is DoorType.Interior and not_in_proposal(d) and d not in used_doors and d.dest not in used_doors:
|
||||
if not d.entranceFlag:
|
||||
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
|
||||
elif d.type is DoorType.Normal and not_in_proposal(d):
|
||||
elif d.type is DoorType.Normal and not_in_proposal(d) and d not in used_doors:
|
||||
if not d.entranceFlag:
|
||||
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
|
||||
do_bombable_dashable(pair[0], DoorKind.Bombable, world, player)
|
||||
@@ -3004,7 +3005,7 @@ def valid_key_door_pair(door1, door2):
|
||||
return len(door1.entrance.parent_region.exits) <= 1 or len(door2.entrance.parent_region.exits) <= 1
|
||||
|
||||
|
||||
def reassign_key_doors(small_map, world, player):
|
||||
def reassign_key_doors(small_map, used_doors, world, player):
|
||||
logger = logging.getLogger('')
|
||||
for name, small_doors in small_map.items():
|
||||
logger.debug(f'Key doors for {name}')
|
||||
@@ -3014,7 +3015,7 @@ def reassign_key_doors(small_map, world, player):
|
||||
queue = deque(find_current_key_doors(builder))
|
||||
while len(queue) > 0:
|
||||
d = queue.pop()
|
||||
if d.type is DoorType.SpiralStairs and d not in proposal:
|
||||
if d.type is DoorType.SpiralStairs and d not in proposal and d not in used_doors:
|
||||
room = world.get_room(d.roomIndex, player)
|
||||
if room.doorList[d.doorListPos][1] == DoorKind.StairKeyLow:
|
||||
room.delete(d.doorListPos)
|
||||
@@ -3024,13 +3025,14 @@ def reassign_key_doors(small_map, world, player):
|
||||
else:
|
||||
room.delete(d.doorListPos)
|
||||
d.smallKey = False
|
||||
elif d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal:
|
||||
elif (d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal
|
||||
and d not in used_doors and d.dest not in used_doors):
|
||||
if not d.entranceFlag:
|
||||
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
|
||||
d.smallKey = False
|
||||
d.dest.smallKey = False
|
||||
queue.remove(d.dest)
|
||||
elif d.type is DoorType.Normal and d not in flat_proposal:
|
||||
elif d.type is DoorType.Normal and d not in flat_proposal and d not in used_doors:
|
||||
if not d.entranceFlag:
|
||||
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
|
||||
d.smallKey = False
|
||||
|
||||
40
ItemList.py
40
ItemList.py
@@ -1487,7 +1487,8 @@ def make_customizer_pool(world, player):
|
||||
bow_found = next((i for i in pool if i in {'Bow', 'Progressive Bow'}), None)
|
||||
if not bow_found:
|
||||
missing_items.append('Progressive Bow')
|
||||
logging.getLogger('').warning(f'The following items are not in the custom item pool {", ".join(missing_items)}')
|
||||
if missing_items:
|
||||
logging.getLogger('').warning(f'The following items are not in the custom item pool {", ".join(missing_items)}')
|
||||
|
||||
g, t = set_default_triforce(world.goal[player], world.treasure_hunt_count[player],
|
||||
world.treasure_hunt_total[player])
|
||||
@@ -1496,20 +1497,23 @@ def make_customizer_pool(world, player):
|
||||
if pieces < t:
|
||||
pool.extend(['Triforce Piece'] * (t - pieces))
|
||||
|
||||
if not world.customizer.get_start_inventory():
|
||||
if world.logic[player] in ['owglitches', 'nologic']:
|
||||
precollected_items.append('Pegasus Boots')
|
||||
if 'Pegasus Boots' in pool:
|
||||
pool.remove('Pegasus Boots')
|
||||
pool.append('Rupees (20)')
|
||||
if world.swords[player] == 'assured':
|
||||
precollected_items.append('Progressive Sword')
|
||||
if 'Progressive Sword' in pool:
|
||||
pool.remove('Progressive Sword')
|
||||
pool.append('Rupees (50)')
|
||||
elif 'Fighter Sword' in pool:
|
||||
pool.remove('Fighter Sword')
|
||||
pool.append('Rupees (50)')
|
||||
sphere_0 = world.customizer.get_start_inventory()
|
||||
no_start_inventory = not sphere_0 or not sphere_0[player]
|
||||
init_equip = [] if no_start_inventory else sphere_0[player]
|
||||
if (world.logic[player] in ['owglitches', 'nologic']
|
||||
and (no_start_inventory or all(x != 'Pegasus Boots' for x in init_equip))):
|
||||
precollected_items.append('Pegasus Boots')
|
||||
if 'Pegasus Boots' in pool:
|
||||
pool.remove('Pegasus Boots')
|
||||
pool.append('Rupees (20)')
|
||||
if world.swords[player] == 'assured' and (no_start_inventory or all(' Sword' not in x for x in init_equip)):
|
||||
precollected_items.append('Progressive Sword')
|
||||
if 'Progressive Sword' in pool:
|
||||
pool.remove('Progressive Sword')
|
||||
pool.append('Rupees (50)')
|
||||
elif 'Fighter Sword' in pool:
|
||||
pool.remove('Fighter Sword')
|
||||
pool.append('Rupees (50)')
|
||||
|
||||
return pool, placed_items, precollected_items, clock_mode, 1
|
||||
|
||||
@@ -1578,10 +1582,13 @@ def fill_specific_items(world):
|
||||
dungeon_pool, prize_set, prize_pool)
|
||||
if item_to_place:
|
||||
world.push_item(loc, item_to_place, False)
|
||||
loc.locked = True
|
||||
track_outside_keys(item_to_place, loc, world)
|
||||
track_dungeon_items(item_to_place, loc, world)
|
||||
loc.event = (event_flag or item_to_place.advancement
|
||||
or item_to_place.bigkey or item_to_place.smallkey)
|
||||
else:
|
||||
raise Exception(f'Did not find "{item}" in item pool to place at "{location}"')
|
||||
advanced_placements = world.customizer.get_advanced_placements()
|
||||
if advanced_placements:
|
||||
for player, placement_list in advanced_placements.items():
|
||||
@@ -1591,7 +1598,7 @@ def fill_specific_items(world):
|
||||
item_to_place, event_flag = get_item_and_event_flag(item, world, player,
|
||||
dungeon_pool, prize_set, prize_pool)
|
||||
if not item_to_place:
|
||||
continue
|
||||
raise Exception(f'Did not find "{item}" in item pool to place for a LocationGroup"')
|
||||
locations = placement['locations']
|
||||
handled = False
|
||||
while not handled:
|
||||
@@ -1611,6 +1618,7 @@ def fill_specific_items(world):
|
||||
if loc.item:
|
||||
continue
|
||||
world.push_item(loc, item_to_place, False)
|
||||
loc.locked = True
|
||||
track_outside_keys(item_to_place, loc, world)
|
||||
track_dungeon_items(item_to_place, loc, world)
|
||||
loc.event = (event_flag or item_to_place.advancement
|
||||
|
||||
6
Main.py
6
Main.py
@@ -36,7 +36,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new
|
||||
from source.tools.BPS import create_bps_from_data
|
||||
from source.classes.CustomSettings import CustomSettings
|
||||
|
||||
version_number = '1.2.0.17'
|
||||
version_number = '1.2.0.18'
|
||||
version_branch = '-u'
|
||||
__version__ = f'{version_number}{version_branch}'
|
||||
|
||||
@@ -814,7 +814,9 @@ def create_playthrough(world):
|
||||
|
||||
logging.getLogger('').debug(world.fish.translate("cli", "cli", "building.calculating.spheres"), len(collection_spheres), len(sphere), len(prog_locations))
|
||||
if not sphere:
|
||||
logging.getLogger('').error(world.fish.translate("cli", "cli", "cannot.reach.items"), [world.fish.translate("cli","cli","cannot.reach.item") % (location.item.name, location.item.player, location.name, location.player) for location in sphere_candidates])
|
||||
if world.accessibility[location.item.player] != 'none':
|
||||
logging.getLogger('').error(world.fish.translate("cli", "cli", "cannot.reach.items"),
|
||||
[world.fish.translate("cli","cli","cannot.reach.item") % (location.item.name, location.item.player, location.name, location.player) for location in sphere_candidates])
|
||||
if any([location.name not in optional_locations and world.accessibility[location.item.player] != 'none' for location in sphere_candidates]):
|
||||
raise RuntimeError(world.fish.translate("cli", "cli", "cannot.reach.progression"))
|
||||
else:
|
||||
|
||||
@@ -57,7 +57,7 @@ Please see [Customizer documentation](docs/Customizer.md) on how to create custo
|
||||
|
||||
## New Goals
|
||||
|
||||
### Triforce Hunt + Ganon
|
||||
### Ganonhunt
|
||||
Collect the requisite triforce pieces, then defeat Ganon. (Aga2 not required). Use `ganonhunt` on CLI
|
||||
|
||||
### Completionist
|
||||
@@ -109,6 +109,16 @@ These are now independent of retro mode and have three options: None, Random, an
|
||||
|
||||
# Bug Fixes and Notes
|
||||
|
||||
* 1.2.0.18u
|
||||
* Fixed an issue with pyramid hole being in logic when it is not opened.
|
||||
* Crystal cutscene at GT use new symmetrical layouts (thanks Codemann)
|
||||
* Fix for Hera Boss music (thanks Codemann)
|
||||
* Fixed an issue where certain vanilla door types would not allow other types to be placed.
|
||||
* Customizer: fixed an issue where last ditch placements would move customized items. Those are now locked and the generation will fail instead is no alternative are found.
|
||||
* Customizer: fixed an issue with assured sword and start_inventory
|
||||
* Customizer: warns when trying to specifically place an item that's not in the item pool
|
||||
* Fixed "accessibility: none" displaying a spoiling message
|
||||
* Fixed warning message about custom item pool when it is fine
|
||||
* 1.2.0.17u
|
||||
* Fixed logic bug that allowed Pearl to be behind Graveyard Cave or King's Tomb entrances with only Mirror and West Dark World access (cross world shuffles only)
|
||||
* Removed backup locations for Dungeon Only and Major Only algorithms. If item cannot be placed in the appropriate location, the seed will fail to generate instead
|
||||
|
||||
@@ -269,7 +269,7 @@
|
||||
"randomizer.item.goal.triforcehunt": "Triforce Hunt",
|
||||
"randomizer.item.goal.trinity": "Trinity",
|
||||
"randomizer.item.goal.crystals": "Crystals",
|
||||
"randomizer.item.goal.ganonhunt": "Triforce Hunt + Ganon",
|
||||
"randomizer.item.goal.ganonhunt": "Ganonhunt",
|
||||
"randomizer.item.goal.completionist": "Completionist",
|
||||
|
||||
"randomizer.item.crystals_gt": "Crystals to open GT",
|
||||
|
||||
Reference in New Issue
Block a user