Skip to content

Commit 956d8f1

Browse files
committed
Fill excluded locations first in distribute_local_nonprogression
By moving distribute_local_nonprogression *after* the item pool and location lists are separated into their categories, we're able to ensure we don't leave unfilled excluded locations (if possible). Additionally, this moves the function call until after fill_hook, so world code doesn't accidentally stumble into a filled location in the location list.
1 parent 65371c1 commit 956d8f1

File tree

1 file changed

+41
-22
lines changed

1 file changed

+41
-22
lines changed

Fill.py

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,6 @@ def distribute_items_restrictive(multiworld: MultiWorld,
485485
multiworld.random.shuffle(itempool)
486486

487487
fill_locations, itempool = distribute_early_items(multiworld, fill_locations, itempool)
488-
fill_locations, itempool = distribute_local_nonprogression(multiworld, fill_locations, itempool)
489488

490489
progitempool: typing.List[Item] = []
491490
usefulitempool: typing.List[Item] = []
@@ -520,6 +519,11 @@ def mark_for_locking(location: Location):
520519

521520
single_player = multiworld.players == 1 and not multiworld.groups
522521

522+
if not single_player:
523+
usefulitempool, filleritempool = distribute_local_nonprogression(multiworld, excludedlocations,
524+
defaultlocations, prioritylocations,
525+
usefulitempool, filleritempool)
526+
523527
if prioritylocations:
524528
# "priority fill"
525529
fill_restrictive(multiworld, multiworld.state, prioritylocations, progitempool,
@@ -1089,33 +1093,48 @@ def failed(warning: str, force: typing.Union[bool, str]) -> None:
10891093

10901094

10911095
def distribute_local_nonprogression(multiworld: MultiWorld,
1092-
locations: typing.List[Location],
1093-
itempool: typing.List[Item]) \
1094-
-> typing.Tuple[typing.List[Location], typing.List[Item]]:
1096+
excluded_locations: typing.List[Location],
1097+
default_locations: typing.List[Location],
1098+
priority_locations: typing.List[Location],
1099+
useful_itempool: typing.List[Item],
1100+
filler_itempool: typing.List[Item]) \
1101+
-> typing.Tuple[typing.List[Item], typing.List[Item]]:
10951102
# call remaining_fill early on local items, but sort the list of locations filled this way to the back of the list
10961103
# instead of popping them entirely
1104+
# modifies the three location lists in place, and returns unplaced useful and filler items
10971105
local_nonprogression_items: typing.List[Item] = []
1098-
new_itempool: typing.List[Item] = []
1099-
for item in itempool:
1106+
# fill local filler on local excluded locations first
1107+
new_filler_itempool: typing.List[Item] = []
1108+
for item in filler_itempool:
11001109
if not item.advancement and item.name in multiworld.worlds[item.player].options.local_items.value:
11011110
local_nonprogression_items.append(item)
11021111
else:
1103-
new_itempool.append(item)
1104-
non_priority_locations: typing.List[Location] = []
1105-
priority_locations: typing.List[Location] = []
1106-
for location in locations:
1107-
if location.progress_type == location.progress_type.PRIORITY:
1108-
priority_locations.append(location)
1112+
new_filler_itempool.append(item)
1113+
excluded_placements: typing.List[Location] = remaining_fill(multiworld, excluded_locations,
1114+
local_nonprogression_items,
1115+
"Local non-progression excluded placement", False, True)
1116+
# then add local useful to remaining local items and fill in default locations
1117+
new_useful_itempool: typing.List[Item] = []
1118+
for item in useful_itempool:
1119+
if not item.advancement and item.name in multiworld.worlds[item.player].options.local_items.value:
1120+
local_nonprogression_items.append(item)
11091121
else:
1110-
non_priority_locations.append(location)
1111-
placements: typing.List[Location] = remaining_fill(multiworld, non_priority_locations, local_nonprogression_items,
1112-
"Local non-progression placement", False, True)
1113-
# local_nonprogression_items should be empty now
1122+
new_useful_itempool.append(item)
1123+
default_placements: typing.List[Location] = remaining_fill(multiworld, default_locations, local_nonprogression_items,
1124+
"Local non-progression default placement", False, True)
1125+
priority_placements: typing.List[Location] = []
1126+
# then if there are still local items, fill into priority locations
1127+
if local_nonprogression_items:
1128+
priority_placements = remaining_fill(multiworld, priority_locations, local_nonprogression_items,
1129+
"Local non-progression priority placement", False, True)
1130+
# if, somehow, there are still items, then error out, because there's no saving it
11141131
if local_nonprogression_items:
1115-
# this should only be happening if the world has a lot of strict
1116-
raise FillError("Not enough available locations for all local filler. Reduce the amount of local items or "
1117-
"priority locations in your YAMLs.")
1118-
itempool = new_itempool
1132+
# this should only be happening if the world has a lot of strict item rules
1133+
raise FillError("Not enough available locations for all local non-progression. Reduce the amount of local items"
1134+
" in your YAMLs.")
1135+
11191136
# place the filled locations at the back of the list
1120-
locations = [*priority_locations, *non_priority_locations, *placements]
1121-
return locations, itempool
1137+
excluded_locations.extend(excluded_placements)
1138+
default_locations.extend(default_placements)
1139+
priority_locations.extend(priority_placements)
1140+
return new_useful_itempool, new_filler_itempool

0 commit comments

Comments
 (0)