alttp: add item rules for prize locations (#1380)

This commit is contained in:
el-u 2023-01-14 14:29:54 +01:00 committed by GitHub
parent bd774a454e
commit 81d953daa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 1 deletions

View File

@ -1,9 +1,12 @@
import collections import collections
import logging import logging
from typing import Iterator, Set
from worlds.alttp import OverworldGlitchRules from worlds.alttp import OverworldGlitchRules
from BaseClasses import RegionType, MultiWorld, Entrance from BaseClasses import RegionType, MultiWorld, Entrance
from worlds.alttp.Items import ItemFactory, progression_items, item_name_groups from worlds.alttp.Items import ItemFactory, progression_items, item_name_groups, item_table
from worlds.alttp.OverworldGlitchRules import overworld_glitches_rules, no_logic_rules from worlds.alttp.OverworldGlitchRules import overworld_glitches_rules, no_logic_rules
from worlds.alttp.Regions import location_table
from worlds.alttp.UnderworldGlitchRules import underworld_glitches_rules from worlds.alttp.UnderworldGlitchRules import underworld_glitches_rules
from worlds.alttp.Bosses import GanonDefeatRule from worlds.alttp.Bosses import GanonDefeatRule
from worlds.generic.Rules import set_rule, add_rule, forbid_item, add_item_rule, item_in_locations, \ from worlds.generic.Rules import set_rule, add_rule, forbid_item, add_item_rule, item_in_locations, \
@ -176,6 +179,14 @@ def dungeon_boss_rules(world, player):
def global_rules(world, player): def global_rules(world, player):
# ganon can only carry triforce # ganon can only carry triforce
add_item_rule(world.get_location('Ganon', player), lambda item: item.name == 'Triforce' and item.player == player) add_item_rule(world.get_location('Ganon', player), lambda item: item.name == 'Triforce' and item.player == player)
# dungeon prizes can only be crystals/pendants
crystals_and_pendants: Set[str] = \
{item for item, item_data in item_table.items() if item_data.type == "Crystal"}
prize_locations: Iterator[str] = \
(locations for locations, location_data in location_table.items() if location_data[2] == True)
for prize_location in prize_locations:
add_item_rule(world.get_location(prize_location, player),
lambda item: item.name in crystals_and_pendants and item.player == player)
# determines which S&Q locations are available - hide from paths since it isn't an in-game location # determines which S&Q locations are available - hide from paths since it isn't an in-game location
world.get_region('Menu', player).can_reach_private = lambda state: True world.get_region('Menu', player).can_reach_private = lambda state: True
for exit in world.get_region('Menu', player).exits: for exit in world.get_region('Menu', player).exits:

View File

@ -0,0 +1,39 @@
from typing import List
from BaseClasses import Item, Location
from test.TestBase import WorldTestBase
class TestPrizes(WorldTestBase):
game = "A Link to the Past"
def test_item_rules(self):
prize_locations: List[Location] = [
self.multiworld.get_location("Eastern Palace - Prize", 1),
self.multiworld.get_location("Desert Palace - Prize", 1),
self.multiworld.get_location("Tower of Hera - Prize", 1),
self.multiworld.get_location("Palace of Darkness - Prize", 1),
self.multiworld.get_location("Swamp Palace - Prize", 1),
self.multiworld.get_location("Thieves\' Town - Prize", 1),
self.multiworld.get_location("Skull Woods - Prize", 1),
self.multiworld.get_location("Ice Palace - Prize", 1),
self.multiworld.get_location("Misery Mire - Prize", 1),
self.multiworld.get_location("Turtle Rock - Prize", 1),
]
prize_items: List[Item] = [
self.get_item_by_name("Green Pendant"),
self.get_item_by_name("Blue Pendant"),
self.get_item_by_name("Red Pendant"),
self.get_item_by_name("Crystal 1"),
self.get_item_by_name("Crystal 2"),
self.get_item_by_name("Crystal 3"),
self.get_item_by_name("Crystal 4"),
self.get_item_by_name("Crystal 5"),
self.get_item_by_name("Crystal 6"),
self.get_item_by_name("Crystal 7"),
]
for item in self.multiworld.get_items():
for prize_location in prize_locations:
self.assertEqual(item in prize_items, prize_location.item_rule(item),
f"{item} must {'' if item in prize_items else 'not '}be allowed in {prize_location}.")