start moving some alttp options over to the new system
This commit is contained in:
parent
622f8f8158
commit
5ea03c71c0
|
@ -113,8 +113,6 @@ class MultiWorld():
|
||||||
set_player_attr('bush_shuffle', False)
|
set_player_attr('bush_shuffle', False)
|
||||||
set_player_attr('beemizer', 0)
|
set_player_attr('beemizer', 0)
|
||||||
set_player_attr('escape_assist', [])
|
set_player_attr('escape_assist', [])
|
||||||
set_player_attr('crystals_needed_for_ganon', 7)
|
|
||||||
set_player_attr('crystals_needed_for_gt', 7)
|
|
||||||
set_player_attr('open_pyramid', False)
|
set_player_attr('open_pyramid', False)
|
||||||
set_player_attr('treasure_hunt_icon', 'Triforce Piece')
|
set_player_attr('treasure_hunt_icon', 'Triforce Piece')
|
||||||
set_player_attr('treasure_hunt_count', 0)
|
set_player_attr('treasure_hunt_count', 0)
|
||||||
|
@ -131,7 +129,6 @@ class MultiWorld():
|
||||||
set_player_attr('triforce_pieces_available', 30)
|
set_player_attr('triforce_pieces_available', 30)
|
||||||
set_player_attr('triforce_pieces_required', 20)
|
set_player_attr('triforce_pieces_required', 20)
|
||||||
set_player_attr('shop_shuffle', 'off')
|
set_player_attr('shop_shuffle', 'off')
|
||||||
set_player_attr('shop_shuffle_slots', 0)
|
|
||||||
set_player_attr('shuffle_prizes', "g")
|
set_player_attr('shuffle_prizes', "g")
|
||||||
set_player_attr('sprite_pool', [])
|
set_player_attr('sprite_pool', [])
|
||||||
set_player_attr('dark_room_logic', "lamp")
|
set_player_attr('dark_room_logic', "lamp")
|
||||||
|
@ -141,9 +138,6 @@ class MultiWorld():
|
||||||
set_player_attr('plando_connections', [])
|
set_player_attr('plando_connections', [])
|
||||||
set_player_attr('game', "A Link to the Past")
|
set_player_attr('game', "A Link to the Past")
|
||||||
set_player_attr('completion_condition', lambda state: True)
|
set_player_attr('completion_condition', lambda state: True)
|
||||||
import Options
|
|
||||||
for hk_option in Options.hollow_knight_options:
|
|
||||||
set_player_attr(hk_option, False)
|
|
||||||
self.custom_data = {}
|
self.custom_data = {}
|
||||||
for player in range(1, players+1):
|
for player in range(1, players+1):
|
||||||
self.custom_data[player] = {}
|
self.custom_data[player] = {}
|
||||||
|
@ -1448,7 +1442,7 @@ class Spoiler(object):
|
||||||
'triforce_pieces_available': self.world.triforce_pieces_available,
|
'triforce_pieces_available': self.world.triforce_pieces_available,
|
||||||
'triforce_pieces_required': self.world.triforce_pieces_required,
|
'triforce_pieces_required': self.world.triforce_pieces_required,
|
||||||
'shop_shuffle': self.world.shop_shuffle,
|
'shop_shuffle': self.world.shop_shuffle,
|
||||||
'shop_shuffle_slots': self.world.shop_shuffle_slots,
|
'shop_item_slots': self.world.shop_item_slots,
|
||||||
'shuffle_prizes': self.world.shuffle_prizes,
|
'shuffle_prizes': self.world.shuffle_prizes,
|
||||||
'sprite_pool': self.world.sprite_pool,
|
'sprite_pool': self.world.sprite_pool,
|
||||||
'restrict_dungeon_item_on_boss': self.world.restrict_dungeon_item_on_boss,
|
'restrict_dungeon_item_on_boss': self.world.restrict_dungeon_item_on_boss,
|
||||||
|
@ -1565,8 +1559,8 @@ class Spoiler(object):
|
||||||
"f" in self.metadata["shop_shuffle"][player]))
|
"f" in self.metadata["shop_shuffle"][player]))
|
||||||
outfile.write('Custom Potion Shop: %s\n' %
|
outfile.write('Custom Potion Shop: %s\n' %
|
||||||
bool_to_text("w" in self.metadata["shop_shuffle"][player]))
|
bool_to_text("w" in self.metadata["shop_shuffle"][player]))
|
||||||
outfile.write('Shop Slots: %s\n' %
|
outfile.write('Shop Item Slots: %s\n' %
|
||||||
self.metadata["shop_shuffle_slots"][player])
|
self.metadata["shop_item_slots"][player])
|
||||||
outfile.write('Boss shuffle: %s\n' % self.metadata['boss_shuffle'][player])
|
outfile.write('Boss shuffle: %s\n' % self.metadata['boss_shuffle'][player])
|
||||||
outfile.write(
|
outfile.write(
|
||||||
'Enemy shuffle: %s\n' % bool_to_text(self.metadata['enemy_shuffle'][player]))
|
'Enemy shuffle: %s\n' % bool_to_text(self.metadata['enemy_shuffle'][player]))
|
||||||
|
|
2
Gui.py
2
Gui.py
|
@ -468,7 +468,7 @@ def guiMain(args=None):
|
||||||
if shopWitchShuffleVar.get():
|
if shopWitchShuffleVar.get():
|
||||||
guiargs.shop_shuffle += "w"
|
guiargs.shop_shuffle += "w"
|
||||||
if shopPoolShuffleVar.get():
|
if shopPoolShuffleVar.get():
|
||||||
guiargs.shop_shuffle_slots = 30
|
guiargs.shop_item_slots = 30
|
||||||
guiargs.shuffle_prizes = {"none": "",
|
guiargs.shuffle_prizes = {"none": "",
|
||||||
"bonk": "b",
|
"bonk": "b",
|
||||||
"general": "g",
|
"general": "g",
|
||||||
|
|
13
Main.py
13
Main.py
|
@ -94,8 +94,6 @@ def main(args, seed=None):
|
||||||
world.compassshuffle = args.compassshuffle.copy()
|
world.compassshuffle = args.compassshuffle.copy()
|
||||||
world.keyshuffle = args.keyshuffle.copy()
|
world.keyshuffle = args.keyshuffle.copy()
|
||||||
world.bigkeyshuffle = args.bigkeyshuffle.copy()
|
world.bigkeyshuffle = args.bigkeyshuffle.copy()
|
||||||
world.crystals_needed_for_ganon = args.crystals_ganon.copy()
|
|
||||||
world.crystals_needed_for_gt = args.crystals_gt.copy()
|
|
||||||
world.open_pyramid = args.open_pyramid.copy()
|
world.open_pyramid = args.open_pyramid.copy()
|
||||||
world.boss_shuffle = args.shufflebosses.copy()
|
world.boss_shuffle = args.shufflebosses.copy()
|
||||||
world.enemy_shuffle = args.enemy_shuffle.copy()
|
world.enemy_shuffle = args.enemy_shuffle.copy()
|
||||||
|
@ -117,7 +115,6 @@ def main(args, seed=None):
|
||||||
world.triforce_pieces_available = args.triforce_pieces_available.copy()
|
world.triforce_pieces_available = args.triforce_pieces_available.copy()
|
||||||
world.triforce_pieces_required = args.triforce_pieces_required.copy()
|
world.triforce_pieces_required = args.triforce_pieces_required.copy()
|
||||||
world.shop_shuffle = args.shop_shuffle.copy()
|
world.shop_shuffle = args.shop_shuffle.copy()
|
||||||
world.shop_shuffle_slots = args.shop_shuffle_slots.copy()
|
|
||||||
world.progression_balancing = args.progression_balancing.copy()
|
world.progression_balancing = args.progression_balancing.copy()
|
||||||
world.shuffle_prizes = args.shuffle_prizes.copy()
|
world.shuffle_prizes = args.shuffle_prizes.copy()
|
||||||
world.sprite_pool = args.sprite_pool.copy()
|
world.sprite_pool = args.sprite_pool.copy()
|
||||||
|
@ -130,12 +127,10 @@ def main(args, seed=None):
|
||||||
world.required_medallions = args.required_medallions.copy()
|
world.required_medallions = args.required_medallions.copy()
|
||||||
world.game = args.game.copy()
|
world.game = args.game.copy()
|
||||||
import Options
|
import Options
|
||||||
for hk_option in Options.hollow_knight_options:
|
for option_set in Options.option_sets:
|
||||||
setattr(world, hk_option, getattr(args, hk_option, {}))
|
for option in option_set:
|
||||||
for factorio_option in Options.factorio_options:
|
setattr(world, option, getattr(args, option, {}))
|
||||||
setattr(world, factorio_option, getattr(args, factorio_option, {}))
|
|
||||||
for minecraft_option in Options.minecraft_options:
|
|
||||||
setattr(world, minecraft_option, getattr(args, minecraft_option, {}))
|
|
||||||
world.glitch_triforce = args.glitch_triforce # This is enabled/disabled globally, no per player option.
|
world.glitch_triforce = args.glitch_triforce # This is enabled/disabled globally, no per player option.
|
||||||
|
|
||||||
world.rom_seeds = {player: random.Random(world.random.randint(0, 999999999)) for player in range(1, world.players + 1)}
|
world.rom_seeds = {player: random.Random(world.random.randint(0, 999999999)) for player in range(1, world.players + 1)}
|
||||||
|
|
14
Mystery.py
14
Mystery.py
|
@ -581,6 +581,12 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b
|
||||||
|
|
||||||
|
|
||||||
def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
|
def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
|
||||||
|
for option_name, option in Options.alttp_options.items():
|
||||||
|
if option_name in weights:
|
||||||
|
setattr(ret, option_name, option.from_any(get_choice(option_name, weights)))
|
||||||
|
else:
|
||||||
|
setattr(ret, option_name, option(option.default))
|
||||||
|
|
||||||
glitches_required = get_choice('glitches_required', weights)
|
glitches_required = get_choice('glitches_required', weights)
|
||||||
if glitches_required not in [None, 'none', 'no_logic', 'overworld_glitches', 'minor_glitches']:
|
if glitches_required not in [None, 'none', 'no_logic', 'overworld_glitches', 'minor_glitches']:
|
||||||
logging.warning("Only NMG, OWG and No Logic supported")
|
logging.warning("Only NMG, OWG and No Logic supported")
|
||||||
|
@ -632,12 +638,9 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
|
||||||
# fast ganon + ganon at hole
|
# fast ganon + ganon at hole
|
||||||
ret.open_pyramid = get_choice('open_pyramid', weights, 'goal')
|
ret.open_pyramid = get_choice('open_pyramid', weights, 'goal')
|
||||||
|
|
||||||
ret.crystals_gt = Options.Crystals.from_any(get_choice('tower_open', weights)).value
|
|
||||||
ret.crystals_ganon = Options.Crystals.from_any(get_choice('ganon_open', weights)).value
|
|
||||||
|
|
||||||
extra_pieces = get_choice('triforce_pieces_mode', weights, 'available')
|
extra_pieces = get_choice('triforce_pieces_mode', weights, 'available')
|
||||||
|
|
||||||
ret.triforce_pieces_required = Options.TriforcePieces.from_any(get_choice('triforce_pieces_required', weights)).value
|
ret.triforce_pieces_required = Options.TriforcePieces.from_any(get_choice('triforce_pieces_required', weights))
|
||||||
|
|
||||||
# sum a percentage to required
|
# sum a percentage to required
|
||||||
if extra_pieces == 'percentage':
|
if extra_pieces == 'percentage':
|
||||||
|
@ -645,7 +648,7 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
|
||||||
ret.triforce_pieces_available = int(round(ret.triforce_pieces_required * percentage, 0))
|
ret.triforce_pieces_available = int(round(ret.triforce_pieces_required * percentage, 0))
|
||||||
# vanilla mode (specify how many pieces are)
|
# vanilla mode (specify how many pieces are)
|
||||||
elif extra_pieces == 'available':
|
elif extra_pieces == 'available':
|
||||||
ret.triforce_pieces_available = Options.TriforcePieces.from_any(get_choice('triforce_pieces_available', weights)).value
|
ret.triforce_pieces_available = Options.TriforcePieces.from_any(get_choice('triforce_pieces_available', weights))
|
||||||
# required pieces + fixed extra
|
# required pieces + fixed extra
|
||||||
elif extra_pieces == 'extra':
|
elif extra_pieces == 'extra':
|
||||||
extra_pieces = max(0, int(get_choice('triforce_pieces_extra', weights, 10)))
|
extra_pieces = max(0, int(get_choice('triforce_pieces_extra', weights, 10)))
|
||||||
|
@ -653,7 +656,6 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
|
||||||
|
|
||||||
# change minimum to required pieces to avoid problems
|
# change minimum to required pieces to avoid problems
|
||||||
ret.triforce_pieces_available = min(max(ret.triforce_pieces_required, int(ret.triforce_pieces_available)), 90)
|
ret.triforce_pieces_available = min(max(ret.triforce_pieces_required, int(ret.triforce_pieces_available)), 90)
|
||||||
ret.shop_shuffle_slots = Options.TriforcePieces.from_any(get_choice('shop_shuffle_slots', weights)).value
|
|
||||||
|
|
||||||
ret.shop_shuffle = get_choice('shop_shuffle', weights, '')
|
ret.shop_shuffle = get_choice('shop_shuffle', weights, '')
|
||||||
if not ret.shop_shuffle:
|
if not ret.shop_shuffle:
|
||||||
|
|
33
Options.py
33
Options.py
|
@ -8,6 +8,7 @@ class AssembleOptions(type):
|
||||||
options = attrs["options"] = {}
|
options = attrs["options"] = {}
|
||||||
name_lookup = attrs["name_lookup"] = {}
|
name_lookup = attrs["name_lookup"] = {}
|
||||||
for base in bases:
|
for base in bases:
|
||||||
|
if hasattr(base, "options"):
|
||||||
options.update(base.options)
|
options.update(base.options)
|
||||||
name_lookup.update(name_lookup)
|
name_lookup.update(name_lookup)
|
||||||
new_options = {name[7:].lower(): option_id for name, option_id in attrs.items() if
|
new_options = {name[7:].lower(): option_id for name, option_id in attrs.items() if
|
||||||
|
@ -110,7 +111,7 @@ class Choice(Option):
|
||||||
return cls.from_text(str(data))
|
return cls.from_text(str(data))
|
||||||
|
|
||||||
|
|
||||||
class Range(Option):
|
class Range(Option, int):
|
||||||
range_start = 0
|
range_start = 0
|
||||||
range_end = 1
|
range_end = 1
|
||||||
|
|
||||||
|
@ -119,7 +120,7 @@ class Range(Option):
|
||||||
raise Exception(f"{value} is lower than minimum {self.range_start} for option {self.__class__.__name__}")
|
raise Exception(f"{value} is lower than minimum {self.range_start} for option {self.__class__.__name__}")
|
||||||
elif value > self.range_end:
|
elif value > self.range_end:
|
||||||
raise Exception(f"{value} is higher than maximum {self.range_end} for option {self.__class__.__name__}")
|
raise Exception(f"{value} is higher than maximum {self.range_end} for option {self.__class__.__name__}")
|
||||||
self.value: int = value
|
self.value = value
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_text(cls, text: str) -> Range:
|
def from_text(cls, text: str) -> Range:
|
||||||
|
@ -139,6 +140,9 @@ class Range(Option):
|
||||||
return cls(data)
|
return cls(data)
|
||||||
return cls.from_text(str(data))
|
return cls.from_text(str(data))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.value)
|
||||||
|
|
||||||
|
|
||||||
class OptionNameSet(Option):
|
class OptionNameSet(Option):
|
||||||
default = frozenset()
|
default = frozenset()
|
||||||
|
@ -210,12 +214,20 @@ class Crystals(Range):
|
||||||
range_end = 7
|
range_end = 7
|
||||||
|
|
||||||
|
|
||||||
|
class CrystalsTower(Crystals):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CrystalsGanon(Crystals):
|
||||||
|
default = 7
|
||||||
|
|
||||||
|
|
||||||
class TriforcePieces(Range):
|
class TriforcePieces(Range):
|
||||||
range_start = 1
|
range_start = 1
|
||||||
range_end = 90
|
range_end = 90
|
||||||
|
|
||||||
|
|
||||||
class ShopShuffleSlots(Range):
|
class ShopItemSlots(Range):
|
||||||
range_start = 0
|
range_start = 0
|
||||||
range_end = 30
|
range_end = 30
|
||||||
|
|
||||||
|
@ -240,6 +252,12 @@ class Enemies(Choice):
|
||||||
option_chaos = 2
|
option_chaos = 2
|
||||||
|
|
||||||
|
|
||||||
|
alttp_options: typing.Dict[str, type(Option)] = {
|
||||||
|
"crystals_needed_for_gt": CrystalsTower,
|
||||||
|
"crystals_needed_for_ganon": CrystalsGanon,
|
||||||
|
"shop_item_slots": ShopItemSlots,
|
||||||
|
}
|
||||||
|
|
||||||
mapshuffle = Toggle
|
mapshuffle = Toggle
|
||||||
compassshuffle = Toggle
|
compassshuffle = Toggle
|
||||||
keyshuffle = Toggle
|
keyshuffle = Toggle
|
||||||
|
@ -268,7 +286,7 @@ RandomizeLoreTablets = Toggle
|
||||||
RandomizeLifebloodCocoons = Toggle
|
RandomizeLifebloodCocoons = Toggle
|
||||||
RandomizeFlames = Toggle
|
RandomizeFlames = Toggle
|
||||||
|
|
||||||
hollow_knight_randomize_options: typing.Dict[str, Option] = {
|
hollow_knight_randomize_options: typing.Dict[str, type(Option)] = {
|
||||||
"RandomizeDreamers": RandomizeDreamers,
|
"RandomizeDreamers": RandomizeDreamers,
|
||||||
"RandomizeSkills": RandomizeSkills,
|
"RandomizeSkills": RandomizeSkills,
|
||||||
"RandomizeCharms": RandomizeCharms,
|
"RandomizeCharms": RandomizeCharms,
|
||||||
|
@ -409,6 +427,13 @@ minecraft_options: typing.Dict[str, type(Option)] = {
|
||||||
"shuffle_structures": Toggle
|
"shuffle_structures": Toggle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
option_sets = (
|
||||||
|
minecraft_options,
|
||||||
|
factorio_options,
|
||||||
|
alttp_options,
|
||||||
|
hollow_knight_options
|
||||||
|
)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ triforce_pieces_required: # Set to how many out of X triforce pieces you need to
|
||||||
30: 0
|
30: 0
|
||||||
40: 0
|
40: 0
|
||||||
50: 0
|
50: 0
|
||||||
tower_open: # Crystals required to open GT
|
crystals_needed_for_gt: # Crystals required to open GT
|
||||||
0: 0
|
0: 0
|
||||||
1: 0
|
1: 0
|
||||||
2: 0
|
2: 0
|
||||||
|
@ -232,7 +232,7 @@ tower_open: # Crystals required to open GT
|
||||||
random: 0
|
random: 0
|
||||||
random-low: 50 # any valid number, weighted towards the lower end
|
random-low: 50 # any valid number, weighted towards the lower end
|
||||||
random-high: 0
|
random-high: 0
|
||||||
ganon_open: # Crystals required to hurt Ganon
|
crystals_needed_for_ganon: # Crystals required to hurt Ganon
|
||||||
0: 0
|
0: 0
|
||||||
1: 0
|
1: 0
|
||||||
2: 0
|
2: 0
|
||||||
|
@ -317,7 +317,7 @@ beemizer: # Remove items from the global item pool and replace them with single
|
||||||
4: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 90% are traps and 10% single bees
|
4: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 90% are traps and 10% single bees
|
||||||
5: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 100% are traps and 0% single bees
|
5: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 100% are traps and 0% single bees
|
||||||
### Shop Settings ###
|
### Shop Settings ###
|
||||||
shop_shuffle_slots: # Maximum amount of shop slots to be filled with regular item pool items (such as Moon Pearl)
|
shop_item_slots: # Maximum amount of shop slots to be filled with regular item pool items (such as Moon Pearl)
|
||||||
0: 50
|
0: 50
|
||||||
5: 0
|
5: 0
|
||||||
15: 0
|
15: 0
|
||||||
|
|
|
@ -196,22 +196,6 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
The dungeon variants only mix up dungeons and keep the rest of
|
The dungeon variants only mix up dungeons and keep the rest of
|
||||||
the overworld vanilla.
|
the overworld vanilla.
|
||||||
''')
|
''')
|
||||||
parser.add_argument('--crystals_ganon', default=defval('7'), const='7', nargs='?', choices=['random', '0', '1', '2', '3', '4', '5', '6', '7'],
|
|
||||||
help='''\
|
|
||||||
How many crystals are needed to defeat ganon. Any other
|
|
||||||
requirements for ganon for the selected goal still apply.
|
|
||||||
This setting does not apply when the all dungeons goal is
|
|
||||||
selected. (default: %(default)s)
|
|
||||||
Random: Picks a random value between 0 and 7 (inclusive).
|
|
||||||
0-7: Number of crystals needed
|
|
||||||
''')
|
|
||||||
parser.add_argument('--crystals_gt', default=defval('7'), const='7', nargs='?',
|
|
||||||
choices=['0', '1', '2', '3', '4', '5', '6', '7'],
|
|
||||||
help='''\
|
|
||||||
How many crystals are needed to open GT. For inverted mode
|
|
||||||
this applies to the castle tower door instead. (default: %(default)s)
|
|
||||||
0-7: Number of crystals needed
|
|
||||||
''')
|
|
||||||
parser.add_argument('--open_pyramid', default=defval('auto'), help='''\
|
parser.add_argument('--open_pyramid', default=defval('auto'), help='''\
|
||||||
Pre-opens the pyramid hole, this removes the Agahnim 2 requirement for it.
|
Pre-opens the pyramid hole, this removes the Agahnim 2 requirement for it.
|
||||||
Depending on goal, you might still need to beat Agahnim 2 in order to beat ganon.
|
Depending on goal, you might still need to beat Agahnim 2 in order to beat ganon.
|
||||||
|
@ -337,11 +321,6 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
u: shuffle capacity upgrades into the item pool
|
u: shuffle capacity upgrades into the item pool
|
||||||
w: consider witch's hut like any other shop and shuffle/randomize it too
|
w: consider witch's hut like any other shop and shuffle/randomize it too
|
||||||
''')
|
''')
|
||||||
parser.add_argument('--shop_shuffle_slots', default=defval(0),
|
|
||||||
type=lambda value: min(max(int(value), 1), 96),
|
|
||||||
help='''
|
|
||||||
Maximum amount of shop slots able to be filled by items from the item pool.
|
|
||||||
''')
|
|
||||||
parser.add_argument('--shuffle_prizes', default=defval('g'), choices=['', 'g', 'b', 'gb'])
|
parser.add_argument('--shuffle_prizes', default=defval('g'), choices=['', 'g', 'b', 'gb'])
|
||||||
parser.add_argument('--sprite_pool', help='''\
|
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.''')
|
Specifies a colon separated list of sprites used for random/randomonevent. If not specified, the full sprite pool is used.''')
|
||||||
|
@ -397,14 +376,14 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
playerargs = parse_arguments(shlex.split(getattr(ret, f"p{player}")), True)
|
playerargs = parse_arguments(shlex.split(getattr(ret, f"p{player}")), True)
|
||||||
|
|
||||||
for name in ['logic', 'mode', 'swordless', 'goal', 'difficulty', 'item_functionality',
|
for name in ['logic', 'mode', 'swordless', 'goal', 'difficulty', 'item_functionality',
|
||||||
'shuffle', 'crystals_ganon', 'crystals_gt', 'open_pyramid', 'timer',
|
'shuffle', 'open_pyramid', 'timer',
|
||||||
'countdown_start_time', 'red_clock_time', 'blue_clock_time', 'green_clock_time',
|
'countdown_start_time', 'red_clock_time', 'blue_clock_time', 'green_clock_time',
|
||||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
||||||
'local_items', 'non_local_items', 'retro', 'accessibility', 'hints', 'beemizer',
|
'local_items', 'non_local_items', 'retro', 'accessibility', 'hints', 'beemizer',
|
||||||
'shufflebosses', 'enemy_shuffle', 'enemy_health', 'enemy_damage', 'shufflepots',
|
'shufflebosses', 'enemy_shuffle', 'enemy_health', 'enemy_damage', 'shufflepots',
|
||||||
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor',
|
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor',
|
||||||
'heartbeep', "progression_balancing", "triforce_pieces_available",
|
'heartbeep', "progression_balancing", "triforce_pieces_available",
|
||||||
"triforce_pieces_required", "shop_shuffle", "shop_shuffle_slots",
|
"triforce_pieces_required", "shop_shuffle",
|
||||||
"required_medallions", "start_hints",
|
"required_medallions", "start_hints",
|
||||||
"plando_items", "plando_texts", "plando_connections", "er_seeds",
|
"plando_items", "plando_texts", "plando_connections", "er_seeds",
|
||||||
'progressive', 'dungeon_counters', 'glitch_boots', 'killable_thieves',
|
'progressive', 'dungeon_counters', 'glitch_boots', 'killable_thieves',
|
||||||
|
|
|
@ -885,7 +885,7 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
credits_total = 216
|
credits_total = 216
|
||||||
if world.retro[player]: # Old man cave and Take any caves will count towards collection rate.
|
if world.retro[player]: # Old man cave and Take any caves will count towards collection rate.
|
||||||
credits_total += 5
|
credits_total += 5
|
||||||
if world.shop_shuffle_slots[player]: # Potion shop only counts towards collection rate if included in the shuffle.
|
if world.shop_item_slots[player]: # Potion shop only counts towards collection rate if included in the shuffle.
|
||||||
credits_total += 30 if 'w' in world.shop_shuffle[player] else 27
|
credits_total += 30 if 'w' in world.shop_shuffle[player] else 27
|
||||||
|
|
||||||
rom.write_byte(0x187010, credits_total) # dynamic credits
|
rom.write_byte(0x187010, credits_total) # dynamic credits
|
||||||
|
@ -1705,7 +1705,7 @@ def write_custom_shops(rom, world, player):
|
||||||
slot = 0 if shop.type == ShopType.TakeAny else index
|
slot = 0 if shop.type == ShopType.TakeAny else index
|
||||||
if item is None:
|
if item is None:
|
||||||
break
|
break
|
||||||
if world.shop_shuffle_slots[player] or shop.type == ShopType.TakeAny:
|
if world.shop_item_slots[player] or shop.type == ShopType.TakeAny:
|
||||||
count_shop = (shop.region.name != 'Potion Shop' or 'w' in world.shop_shuffle[player]) and \
|
count_shop = (shop.region.name != 'Potion Shop' or 'w' in world.shop_shuffle[player]) and \
|
||||||
shop.region.name != 'Capacity Upgrade'
|
shop.region.name != 'Capacity Upgrade'
|
||||||
rom.write_byte(0x186560 + shop.sram_offset + slot, 1 if count_shop else 0)
|
rom.write_byte(0x186560 + shop.sram_offset + slot, 1 if count_shop else 0)
|
||||||
|
|
|
@ -243,7 +243,7 @@ def create_shops(world, player: int):
|
||||||
else:
|
else:
|
||||||
dynamic_shop_slots = total_dynamic_shop_slots
|
dynamic_shop_slots = total_dynamic_shop_slots
|
||||||
|
|
||||||
num_slots = min(dynamic_shop_slots, max(0, int(world.shop_shuffle_slots[player]))) # 0 to 30
|
num_slots = min(dynamic_shop_slots, world.shop_item_slots[player])
|
||||||
single_purchase_slots: List[bool] = [True] * num_slots + [False] * (dynamic_shop_slots - num_slots)
|
single_purchase_slots: List[bool] = [True] * num_slots + [False] * (dynamic_shop_slots - num_slots)
|
||||||
world.random.shuffle(single_purchase_slots)
|
world.random.shuffle(single_purchase_slots)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue