Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ALttP: fix dungeon fill failures properly #1812

Merged
merged 6 commits into from
May 18, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions worlds/alttp/Dungeons.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import typing

from BaseClasses import Dungeon
from BaseClasses import CollectionState, Dungeon
from Fill import fill_restrictive

from .Bosses import BossFactory
Expand Down Expand Up @@ -154,16 +154,32 @@ def fill_dungeons_restrictive(world):
(not (item.player, item.name) in dungeon_specific or item.dungeon is dungeon) and orig_rule(item)

world.random.shuffle(locations)
all_state_base = world.get_all_state(use_cache=True)
# Dungeon-locked items have to be placed first, to not run out of spaces for dungeon-locked items
# subsort in the order Big Key, Small Key, Other before placing dungeon items

sort_order = {"BigKey": 3, "SmallKey": 2}
in_dungeon_items.sort(
key=lambda item: sort_order.get(item.type, 1) +
(5 if (item.player, item.name) in dungeon_specific else 0))

# Construct a partial all_state which contains only the items from get_pre_fill_items which aren't in_dungeon
in_dungeon_player_ids = {item.player for item in in_dungeon_items}
all_state_base = CollectionState(world)
for item in world.itempool:
world.worlds[item.player].collect(all_state_base, item)
pre_fill_items = []
for player in in_dungeon_player_ids:
pre_fill_items += world.worlds[player].get_pre_fill_items()
for item in in_dungeon_items:
all_state_base.remove(item)
try:
pre_fill_items.remove(item)
except ValueError:
# pre_fill_items should be a subset of in_dungeon_items, but just in case
pass
for item in pre_fill_items:
world.worlds[item.player].collect(all_state_base, item)
all_state_base.sweep_for_events()


# Remove completion condition so that minimal-accessibility worlds place keys properly
for player in {item.player for item in in_dungeon_items}:
Expand Down