diff --git a/BaseClasses.py b/BaseClasses.py index 209667e0..20d4f136 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -125,6 +125,7 @@ class World(object): set_player_attr('triforce_pieces_required', 20) set_player_attr('shop_shuffle', 'off') set_player_attr('shuffle_prizes', "g") + set_player_attr('sprite_pool', []) def secure(self): self.random = secrets.SystemRandom() @@ -1291,7 +1292,8 @@ class Spoiler(object): 'triforce_pieces_available': self.world.triforce_pieces_available, 'triforce_pieces_required': self.world.triforce_pieces_required, 'shop_shuffle': self.world.shop_shuffle, - 'shuffle_prizes': self.world.shuffle_prizes + 'shuffle_prizes': self.world.shuffle_prizes, + 'sprite_pool': self.world.sprite_pool } def to_json(self): diff --git a/EntranceRandomizer.py b/EntranceRandomizer.py index d74c9aaa..8ab9e097 100755 --- a/EntranceRandomizer.py +++ b/EntranceRandomizer.py @@ -315,6 +315,8 @@ def parse_arguments(argv, no_defaults=False): u: shuffle capacity upgrades into the item pool ''') parser.add_argument('--shuffle_prizes', default=defval('g'), choices=['', 'g', 'b', 'gb']) + parser.add_argument('--sprite_pool', help='''\ + Specifies a colon separated list of sprites used for random/randomonevent. If not specified, the full sprite pool is used.''') parser.add_argument('--remote_items', default=defval(False), action='store_true') parser.add_argument('--multi', default=defval(1), type=lambda value: min(max(int(value), 1), 255)) parser.add_argument('--names', default=defval('')) @@ -360,7 +362,7 @@ def parse_arguments(argv, no_defaults=False): 'heartbeep', "skip_progression_balancing", "triforce_pieces_available", "triforce_pieces_required", "shop_shuffle", 'remote_items', 'progressive', 'dungeon_counters', 'glitch_boots', 'killable_thieves', - 'tile_shuffle', 'bush_shuffle', 'shuffle_prizes']: + 'tile_shuffle', 'bush_shuffle', 'shuffle_prizes', 'sprite_pool']: value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) if player == 1: setattr(ret, name, {1: value}) diff --git a/Gui.py b/Gui.py index a0796088..861f3d9d 100755 --- a/Gui.py +++ b/Gui.py @@ -550,6 +550,7 @@ def guiMain(args=None): "bonk": "b", "general": "g", "both": "bg"}[prizeVar.get()] + guiargs.sprite_pool = [] guiargs.customitemarray = [int(bowVar.get()), int(silverarrowVar.get()), int(boomerangVar.get()), int(magicboomerangVar.get()), int(hookshotVar.get()), int(mushroomVar.get()), int(magicpowderVar.get()), int(firerodVar.get()), diff --git a/Main.py b/Main.py index 40cf81d0..ad71d6da 100644 --- a/Main.py +++ b/Main.py @@ -81,6 +81,7 @@ def main(args, seed=None): world.shop_shuffle = args.shop_shuffle.copy() world.progression_balancing = {player: not balance for player, balance in args.skip_progression_balancing.items()} world.shuffle_prizes = args.shuffle_prizes.copy() + world.sprite_pool = args.sprite_pool.copy() world.rom_seeds = {player: random.Random(world.random.randint(0, 999999999)) for player in range(1, world.players + 1)} diff --git a/Mystery.py b/Mystery.py index fbfa6c9e..70871d5a 100644 --- a/Mystery.py +++ b/Mystery.py @@ -468,6 +468,7 @@ def roll_settings(weights): if 'rom' in weights: romweights = weights['rom'] + ret.sprite_pool = romweights['sprite_pool'] if 'sprite_pool' in romweights else [] ret.sprite = get_choice('sprite', romweights, "Link") ret.disablemusic = get_choice('disablemusic', romweights, False) ret.quickswap = get_choice('quickswap', romweights, True) diff --git a/Rom.py b/Rom.py index 0164013c..355870ce 100644 --- a/Rom.py +++ b/Rom.py @@ -162,7 +162,7 @@ def check_enemizer(enemizercli): check_enemizer.done = True -def apply_random_sprite_on_event(rom: LocalRom, sprite, local_random, allow_random_on_event): +def apply_random_sprite_on_event(rom: LocalRom, sprite, local_random, allow_random_on_event, sprite_pool): onevent = onhit = 0 sprites = list() if not allow_random_on_event: @@ -192,7 +192,13 @@ def apply_random_sprite_on_event(rom: LocalRom, sprite, local_random, allow_rand _populate_sprite_table() if onevent: - sprites = list(set(_sprite_table.values())) # convert to list and remove dupes + if sprite_pool: + if isinstance(sprite_pool, str): + sprite_pool = sprite_pool.split(':') + for sprite in sprite_pool: + sprites.append(Sprite(sprite) if os.path.isfile(sprite) else get_sprite_from_name(sprite, local_random)) + else: + sprites = list(set(_sprite_table.values())) # convert to list and remove dupes else: sprites.append(sprite) if sprites: @@ -1464,7 +1470,7 @@ def hud_format_text(text): def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, sprite, ow_palettes, uw_palettes, world=None, player=1, allow_random_on_event=False): local_random = random if not world else world.rom_seeds[player] - apply_random_sprite_on_event(rom, sprite, local_random, allow_random_on_event) + apply_random_sprite_on_event(rom, sprite, local_random, allow_random_on_event, world.sprite_pool[player] if world else []) # enable instant item menu if fastmenu == 'instant': diff --git a/playerSettings.yaml b/playerSettings.yaml index 472a65c0..aebc18fa 100644 --- a/playerSettings.yaml +++ b/playerSettings.yaml @@ -286,6 +286,11 @@ debug: # Only available if the host uses the doors branch, it is ignored otherwi on: 0 # Enables debugging features. Currently, these are the Item collection counter. (overwrites total triforce pieces) and Castle Gate closed indicator. off: 50 rom: + #sprite_pool: # When specified, limits the pool of sprites used for randomon-event to the specified pool. Uncomment to use this. + # - link + # - pride link + # - penguin link + # - random # You can specify random multiple times for however many potentially unique random sprites you want in your pool. sprite: # Enter the name of your preferred sprite and weight it appropriately random: 0 randomonhit: 0 # Random sprite on hit