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) | ||||
|             count = 0 | ||||
|             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: | ||||
|                 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): | ||||
|                     if (location.address is None) == (item.code is None):  # either both None or both not None | ||||
|                         if not location.item: | ||||
|                             if location.item_rule(item): | ||||
|                                 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) | ||||
|                                     count = count + 1 | ||||
|                                     break | ||||
|  | @ -998,6 +1015,7 @@ def distribute_planned(multiworld: MultiWorld) -> None: | |||
|                             err.append(f"Cannot place {item_name} into already filled location {location}.") | ||||
|                     else: | ||||
|                         err.append(f"Mismatch between {item_name} and {location}, only one is an event.") | ||||
| 
 | ||||
|                 if count == maxcount: | ||||
|                     break | ||||
|             if count < placement['count']['min']: | ||||
|  | @ -1005,17 +1023,16 @@ def distribute_planned(multiworld: MultiWorld) -> None: | |||
|                 failed( | ||||
|                     f"Plando block failed to place {m - count} of {m} item(s) for {multiworld.player_name[player]}, error(s): {' '.join(err)}", | ||||
|                     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) | ||||
|                 location.locked = True | ||||
|                 logging.debug(f"Plando placed {item} at {location}") | ||||
|                 if from_pool: | ||||
|                     try: | ||||
|                         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']) | ||||
|                 if index is not None:  # If this item is from_pool and was found in the pool, remove it. | ||||
|                     multiworld.itempool.pop(index) | ||||
| 
 | ||||
|         except Exception as e: | ||||
|             raise Exception( | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue