ArchipelagoMW / Archipelago

Archipelago Multi-Game Randomizer and Server
https://archipelago.gg
Other
521 stars 678 forks source link

Core: Fix empty rule comparisons with subclasses #4201

Closed Mysteryem closed 1 week ago

Mysteryem commented 1 week ago

What is this fixing or adding?

If a world uses a Location or Entrance subclass that overrides the item_rule/access_rule class attribute, then spot.__class__.item_rule/spot.__class__.access_rule will get the overridden rule, which may not be an empty rule.

Uses of spot.__class__ have been replaced with getting the class attribute rule belonging to the Location or Entrance class.

How was this tested?

from BaseClasses import Location

class MyLocation(Location):
    pass

class MyLocationOverride(Location):
    item_rule = staticmethod(lambda item: False)

# Uses the empty rule, so should be True
my_loc = MyLocation(player=1)
# True
print(my_loc.item_rule is my_loc.__class__.item_rule)
# True
print(my_loc.item_rule is Location.item_rule)

# Overrides the empty rule, so should be False
my_loc_override = MyLocationOverride(player=1)
# True
print(my_loc_override.item_rule is my_loc_override.__class__.item_rule)
# False
print(my_loc_override.item_rule is Location.item_rule)