diff --git a/BaseClasses.py b/BaseClasses.py index b25d998311a1..7965eb8b0d0d 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -714,6 +714,7 @@ def sweep_for_events(self, key_only: bool = False, locations: Optional[Iterable[ assert isinstance(event.item, Item), "tried to collect Event with no Item" self.collect(event.item, True, event) + # item name related def has(self, item: str, player: int, count: int = 1) -> bool: return self.prog_items[player][item] >= count @@ -728,6 +729,11 @@ def has_any(self, items: Iterable[str], player: int) -> bool: def count(self, item: str, player: int) -> int: return self.prog_items[player][item] + def item_count(self, item: str, player: int) -> int: + Utils.deprecate("Use count instead.") + return self.count(item, player) + + # item name group related def has_group(self, item_name_group: str, player: int, count: int = 1) -> bool: found: int = 0 player_prog_items = self.prog_items[player] @@ -744,9 +750,7 @@ def count_group(self, item_name_group: str, player: int) -> int: found += player_prog_items[item_name] return found - def item_count(self, item: str, player: int) -> int: - return self.prog_items[player][item] - + # Item related def collect(self, item: Item, event: bool = False, location: Optional[Location] = None) -> bool: if location: self.locations_checked.add(location) diff --git a/docs/world api.md b/docs/world api.md index 4008c9c4dddf..71710ac2932e 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -691,7 +691,7 @@ def generate_basic(self) -> None: ### Setting Rules ```python -from worlds.generic.Rules import add_rule, set_rule, forbid_item +from worlds.generic.Rules import add_rule, set_rule, forbid_item, add_item_rule from .items import get_item_type @@ -718,7 +718,7 @@ def set_rules(self) -> None: # require one item from an item group add_rule(self.multiworld.get_location("Chest3", self.player), lambda state: state.has_group("weapons", self.player)) - # state also has .item_count() for items, .has_any() and .has_all() for sets + # state also has .count() for items, .has_any() and .has_all() for multiple # and .count_group() for groups # set_rule is likely to be a bit faster than add_rule diff --git a/worlds/alttp/StateHelpers.py b/worlds/alttp/StateHelpers.py index 95e31e5ba328..38ce00ef4537 100644 --- a/worlds/alttp/StateHelpers.py +++ b/worlds/alttp/StateHelpers.py @@ -31,7 +31,7 @@ def can_shoot_arrows(state: CollectionState, player: int) -> bool: def has_triforce_pieces(state: CollectionState, player: int) -> bool: count = state.multiworld.treasure_hunt_count[player] - return state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= count + return state.count('Triforce Piece', player) + state.count('Power Star', player) >= count def has_crystals(state: CollectionState, count: int, player: int) -> bool: @@ -60,9 +60,9 @@ def has_hearts(state: CollectionState, player: int, count: int) -> int: def heart_count(state: CollectionState, player: int) -> int: # Warning: This only considers items that are marked as advancement items diff = state.multiworld.difficulty_requirements[player] - return min(state.item_count('Boss Heart Container', player), diff.boss_heart_container_limit) \ - + state.item_count('Sanctuary Heart Container', player) \ - + min(state.item_count('Piece of Heart', player), diff.heart_piece_limit) // 4 \ + return min(state.count('Boss Heart Container', player), diff.boss_heart_container_limit) \ + + state.count('Sanctuary Heart Container', player) \ + + min(state.count('Piece of Heart', player), diff.heart_piece_limit) // 4 \ + 3 # starting hearts diff --git a/worlds/checksfinder/Rules.py b/worlds/checksfinder/Rules.py index 4e12668798dc..38d7d77ad393 100644 --- a/worlds/checksfinder/Rules.py +++ b/worlds/checksfinder/Rules.py @@ -1,37 +1,34 @@ -from ..generic.Rules import set_rule, add_rule -from BaseClasses import MultiWorld -from ..AutoWorld import LogicMixin +from ..generic.Rules import set_rule +from BaseClasses import MultiWorld, CollectionState -class ChecksFinderLogic(LogicMixin): - - def _has_total(self, player: int, total: int): - return (self.item_count('Map Width', player)+self.item_count('Map Height', player)+ - self.item_count('Map Bombs', player)) >= total +def _has_total(state: CollectionState, player: int, total: int): + return (state.count('Map Width', player) + state.count('Map Height', player) + + state.count('Map Bombs', player)) >= total # Sets rules on entrances and advancements that are always applied def set_rules(world: MultiWorld, player: int): - set_rule(world.get_location(("Tile 6"), player), lambda state: state._has_total(player, 1)) - set_rule(world.get_location(("Tile 7"), player), lambda state: state._has_total(player, 2)) - set_rule(world.get_location(("Tile 8"), player), lambda state: state._has_total(player, 3)) - set_rule(world.get_location(("Tile 9"), player), lambda state: state._has_total(player, 4)) - set_rule(world.get_location(("Tile 10"), player), lambda state: state._has_total(player, 5)) - set_rule(world.get_location(("Tile 11"), player), lambda state: state._has_total(player, 6)) - set_rule(world.get_location(("Tile 12"), player), lambda state: state._has_total(player, 7)) - set_rule(world.get_location(("Tile 13"), player), lambda state: state._has_total(player, 8)) - set_rule(world.get_location(("Tile 14"), player), lambda state: state._has_total(player, 9)) - set_rule(world.get_location(("Tile 15"), player), lambda state: state._has_total(player, 10)) - set_rule(world.get_location(("Tile 16"), player), lambda state: state._has_total(player, 11)) - set_rule(world.get_location(("Tile 17"), player), lambda state: state._has_total(player, 12)) - set_rule(world.get_location(("Tile 18"), player), lambda state: state._has_total(player, 13)) - set_rule(world.get_location(("Tile 19"), player), lambda state: state._has_total(player, 14)) - set_rule(world.get_location(("Tile 20"), player), lambda state: state._has_total(player, 15)) - set_rule(world.get_location(("Tile 21"), player), lambda state: state._has_total(player, 16)) - set_rule(world.get_location(("Tile 22"), player), lambda state: state._has_total(player, 17)) - set_rule(world.get_location(("Tile 23"), player), lambda state: state._has_total(player, 18)) - set_rule(world.get_location(("Tile 24"), player), lambda state: state._has_total(player, 19)) - set_rule(world.get_location(("Tile 25"), player), lambda state: state._has_total(player, 20)) + set_rule(world.get_location("Tile 6", player), lambda state: _has_total(state, player, 1)) + set_rule(world.get_location("Tile 7", player), lambda state: _has_total(state, player, 2)) + set_rule(world.get_location("Tile 8", player), lambda state: _has_total(state, player, 3)) + set_rule(world.get_location("Tile 9", player), lambda state: _has_total(state, player, 4)) + set_rule(world.get_location("Tile 10", player), lambda state: _has_total(state, player, 5)) + set_rule(world.get_location("Tile 11", player), lambda state: _has_total(state, player, 6)) + set_rule(world.get_location("Tile 12", player), lambda state: _has_total(state, player, 7)) + set_rule(world.get_location("Tile 13", player), lambda state: _has_total(state, player, 8)) + set_rule(world.get_location("Tile 14", player), lambda state: _has_total(state, player, 9)) + set_rule(world.get_location("Tile 15", player), lambda state: _has_total(state, player, 10)) + set_rule(world.get_location("Tile 16", player), lambda state: _has_total(state, player, 11)) + set_rule(world.get_location("Tile 17", player), lambda state: _has_total(state, player, 12)) + set_rule(world.get_location("Tile 18", player), lambda state: _has_total(state, player, 13)) + set_rule(world.get_location("Tile 19", player), lambda state: _has_total(state, player, 14)) + set_rule(world.get_location("Tile 20", player), lambda state: _has_total(state, player, 15)) + set_rule(world.get_location("Tile 21", player), lambda state: _has_total(state, player, 16)) + set_rule(world.get_location("Tile 22", player), lambda state: _has_total(state, player, 17)) + set_rule(world.get_location("Tile 23", player), lambda state: _has_total(state, player, 18)) + set_rule(world.get_location("Tile 24", player), lambda state: _has_total(state, player, 19)) + set_rule(world.get_location("Tile 25", player), lambda state: _has_total(state, player, 20)) # Sets rules on completion condition diff --git a/worlds/kh2/logic.py b/worlds/kh2/logic.py index 1c5883f5ce8a..10af4144a7fb 100644 --- a/worlds/kh2/logic.py +++ b/worlds/kh2/logic.py @@ -63,7 +63,7 @@ def kh_visit_locking_amount(self, player, amount): ItemName.MembershipCard, ItemName.IceCream, ItemName.WaytotheDawn, ItemName.IdentityDisk, ItemName.NamineSketches}: - visit += self.item_count(item, player) + visit += self.count(item, player) return visit >= amount def kh_three_proof_unlocked(self, player): diff --git a/worlds/noita/Rules.py b/worlds/noita/Rules.py index 808dd3a200a6..8190b80dc710 100644 --- a/worlds/noita/Rules.py +++ b/worlds/noita/Rules.py @@ -57,11 +57,11 @@ class EntranceLock(NamedTuple): def has_perk_count(state: CollectionState, player: int, amount: int) -> bool: - return sum(state.item_count(perk, player) for perk in perk_list) >= amount + return sum(state.count(perk, player) for perk in perk_list) >= amount def has_orb_count(state: CollectionState, player: int, amount: int) -> bool: - return state.item_count("Orb", player) >= amount + return state.count("Orb", player) >= amount def forbid_items_at_location(multiworld: MultiWorld, location_name: str, items: Set[str], player: int): diff --git a/worlds/overcooked2/Logic.py b/worlds/overcooked2/Logic.py index d8468cb59af1..20111aa01d66 100644 --- a/worlds/overcooked2/Logic.py +++ b/worlds/overcooked2/Logic.py @@ -18,7 +18,7 @@ def has_requirements_for_level_access(state: CollectionState, level_name: str, p return state.has(level_name, player) # Must have enough stars to purchase level - star_count = state.item_count("Star", player) + state.item_count("Bonus Star", player) + star_count = state.count("Star", player) + state.count("Bonus Star", player) if star_count < required_star_count: return False @@ -64,7 +64,7 @@ def meets_requirements(state: CollectionState, name: str, stars: int, player: in total: float = 0.0 for (item_name, weight) in additive_reqs: - for _ in range(0, state.item_count(item_name, player)): + for _ in range(0, state.count(item_name, player)): total += weight if total >= 0.99: # be nice to rounding errors :) return True diff --git a/worlds/rogue_legacy/Rules.py b/worlds/rogue_legacy/Rules.py index 90f6cc08b1fb..2fac8d561399 100644 --- a/worlds/rogue_legacy/Rules.py +++ b/worlds/rogue_legacy/Rules.py @@ -7,8 +7,8 @@ def get_upgrade_total(multiworld: MultiWorld, player: int) -> int: def get_upgrade_count(state: CollectionState, player: int) -> int: - return state.item_count("Health Up", player) + state.item_count("Mana Up", player) + \ - state.item_count("Attack Up", player) + state.item_count("Magic Damage Up", player) + return state.count("Health Up", player) + state.count("Mana Up", player) + \ + state.count("Attack Up", player) + state.count("Magic Damage Up", player) def has_vendors(state: CollectionState, player: int) -> bool: diff --git a/worlds/soe/Logic.py b/worlds/soe/Logic.py index e464b7fd3b8e..fe5339c955b9 100644 --- a/worlds/soe/Logic.py +++ b/worlds/soe/Logic.py @@ -18,7 +18,7 @@ class LogicProtocol(Protocol): def has(self, name: str, player: int) -> bool: ... - def item_count(self, name: str, player: int) -> int: ... + def count(self, name: str, player: int) -> int: ... def soe_has(self, progress: int, world: MultiWorld, player: int, count: int) -> bool: ... def _soe_count(self, progress: int, world: MultiWorld, player: int, max_count: int) -> int: ... @@ -35,7 +35,7 @@ def _soe_count(self: LogicProtocol, progress: int, world: MultiWorld, player: in for pvd in item.provides: if pvd[1] == progress: if self.has(item.name, player): - n += self.item_count(item.name, player) * pvd[0] + n += self.count(item.name, player) * pvd[0] if n >= max_count > 0: return n for rule in rules: diff --git a/worlds/spire/Rules.py b/worlds/spire/Rules.py index 7c8c1c0f3d86..3c6f09b34dce 100644 --- a/worlds/spire/Rules.py +++ b/worlds/spire/Rules.py @@ -5,11 +5,11 @@ class SpireLogic(LogicMixin): def _spire_has_relics(self, player: int, amount: int) -> bool: - count: int = self.item_count("Relic", player) + self.item_count("Boss Relic", player) + count: int = self.count("Relic", player) + self.count("Boss Relic", player) return count >= amount def _spire_has_cards(self, player: int, amount: int) -> bool: - count = self.item_count("Card Draw", player) + self.item_count("Rare Card Draw", player) + count = self.count("Card Draw", player) + self.count("Rare Card Draw", player) return count >= amount diff --git a/worlds/zillion/logic.py b/worlds/zillion/logic.py index e99867c742aa..12f1875b4047 100644 --- a/worlds/zillion/logic.py +++ b/worlds/zillion/logic.py @@ -38,7 +38,7 @@ def item_counts(cs: CollectionState, p: int) -> Tuple[Tuple[str, int], ...]: ((item_name, count), (item_name, count), ...) """ - return tuple((item_name, cs.item_count(item_name, p)) for item_name in item_name_to_id) + return tuple((item_name, cs.count(item_name, p)) for item_name in item_name_to_id) LogicCacheType = Dict[int, Tuple[_Counter[Tuple[str, int]], FrozenSet[Location]]]