Skip to content

Commit f9fda56

Browse files
authored
Fix the fact that list[Item].remove ignore classification (#172)
* add remove_specific_item * added source * make remove_specific_item use 'is' instead of additional checks
1 parent c3880e0 commit f9fda56

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

src/Helpers.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,18 @@ def format_to_valid_identifier(input: str) -> str:
211211
input = "_" + input
212212
return input.replace(" ", "_")
213213

214+
def remove_specific_item(source: list[Item], item: Item) -> Item:
215+
"""Remove and return an item from a list in a more precise way, base AP only check for name and player id before removing.
216+
\nThis checks that the item IS the exact same in the list.
217+
\nRaise ValueError if the item is not in the list."""
218+
# Inspired by https://stackoverflow.com/a/58761459
219+
for i in range(len(source)): # check all elements of the list like a normal remove does
220+
if item is source[i]:
221+
return source.pop(i)
222+
223+
# if we reach here we didn't get any item
224+
raise ValueError(f"Item '{item.name}' could not be found in source list")
225+
214226
class ProgItemsCat(IntEnum):
215227
VALUE = 1
216228
CATEGORY = 2

src/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from .Items import ManualItem
2121
from .Rules import set_rules
2222
from .Options import manual_options_data
23-
from .Helpers import is_item_enabled, get_option_value, get_items_for_player, resolve_yaml_option, format_state_prog_items_key, ProgItemsCat
23+
from .Helpers import is_item_enabled, get_option_value, remove_specific_item, resolve_yaml_option, format_state_prog_items_key, ProgItemsCat
2424

2525
from BaseClasses import CollectionState, ItemClassification, Item
2626
from Options import PerGameCommonOptions
@@ -245,7 +245,7 @@ def stringCheck(string: str) -> ItemClassification:
245245
for starting_item in items:
246246
items_started.append(starting_item)
247247
self.multiworld.push_precollected(starting_item)
248-
pool.remove(starting_item)
248+
remove_specific_item(pool, starting_item)
249249

250250
self.start_inventory = {i.name: items_started.count(i) for i in items_started}
251251

@@ -390,7 +390,7 @@ def generate_basic(self):
390390
location.place_locked_item(item_to_place)
391391

392392
# remove the item we're about to place from the pool so it isn't placed twice
393-
self.multiworld.itempool.remove(item_to_place)
393+
remove_specific_item(self.multiworld.itempool, item_to_place)
394394

395395

396396
after_generate_basic(self, self.multiworld, self.player)
@@ -501,7 +501,7 @@ def adjust_filler_items(self, item_pool, traps):
501501
else:
502502
logging.warning("Could not remove enough non-progression items from the pool.")
503503
break
504-
item_pool.remove(popped)
504+
remove_specific_item(item_pool, popped)
505505

506506
return item_pool
507507

src/hooks/World.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from ..Data import game_table, item_table, location_table, region_table
1313

1414
# These helper methods allow you to determine if an option has been set, or what its value is, for any player in the multiworld
15-
from ..Helpers import is_option_enabled, get_option_value, format_state_prog_items_key, ProgItemsCat
15+
from ..Helpers import is_option_enabled, get_option_value, format_state_prog_items_key, ProgItemsCat, remove_specific_item
1616

1717
# calling logging.info("message") anywhere below in this file will output the message to both console and log file
1818
import logging
@@ -80,7 +80,7 @@ def before_create_items_filler(item_pool: list, world: World, multiworld: MultiW
8080

8181
for itemName in itemNamesToRemove:
8282
item = next(i for i in item_pool if i.name == itemName)
83-
item_pool.remove(item)
83+
remove_specific_item(item_pool, item)
8484

8585
return item_pool
8686

@@ -90,7 +90,7 @@ def before_create_items_filler(item_pool: list, world: World, multiworld: MultiW
9090
# location = next(l for l in multiworld.get_unfilled_locations(player=player) if l.name == "Location Name")
9191
# item_to_place = next(i for i in item_pool if i.name == "Item Name")
9292
# location.place_locked_item(item_to_place)
93-
# item_pool.remove(item_to_place)
93+
# remove_specific_item(item_pool, item_to_place)
9494

9595
# The complete item pool prior to being set for generation is provided here, in case you want to make changes to it
9696
def after_create_items(item_pool: list, world: World, multiworld: MultiWorld, player: int) -> list:

0 commit comments

Comments
 (0)