Core: Actually take item from pool when plandoing from_pool (#2420)
* Actually take item from pool when plandoing from_pool * Remove the awkward index thing * oops left a comment in * there wasn't a line break here before * Only remove if actually found, check against player number * oops * Go back to index based system so we can just remove at the end * Comment * Fix error on None * Update Fill.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
This commit is contained in:
parent
30b414429f
commit
1371c63a8d
39
Fill.py
39
Fill.py
|
@ -978,15 +978,32 @@ def distribute_planned(multiworld: MultiWorld) -> None:
|
||||||
multiworld.random.shuffle(items)
|
multiworld.random.shuffle(items)
|
||||||
count = 0
|
count = 0
|
||||||
err: typing.List[str] = []
|
err: typing.List[str] = []
|
||||||
successful_pairs: typing.List[typing.Tuple[Item, Location]] = []
|
successful_pairs: typing.List[typing.Tuple[int, Item, Location]] = []
|
||||||
|
claimed_indices: typing.Set[typing.Optional[int]] = set()
|
||||||
for item_name in items:
|
for item_name in items:
|
||||||
item = multiworld.worlds[player].create_item(item_name)
|
index_to_delete: typing.Optional[int] = None
|
||||||
|
if from_pool:
|
||||||
|
try:
|
||||||
|
# If from_pool, try to find an existing item with this name & player in the itempool and use it
|
||||||
|
index_to_delete, item = next(
|
||||||
|
(i, item) for i, item in enumerate(multiworld.itempool)
|
||||||
|
if item.player == player and item.name == item_name and i not in claimed_indices
|
||||||
|
)
|
||||||
|
except StopIteration:
|
||||||
|
warn(
|
||||||
|
f"Could not remove {item_name} from pool for {multiworld.player_name[player]} as it's already missing from it.",
|
||||||
|
placement['force'])
|
||||||
|
item = multiworld.worlds[player].create_item(item_name)
|
||||||
|
else:
|
||||||
|
item = multiworld.worlds[player].create_item(item_name)
|
||||||
|
|
||||||
for location in reversed(candidates):
|
for location in reversed(candidates):
|
||||||
if (location.address is None) == (item.code is None): # either both None or both not None
|
if (location.address is None) == (item.code is None): # either both None or both not None
|
||||||
if not location.item:
|
if not location.item:
|
||||||
if location.item_rule(item):
|
if location.item_rule(item):
|
||||||
if location.can_fill(multiworld.state, item, False):
|
if location.can_fill(multiworld.state, item, False):
|
||||||
successful_pairs.append((item, location))
|
successful_pairs.append((index_to_delete, item, location))
|
||||||
|
claimed_indices.add(index_to_delete)
|
||||||
candidates.remove(location)
|
candidates.remove(location)
|
||||||
count = count + 1
|
count = count + 1
|
||||||
break
|
break
|
||||||
|
@ -998,6 +1015,7 @@ def distribute_planned(multiworld: MultiWorld) -> None:
|
||||||
err.append(f"Cannot place {item_name} into already filled location {location}.")
|
err.append(f"Cannot place {item_name} into already filled location {location}.")
|
||||||
else:
|
else:
|
||||||
err.append(f"Mismatch between {item_name} and {location}, only one is an event.")
|
err.append(f"Mismatch between {item_name} and {location}, only one is an event.")
|
||||||
|
|
||||||
if count == maxcount:
|
if count == maxcount:
|
||||||
break
|
break
|
||||||
if count < placement['count']['min']:
|
if count < placement['count']['min']:
|
||||||
|
@ -1005,17 +1023,16 @@ def distribute_planned(multiworld: MultiWorld) -> None:
|
||||||
failed(
|
failed(
|
||||||
f"Plando block failed to place {m - count} of {m} item(s) for {multiworld.player_name[player]}, error(s): {' '.join(err)}",
|
f"Plando block failed to place {m - count} of {m} item(s) for {multiworld.player_name[player]}, error(s): {' '.join(err)}",
|
||||||
placement['force'])
|
placement['force'])
|
||||||
for (item, location) in successful_pairs:
|
|
||||||
|
# Sort indices in reverse so we can remove them one by one
|
||||||
|
successful_pairs = sorted(successful_pairs, key=lambda successful_pair: successful_pair[0] or 0, reverse=True)
|
||||||
|
|
||||||
|
for (index, item, location) in successful_pairs:
|
||||||
multiworld.push_item(location, item, collect=False)
|
multiworld.push_item(location, item, collect=False)
|
||||||
location.locked = True
|
location.locked = True
|
||||||
logging.debug(f"Plando placed {item} at {location}")
|
logging.debug(f"Plando placed {item} at {location}")
|
||||||
if from_pool:
|
if index is not None: # If this item is from_pool and was found in the pool, remove it.
|
||||||
try:
|
multiworld.itempool.pop(index)
|
||||||
multiworld.itempool.remove(item)
|
|
||||||
except ValueError:
|
|
||||||
warn(
|
|
||||||
f"Could not remove {item} from pool for {multiworld.player_name[player]} as it's already missing from it.",
|
|
||||||
placement['force'])
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
|
|
Loading…
Reference in New Issue