make world-local items available as a general option
This commit is contained in:
		
							parent
							
								
									38cbcc662f
								
							
						
					
					
						commit
						e55726efca
					
				| 
						 | 
				
			
			@ -113,6 +113,7 @@ class World(object):
 | 
			
		|||
            set_player_attr('can_take_damage', True)
 | 
			
		||||
            set_player_attr('glitch_boots', True)
 | 
			
		||||
            set_player_attr('progression_balancing', True)
 | 
			
		||||
            set_player_attr('local_items', set())
 | 
			
		||||
 | 
			
		||||
    def get_name_string_for_object(self, obj) -> str:
 | 
			
		||||
        return obj.name if self.players == 1 else f'{obj.name} ({self.get_player_names(obj.player)})'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -236,7 +236,10 @@ def parse_arguments(argv, no_defaults=False):
 | 
			
		|||
                             Keys are universal, shooting arrows costs rupees,
 | 
			
		||||
                             and a few other little things make this more like Zelda-1.
 | 
			
		||||
                             ''', action='store_true')
 | 
			
		||||
    parser.add_argument('--startinventory', default=defval(''), help='Specifies a list of items that will be in your starting inventory (separated by commas)')
 | 
			
		||||
    parser.add_argument('--startinventory', default=defval(''),
 | 
			
		||||
                        help='Specifies a list of items that will be in your starting inventory (separated by commas)')
 | 
			
		||||
    parser.add_argument('--local_items', default=defval(''),
 | 
			
		||||
                        help='Specifies a list of items that will not spread across the multiworld (separated by commas)')
 | 
			
		||||
    parser.add_argument('--custom', default=defval(False), help='Not supported.')
 | 
			
		||||
    parser.add_argument('--customitemarray', default=defval(False), help='Not supported.')
 | 
			
		||||
    parser.add_argument('--accessibility', default=defval('items'), const='items', nargs='?', choices=['items', 'locations', 'none'], help='''\
 | 
			
		||||
| 
						 | 
				
			
			@ -323,7 +326,7 @@ def parse_arguments(argv, no_defaults=False):
 | 
			
		|||
            for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality',
 | 
			
		||||
                         'shuffle', 'crystals_ganon', 'crystals_gt', 'openpyramid', 'timer',
 | 
			
		||||
                         'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
 | 
			
		||||
                         'retro', 'accessibility', 'hints', 'beemizer',
 | 
			
		||||
                         'local_items', 'retro', 'accessibility', 'hints', 'beemizer',
 | 
			
		||||
                         'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots',
 | 
			
		||||
                         'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor',
 | 
			
		||||
                         'heartbeep', "skip_progression_balancing",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								Items.py
								
								
								
								
							
							
						
						
									
										27
									
								
								Items.py
								
								
								
								
							| 
						 | 
				
			
			@ -128,11 +128,11 @@ item_table = {'Bow': (True, False, None, 0x0B, 'You have\nchosen the\narcher cla
 | 
			
		|||
              'Compass (Escape)': (False, True, 'Compass', 0x8F, 'Now you can find no boss!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Hyrule Castle'),
 | 
			
		||||
              'Map (Escape)': (False, True, 'Map', 0x7F, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Hyrule Castle'),
 | 
			
		||||
              'Small Key (Agahnims Tower)': (False, False, 'SmallKey', 0xA4, 'A small key to Agahnim', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Castle Tower'),
 | 
			
		||||
               # doors-specific items, baserom will not be able to understand these
 | 
			
		||||
              # doors-specific items, baserom will not be able to understand these
 | 
			
		||||
              'Big Key (Agahnims Tower)': (False, False, 'BigKey', 0x9B, 'A big key to Agahnim', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Castle Tower'),
 | 
			
		||||
              'Compass (Agahnims Tower)': (False, True, 'Compass', 0x8B, 'Now you can find Aga1!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds null again', 'a compass to Castle Tower'),
 | 
			
		||||
              'Map (Agahnims Tower)': (False, True, 'Map', 0x7B, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Castle Tower'),
 | 
			
		||||
               # end of doors-specific items
 | 
			
		||||
              # end of doors-specific items
 | 
			
		||||
              'Small Key (Palace of Darkness)': (False, False, 'SmallKey', 0xA6, 'A small key to darkness', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Palace of Darkness'),
 | 
			
		||||
              'Big Key (Palace of Darkness)': (False, False, 'BigKey', 0x99, 'A big key to darkness', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Palace of Darkness'),
 | 
			
		||||
              'Compass (Palace of Darkness)': (False, True, 'Compass', 0x89, 'Now you can find Helmasaur King!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Palace of Darkness'),
 | 
			
		||||
| 
						 | 
				
			
			@ -183,4 +183,25 @@ item_table = {'Bow': (True, False, None, 0x0B, 'You have\nchosen the\narcher cla
 | 
			
		|||
 | 
			
		||||
lookup_id_to_name = {data[3]: name for name, data in item_table.items()}
 | 
			
		||||
 | 
			
		||||
hint_blacklist = {"Triforce"}
 | 
			
		||||
hint_blacklist = {"Triforce"}
 | 
			
		||||
 | 
			
		||||
item_name_groups = {"Bows": {"Bow", "Silver Arrows", "Progressive Bow (Alt)", "Progressive Bow"}}
 | 
			
		||||
# generic groups, (Name, substring)
 | 
			
		||||
_simple_groups = {("Swords", "Sword"),
 | 
			
		||||
 | 
			
		||||
                  ("Small Keys", "Small Key"),
 | 
			
		||||
                  ("Big Keys", "Big Key"),
 | 
			
		||||
                  ("Compasses", "Compass"),
 | 
			
		||||
                  ("Maps", "Map"),
 | 
			
		||||
 | 
			
		||||
                  ("Bottles", "Bottle"),
 | 
			
		||||
                  ("Potions", "Potion"),
 | 
			
		||||
                  ("Rupees", "Rupee")
 | 
			
		||||
                  }
 | 
			
		||||
for basename, substring in _simple_groups:
 | 
			
		||||
    tempset = item_name_groups[basename] = set()
 | 
			
		||||
    for itemname in item_table:
 | 
			
		||||
        if substring in itemname:
 | 
			
		||||
            tempset.add(itemname)
 | 
			
		||||
 | 
			
		||||
del (_simple_groups)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								Main.py
								
								
								
								
							
							
						
						
									
										1
									
								
								Main.py
								
								
								
								
							| 
						 | 
				
			
			@ -85,6 +85,7 @@ def main(args, seed=None):
 | 
			
		|||
            item = ItemFactory(tok.strip(), player)
 | 
			
		||||
            if item:
 | 
			
		||||
                world.push_precollected(item)
 | 
			
		||||
        world.local_items[player] = {item.strip() for item in args.local_items[player].split(',')}
 | 
			
		||||
 | 
			
		||||
        if world.mode[player] != 'inverted':
 | 
			
		||||
            create_regions(world, player)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								Mystery.py
								
								
								
								
							
							
						
						
									
										14
									
								
								Mystery.py
								
								
								
								
							| 
						 | 
				
			
			@ -14,6 +14,7 @@ from Utils import parse_yaml
 | 
			
		|||
from Rom import get_sprite_from_name
 | 
			
		||||
from EntranceRandomizer import parse_arguments
 | 
			
		||||
from Main import main as ERmain
 | 
			
		||||
from Items import item_name_groups, item_table
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -355,11 +356,22 @@ def roll_settings(weights):
 | 
			
		|||
                startitems.append(item)
 | 
			
		||||
        elif itemvalue:
 | 
			
		||||
            startitems.append(item)
 | 
			
		||||
    ret.glitch_boots = get_choice('glitch_boots', weights) if 'glitch_boots' in weights else True
 | 
			
		||||
    ret.startinventory = ','.join(startitems)
 | 
			
		||||
 | 
			
		||||
    ret.glitch_boots = get_choice('glitch_boots', weights) if 'glitch_boots' in weights else True
 | 
			
		||||
 | 
			
		||||
    ret.remote_items = get_choice('remote_items', weights) if 'remote_items' in weights else False
 | 
			
		||||
 | 
			
		||||
    ret.local_items = set()
 | 
			
		||||
    for item_name in weights.get('local_items', []):
 | 
			
		||||
        items = item_name_groups.get(item_name, {item_name})
 | 
			
		||||
        for item in items:
 | 
			
		||||
            if item in item_table:
 | 
			
		||||
                ret.local_items.add(item)
 | 
			
		||||
            else:
 | 
			
		||||
                logging.warning(f"Could not force item {item} to be world-local, as it was not recognized.")
 | 
			
		||||
    ret.local_items = ",".join(ret.local_items)
 | 
			
		||||
 | 
			
		||||
    if 'rom' in weights:
 | 
			
		||||
        romweights = weights['rom']
 | 
			
		||||
        ret.sprite = get_choice('sprite', romweights)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								Rules.py
								
								
								
								
							
							
						
						
									
										5
									
								
								Rules.py
								
								
								
								
							| 
						 | 
				
			
			@ -138,9 +138,12 @@ def global_rules(world, player):
 | 
			
		|||
    # ganon can only carry triforce
 | 
			
		||||
    add_item_rule(world.get_location('Ganon', player), lambda item: item.name == 'Triforce' and item.player == player)
 | 
			
		||||
    if world.goal[player] == "localtriforcehunt":
 | 
			
		||||
        world.local_items[player].add('Triforce Piece')
 | 
			
		||||
    if world.local_items[player]:
 | 
			
		||||
        for location in world.get_locations():
 | 
			
		||||
            if location.player != player:
 | 
			
		||||
                forbid_item(location, 'Triforce Piece', player)
 | 
			
		||||
                for item in world.local_items[player]:
 | 
			
		||||
                    forbid_item(location, item, player)
 | 
			
		||||
    # 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
 | 
			
		||||
    for exit in world.get_region('Menu', player).exits:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,6 +151,11 @@ timer:
 | 
			
		|||
  ohko: 0
 | 
			
		||||
  timed_countdown: 0
 | 
			
		||||
  display: 0
 | 
			
		||||
#can be uncommented to use it
 | 
			
		||||
#local_items: #force certain items to appear in your world only, not across the multiworld. Recognizes some group names, like "Swords"
 | 
			
		||||
#  - "Moon Pearl"
 | 
			
		||||
#  - "Small Keys"
 | 
			
		||||
#  - "Big Keys"
 | 
			
		||||
glitch_boots:
 | 
			
		||||
  on: 1 # enables that you start with Pegasus Boots in any glitched logic mode
 | 
			
		||||
  off: 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue