Core: Don't waste swaps by swapping two copies of the same item (#5516)
There is a limit to the number of times an item can be swapped to prevent swapping going on potentially forever. Swapping an item with a copy of itself is assumed to be a pointless swap, and was wasting possible swaps in cases where there were multiple copies of an item being placed. This swapping behaviour was noticed from debugging solo LADX generations that was wasting swaps by swapping copies of the same item. This patch adds a check that if the placed_item and item_to_place are equal, then the location is skipped and no attempt to swap is made. If worlds do intend to have seemingly equal items to actually have different logical behaviour, those worlds should override __eq__ on their Item subclasses so that the item instances are not considered equal. Generally, fill_restrictive should only be used with progression items, so it is assumed that swapping won't have to deal with multiple copies of an item where some copies are progression and some are not. This is relevant because Item.__eq__ only compares .name and .player.
This commit is contained in:
4
Fill.py
4
Fill.py
@@ -129,6 +129,10 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati
|
|||||||
for i, location in enumerate(placements))
|
for i, location in enumerate(placements))
|
||||||
for (i, location, unsafe) in swap_attempts:
|
for (i, location, unsafe) in swap_attempts:
|
||||||
placed_item = location.item
|
placed_item = location.item
|
||||||
|
if item_to_place == placed_item:
|
||||||
|
# The number of allowed swaps is limited, so do not allow a swap of an item with a copy of
|
||||||
|
# itself.
|
||||||
|
continue
|
||||||
# Unplaceable items can sometimes be swapped infinitely. Limit the
|
# Unplaceable items can sometimes be swapped infinitely. Limit the
|
||||||
# number of times we will swap an individual item to prevent this
|
# number of times we will swap an individual item to prevent this
|
||||||
swap_count = swapped_items[placed_item.player, placed_item.name, unsafe]
|
swap_count = swapped_items[placed_item.player, placed_item.name, unsafe]
|
||||||
|
|||||||
Reference in New Issue
Block a user