Skip to content

Commit

Permalink
DS3: Explicitly track item equality by name when sending IDs (Archipe…
Browse files Browse the repository at this point in the history
…lagoMW#3853)

We had been keeping a set of items and defining item equality, but
item equality really only makes sense if you consider distinct IDs to
be distinct items. But that means the set ends up having multiple
copies of the same item, causing a bug where some items had the wrong
upgrade level in the game.

This also removes the equality definition, which was only used by this
one set.
  • Loading branch information
nex3 authored Aug 30, 2024
1 parent 08dc7e5 commit b1be597
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 13 deletions.
9 changes: 0 additions & 9 deletions worlds/dark_souls_3/Items.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,15 +238,6 @@ def upgrade(self, level: int) -> "DS3ItemData":
ds3_code = cast(int, self.ds3_code) + level,
filler = False,
)

def __hash__(self) -> int:
return (self.name, self.ds3_code).__hash__()

def __eq__(self, other: Any) -> bool:
if isinstance(other, self.__class__):
return self.name == other.name and self.ds3_code == other.ds3_code
else:
return False


class DarkSouls3Item(Item):
Expand Down
11 changes: 7 additions & 4 deletions worlds/dark_souls_3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1504,16 +1504,19 @@ def fill_slot_data(self) -> Dict[str, object]:
# We include all the items the game knows about so that users can manually request items
# that aren't randomized, and then we _also_ include all the items that are placed in
# practice `item_dictionary.values()` doesn't include upgraded or infused weapons.
all_items = {
cast(DarkSouls3Item, location.item).data
items_by_name = {
location.item.name: cast(DarkSouls3Item, location.item).data
for location in self.multiworld.get_filled_locations()
# item.code None is used for events, which we want to skip
if location.item.code is not None and location.item.player == self.player
}.union(item_dictionary.values())
}
for item in item_dictionary.values():
if item.name not in items_by_name:
items_by_name[item.name] = item

ap_ids_to_ds3_ids: Dict[str, int] = {}
item_counts: Dict[str, int] = {}
for item in all_items:
for item in items_by_name.values():
if item.ap_code is None: continue
if item.ds3_code: ap_ids_to_ds3_ids[str(item.ap_code)] = item.ds3_code
if item.count != 1: item_counts[str(item.ap_code)] = item.count
Expand Down

0 comments on commit b1be597

Please sign in to comment.