Flute mode
And some odd fixes
This commit is contained in:
@@ -895,7 +895,7 @@ class CollectionState(object):
|
||||
'Golden Sword', 'Progressive Sword', 'Progressive Glove', 'Silver Arrows', 'Green Pendant',
|
||||
'Blue Pendant', 'Red Pendant', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5',
|
||||
'Crystal 6', 'Crystal 7', 'Blue Boomerang', 'Red Boomerang', 'Blue Shield', 'Red Shield',
|
||||
'Mirror Shield', 'Progressive Shield', 'Bug Catching Net', 'Cane of Byrna',
|
||||
'Mirror Shield', 'Progressive Shield', 'Bug Catching Net', 'Cane of Byrna', 'Ocarina (Activated)',
|
||||
'Boss Heart Container', 'Sanctuary Heart Container', 'Piece of Heart', 'Magic Upgrade (1/2)',
|
||||
'Magic Upgrade (1/4)']
|
||||
or item_name.startswith(('Bottle', 'Small Key', 'Big Key'))
|
||||
@@ -1129,8 +1129,11 @@ class CollectionState(object):
|
||||
return self.has('Fire Rod', player) or self.has('Lamp', player)
|
||||
|
||||
def can_flute(self, player):
|
||||
if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], self.world.precollected_items)):
|
||||
return True
|
||||
lw = self.world.get_region('Light World', player)
|
||||
return self.has('Ocarina', player) and lw.can_reach(self) and self.is_not_bunny(lw, player)
|
||||
return self.has('Ocarina (Activated)', player) or (self.has('Ocarina', player) and lw.can_reach(self)
|
||||
and self.is_not_bunny(lw, player))
|
||||
|
||||
def can_melt_things(self, player):
|
||||
return self.has('Fire Rod', player) or (self.has('Bombos', player) and self.has_sword(player))
|
||||
@@ -2371,6 +2374,7 @@ class Spoiler(object):
|
||||
'retro': self.world.retro,
|
||||
'bombbag': self.world.bombbag,
|
||||
'weapons': self.world.swords,
|
||||
'flute_mode': self.world.flute_mode,
|
||||
'goal': self.world.goal,
|
||||
'shuffle': self.world.shuffle,
|
||||
'shuffleganon': self.world.shuffle_ganon,
|
||||
@@ -2569,6 +2573,7 @@ class Spoiler(object):
|
||||
outfile.write(f"Restricted Boss Items: {self.metadata['restricted_boss_items'][player]}\n")
|
||||
outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player])
|
||||
outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player])
|
||||
outfile.write(f"Flute Mode: {self.metadata['flute_mode'][player]}\n")
|
||||
outfile.write(f"Shopsanity: {yn(self.metadata['shopsanity'][player])}\n")
|
||||
outfile.write(f"Bombbag: {yn(self.metadata['bombbag'][player])}\n")
|
||||
outfile.write(f"Pseudoboots: {yn(self.metadata['pseudoboots'][player])}\n")
|
||||
@@ -2873,6 +2878,8 @@ boss_mode = {"none": 0, "simple": 1, "full": 2, "chaos": 3, 'random': 3, 'unique
|
||||
|
||||
|
||||
# byte 10: settings_version
|
||||
# byte 11: F???, ???? (flute_mode)
|
||||
flute_mode = {'normal': 0, 'active': 1}
|
||||
|
||||
# additions
|
||||
# psuedoboots does not effect code
|
||||
@@ -2917,7 +2924,9 @@ class Settings(object):
|
||||
|
||||
(rb_mode[w.restrict_boss_items[p]] << 6) | (algo_mode[w.algorithm] << 3) | (boss_mode[w.boss_shuffle[p]]),
|
||||
|
||||
settings_version])
|
||||
settings_version,
|
||||
|
||||
flute_mode[w.flute_mode[p]] << 7])
|
||||
return base64.b64encode(code, "+-".encode()).decode()
|
||||
|
||||
@staticmethod
|
||||
@@ -2979,6 +2988,8 @@ class Settings(object):
|
||||
args.restrict_boss_items[p] = r(rb_mode)[(settings[9] & 0xC0) >> 6]
|
||||
args.algorithm = r(algo_mode)[(settings[9] & 0x38) >> 3]
|
||||
args.shufflebosses[p] = r(boss_mode)[(settings[9] & 0x07)]
|
||||
if len(settings) > 11:
|
||||
args.flute_mode[p] = r(flute_mode)[(settings[11] & 0x80) >> 7]
|
||||
|
||||
|
||||
class KeyRuleType(FastEnum):
|
||||
|
||||
2
CLI.py
2
CLI.py
@@ -115,6 +115,7 @@ def parse_cli(argv, no_defaults=False):
|
||||
playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True)
|
||||
|
||||
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality',
|
||||
'flute_mode',
|
||||
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
||||
'usestartinventory', 'bombbag', 'overworld_map', 'restrict_boss_items',
|
||||
@@ -156,6 +157,7 @@ def parse_settings():
|
||||
"crystals_gt": "7",
|
||||
"crystals_ganon": "7",
|
||||
"swords": "random",
|
||||
'flute_mode': 'normal',
|
||||
"difficulty": "normal",
|
||||
"item_functionality": "normal",
|
||||
"timer": "none",
|
||||
|
||||
@@ -834,7 +834,7 @@ def main_dungeon_pool(dungeon_pool, world, player):
|
||||
for name in pool:
|
||||
builder = world.dungeon_layouts[player][name]
|
||||
region_set = builder.master_sector.region_set()
|
||||
builder.bk_required = len(builder.bk_door_proposal) > 0 or any(x in region_set for x in special_bk_regions)
|
||||
builder.bk_required = builder.bk_door_proposal or any(x in region_set for x in special_bk_regions)
|
||||
dungeon = world.get_dungeon(name, player)
|
||||
if not builder.bk_required or builder.bk_provided:
|
||||
dungeon.big_key = None
|
||||
@@ -1793,7 +1793,7 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player)
|
||||
remaining -= len(custom_trap_doors[dungeon])
|
||||
ttl += len(builder.candidates.trap)
|
||||
if ttl == 0:
|
||||
return used_doors
|
||||
continue
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
proportion = len(builder.candidates.trap)
|
||||
@@ -1853,7 +1853,7 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world,
|
||||
remaining -= len(custom_bk_doors[dungeon])
|
||||
ttl += len(builder.candidates.big)
|
||||
if ttl == 0:
|
||||
return used_doors
|
||||
continue
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
proportion = len(builder.candidates.big)
|
||||
@@ -2004,7 +2004,7 @@ def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, worl
|
||||
remaining_dash -= len(custom_dash_doors[dungeon])
|
||||
ttl += len(builder.candidates.bomb_dash)
|
||||
if ttl == 0:
|
||||
return used_doors
|
||||
continue
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
proportion = len(builder.candidates.bomb_dash)
|
||||
@@ -2508,8 +2508,9 @@ def find_small_key_door_candidates(builder, start_regions, used, world, player):
|
||||
|
||||
|
||||
def calc_used_dungeon_items(builder, world, player):
|
||||
base = max(count_reserved_locations(world, player, builder.location_set), 2)
|
||||
basic_flag = world.doorShuffle[player] == 'basic'
|
||||
base = 0 if basic_flag else 2 # at least 2 items per dungeon, except in basic
|
||||
base = max(count_reserved_locations(world, player, builder.location_set), base)
|
||||
if not world.bigkeyshuffle[player]:
|
||||
if builder.bk_required and not builder.bk_provided:
|
||||
base += 1
|
||||
|
||||
@@ -144,6 +144,7 @@ class InitialSram:
|
||||
'Big Key (Ganons Tower)': (0x366, 0x04), 'Compass (Ganons Tower)': (0x364, 0x04), 'Map (Ganons Tower)': (0x368, 0x04)}
|
||||
set_or_table = {'Flippers': (0x356, 1, 0x379, 0x02),'Pegasus Boots': (0x355, 1, 0x379, 0x04),
|
||||
'Shovel': (0x34C, 1, 0x38C, 0x04), 'Ocarina': (0x34C, 3, 0x38C, 0x01),
|
||||
'Ocarina (Activated)': (0x34C, 3, 0x38C, 0x01),
|
||||
'Mushroom': (0x344, 1, 0x38C, 0x20 | 0x08), 'Magic Powder': (0x344, 2, 0x38C, 0x10),
|
||||
'Blue Boomerang': (0x341, 1, 0x38C, 0x80), 'Red Boomerang': (0x341, 2, 0x38C, 0x40)}
|
||||
keys = {'Small Key (Eastern Palace)': [0x37E], 'Small Key (Desert Palace)': [0x37F],
|
||||
|
||||
@@ -267,7 +267,7 @@ def generate_itempool(world, player):
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray)
|
||||
world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999)
|
||||
else:
|
||||
(pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player])
|
||||
(pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player], world.flute_mode[player] == 'active')
|
||||
|
||||
if player in world.pool_adjustment.keys() and not skip_pool_adjustments:
|
||||
amt = world.pool_adjustment[player]
|
||||
@@ -789,7 +789,8 @@ def add_pot_contents(world, player):
|
||||
world.itempool.append(ItemFactory(item, player))
|
||||
|
||||
|
||||
def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic):
|
||||
def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag,
|
||||
door_shuffle, logic, flute_activated):
|
||||
pool = []
|
||||
placed_items = {}
|
||||
precollected_items = []
|
||||
@@ -802,6 +803,10 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
|
||||
pool.extend(alwaysitems)
|
||||
|
||||
if flute_activated:
|
||||
pool.remove('Ocarina')
|
||||
pool.append('Ocarina (Activated)')
|
||||
|
||||
def place_item(loc, item):
|
||||
assert loc not in placed_items
|
||||
placed_items[loc] = item
|
||||
|
||||
1
Items.py
1
Items.py
@@ -30,6 +30,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
|
||||
'Hookshot': (True, False, None, 0x0A, 250, 'BOING!!!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'),
|
||||
'Magic Mirror': (True, False, None, 0x1A, 250, 'Isn\'t your\nreflection so\npretty?', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the mirror'),
|
||||
'Ocarina': (True, False, None, 0x14, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the flute'),
|
||||
'Ocarina (Activated)': (True, False, None, 0x4A, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the flute'),
|
||||
'Pegasus Boots': (True, False, None, 0x4B, 250, 'Gotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the boots'),
|
||||
'Power Glove': (True, False, None, 0x1B, 100, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the Glove'),
|
||||
'Cape': (True, False, None, 0x19, 50, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the cape'),
|
||||
|
||||
6
Main.py
6
Main.py
@@ -95,6 +95,7 @@ def main(args, seed=None, fish=None):
|
||||
world.keyshuffle = args.keyshuffle.copy()
|
||||
world.bigkeyshuffle = args.bigkeyshuffle.copy()
|
||||
world.bombbag = args.bombbag.copy()
|
||||
world.flute_mode = args.flute_mode.copy()
|
||||
world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)}
|
||||
world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)}
|
||||
world.crystals_ganon_orig = args.crystals_ganon.copy()
|
||||
@@ -158,7 +159,9 @@ def main(args, seed=None, fish=None):
|
||||
|
||||
if args.usestartinventory[player]:
|
||||
for tok in filter(None, args.startinventory[player].split(',')):
|
||||
item = ItemFactory(tok.strip(), player)
|
||||
name = tok.strip()
|
||||
name = name if name != 'Ocarina' or world.flute_mode[player] != 'active' else 'Ocarina (Activated)'
|
||||
item = ItemFactory(name, player)
|
||||
if item:
|
||||
world.push_precollected(item)
|
||||
|
||||
@@ -451,6 +454,7 @@ def copy_world(world):
|
||||
ret.keyshuffle = world.keyshuffle.copy()
|
||||
ret.bigkeyshuffle = world.bigkeyshuffle.copy()
|
||||
ret.bombbag = world.bombbag.copy()
|
||||
ret.flute_mode = world.flute_mode.copy()
|
||||
ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy()
|
||||
ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy()
|
||||
ret.crystals_ganon_orig = world.crystals_ganon_orig.copy()
|
||||
|
||||
5
Rom.py
5
Rom.py
@@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = '7b877dcee4ece38713768b74acb333a6'
|
||||
RANDOMIZERBASEHASH = '0be31dc5cb338e7e85d1ce65e839c99e'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -2161,8 +2161,8 @@ def write_strings(rom, world, player, team):
|
||||
while hint_count > 0 and len(items_to_hint) > 0:
|
||||
this_item = items_to_hint.pop(0)
|
||||
this_location = world.find_items_not_key_only(this_item, player)
|
||||
random.shuffle(this_location)
|
||||
if this_location:
|
||||
random.shuffle(this_location)
|
||||
item_name = this_location[0].item.hint_text
|
||||
item_name = item_name[0].upper() + item_name[1:]
|
||||
this_hint = f'{item_name} can be found {hint_text(this_location[0])}.'
|
||||
@@ -2847,6 +2847,7 @@ RelevantItems = ['Bow',
|
||||
'Hookshot',
|
||||
'Magic Mirror',
|
||||
'Ocarina',
|
||||
'Ocarina (Activated)',
|
||||
'Pegasus Boots',
|
||||
'Power Glove',
|
||||
'Cape',
|
||||
|
||||
30
Rules.py
30
Rules.py
@@ -786,9 +786,9 @@ def default_rules(world, player):
|
||||
set_rule(world.get_entrance('50 Rupee Cave', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Death Mountain Entrance Rock', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.has('Ocarina', player))
|
||||
set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.can_flute(player))
|
||||
set_rule(world.get_entrance('Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Ocarina', player) and state.can_lift_heavy_rocks(player))
|
||||
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.can_flute(player) and state.can_lift_heavy_rocks(player))
|
||||
set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||
set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||
set_rule(world.get_entrance('Kakariko Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player)) # bunny cannot lift bushes
|
||||
@@ -1514,7 +1514,7 @@ def set_big_bomb_rules(world, player):
|
||||
#2. Mirror and Flute and basic routes (can make difference if accessed via insanity or w/ mirror from connector, and then via hyrule castle gate, because no gloves are needed in that case)
|
||||
#3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
|
||||
# -> (Mitts and CPB) or (((G or Flute) and M) and BR))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and cross_peg_bridge(state)) or (((state.can_lift_rocks(player) or state.has('Ocarina', player)) and state.has_Mirror(player)) and basic_routes(state)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and cross_peg_bridge(state)) or (((state.can_lift_rocks(player) or state.can_flute(player)) and state.has_Mirror(player)) and basic_routes(state)))
|
||||
elif bombshop_entrance.name in Southern_DW_entrances:
|
||||
#1. Mirror and enter via gate: Need mirror and Aga1
|
||||
#2. cross peg bridge: Need hammer and moon pearl
|
||||
@@ -1523,52 +1523,52 @@ def set_big_bomb_rules(world, player):
|
||||
elif bombshop_entrance.name in Isolated_DW_entrances:
|
||||
# 1. mirror then flute then basic routes
|
||||
# -> M and Flute and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.has('Ocarina', player) and basic_routes(state))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.can_flute(player) and basic_routes(state))
|
||||
elif bombshop_entrance.name in Isolated_LW_entrances:
|
||||
# 1. flute then basic routes
|
||||
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
|
||||
# -> Flute and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Ocarina', player) and basic_routes(state))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and basic_routes(state))
|
||||
elif bombshop_entrance.name in West_LW_DM_entrances:
|
||||
# 1. flute then basic routes or mirror
|
||||
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly.
|
||||
# -> Flute and (M or BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Ocarina', player) and (state.has_Mirror(player) or basic_routes(state)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and (state.has_Mirror(player) or basic_routes(state)))
|
||||
elif bombshop_entrance.name in East_LW_DM_entrances:
|
||||
# 1. flute then basic routes or mirror and hookshot
|
||||
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly and then east DM via Hookshot
|
||||
# -> Flute and ((M and Hookshot) or BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Ocarina', player) and ((state.has_Mirror(player) and state.has('Hookshot', player)) or basic_routes(state)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and ((state.has_Mirror(player) and state.has('Hookshot', player)) or basic_routes(state)))
|
||||
elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)':
|
||||
# Same as East_LW_DM_entrances except navigation without BR requires Mitts
|
||||
# -> Flute and ((M and Hookshot and Mitts) or BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Ocarina', player) and ((state.has_Mirror(player) and state.has('Hookshot', player) and state.can_lift_heavy_rocks(player)) or basic_routes(state)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and ((state.has_Mirror(player) and state.has('Hookshot', player) and state.can_lift_heavy_rocks(player)) or basic_routes(state)))
|
||||
elif bombshop_entrance.name in Castle_ledge_entrances:
|
||||
# 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror
|
||||
# 2. flute then basic routes
|
||||
# -> M or (Flute and BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) or (state.has('Ocarina', player) and basic_routes(state)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) or (state.can_flute(player) and basic_routes(state)))
|
||||
elif bombshop_entrance.name in Desert_mirrorable_ledge_entrances:
|
||||
# Cases when you have mire access: Mirror to reach locations, return via mirror spot, move to center of desert, mirror anagin and:
|
||||
# 1. Have mire access, Mirror to reach locations, return via mirror spot, move to center of desert, mirror again and then basic routes
|
||||
# 2. flute then basic routes
|
||||
# -> (Mire access and M) or Flute) and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: ((state.can_reach('Dark Desert', 'Region', player) and state.has_Mirror(player)) or state.has('Ocarina', player)) and basic_routes(state))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: ((state.can_reach('Dark Desert', 'Region', player) and state.has_Mirror(player)) or state.can_flute(player)) and basic_routes(state))
|
||||
elif bombshop_entrance.name == 'Old Man Cave (West)':
|
||||
# 1. Lift rock then basic_routes
|
||||
# 2. flute then basic_routes
|
||||
# -> (Flute or G) and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Ocarina', player) or state.can_lift_rocks(player)) and basic_routes(state))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or state.can_lift_rocks(player)) and basic_routes(state))
|
||||
elif bombshop_entrance.name == 'Graveyard Cave':
|
||||
# 1. flute then basic routes
|
||||
# 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge
|
||||
# -> (Flute or (M and P and West Dark World access) and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Ocarina', player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state))
|
||||
elif bombshop_entrance.name in Mirror_from_SDW_entrances:
|
||||
# 1. flute then basic routes
|
||||
# 2. (has South dark world access) use existing mirror spot, mirror again off ledge
|
||||
# -> (Flute or (M and South Dark World access) and BR
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Ocarina', player) or (state.can_reach('South Dark World', 'Region', player) and state.has_Mirror(player))) and basic_routes(state))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('South Dark World', 'Region', player) and state.has_Mirror(player))) and basic_routes(state))
|
||||
elif bombshop_entrance.name == 'Dark World Potion Shop':
|
||||
# 1. walk down by lifting rock: needs gloves and pearl`
|
||||
# 2. walk down by hammering peg: needs hammer and pearl
|
||||
@@ -1580,11 +1580,11 @@ def set_big_bomb_rules(world, player):
|
||||
# (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot)
|
||||
# to account for insanity, must consider a way to escape without a cave for basic_routes
|
||||
# -> (M and Mitts) or ((Mitts or Flute or (M and P and West Dark World access)) and BR)
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) or ((state.can_lift_heavy_rocks(player) or state.has('Ocarina', player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) or ((state.can_lift_heavy_rocks(player) or state.can_flute(player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state)))
|
||||
elif bombshop_entrance.name == 'Waterfall of Wishing':
|
||||
# same as the Normal_LW_entrances case except in insanity it's possible you could be here without Flippers which
|
||||
# means you need an escape route of either Flippers or Flute
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.has('Ocarina', player)) and (basic_routes(state) or state.has_Mirror(player)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)) and (basic_routes(state) or state.has_Mirror(player)))
|
||||
|
||||
|
||||
def set_inverted_big_bomb_rules(world, player):
|
||||
|
||||
Binary file not shown.
@@ -45,6 +45,9 @@
|
||||
bombbag:
|
||||
on: 1
|
||||
off: 4
|
||||
flute_mode:
|
||||
normal: 3
|
||||
active: 1
|
||||
entrance_shuffle:
|
||||
none: 15
|
||||
dungeonssimple: 3
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
"vanilla"
|
||||
]
|
||||
},
|
||||
"flute_mode": {
|
||||
"choices": [
|
||||
"normal",
|
||||
"active"
|
||||
]
|
||||
},
|
||||
"goal": {
|
||||
"choices": [
|
||||
"ganon",
|
||||
|
||||
@@ -121,6 +121,11 @@
|
||||
"Hard: Reduced functionality.",
|
||||
"Expert: Greatly reduced functionality."
|
||||
],
|
||||
"flute_mode": [
|
||||
"Determine if you need to wake up the bird or not on flute pickup (default: %(default)s)",
|
||||
"Normal: Normal functionality.",
|
||||
"Active: Flute is activated on pickup."
|
||||
],
|
||||
"timer": [
|
||||
"Select game timer setting. Affects available itempool. (default: %(default)s)",
|
||||
"None: No timer.",
|
||||
|
||||
@@ -285,10 +285,9 @@
|
||||
|
||||
"randomizer.item.shopsanity": "Shopsanity",
|
||||
|
||||
"randomizer.item.itemfunction": "Item Functionality",
|
||||
"randomizer.item.itemfunction.normal": "Normal",
|
||||
"randomizer.item.itemfunction.hard": "Hard",
|
||||
"randomizer.item.itemfunction.expert": "Expert",
|
||||
"randomizer.item.flute_mode": "Flute Mode",
|
||||
"randomizer.item.flute_mode.normal": "Normal",
|
||||
"randomizer.item.flute_mode.active": "Pre-Activated",
|
||||
|
||||
"randomizer.item.timer": "Timer Setting",
|
||||
"randomizer.item.timer.none": "No Timer",
|
||||
@@ -298,11 +297,6 @@
|
||||
"randomizer.item.timer.ohko": "OHKO",
|
||||
"randomizer.item.timer.timed-countdown": "Timed Countdown",
|
||||
|
||||
"randomizer.item.progressives": "Progressive Items",
|
||||
"randomizer.item.progressives.on": "On",
|
||||
"randomizer.item.progressives.off": "Off",
|
||||
"randomizer.item.progressives.random": "Random",
|
||||
|
||||
"randomizer.item.accessibility": "Accessibility",
|
||||
"randomizer.item.accessibility.items": "100% Inventory",
|
||||
"randomizer.item.accessibility.locations": "100% Locations",
|
||||
|
||||
@@ -78,12 +78,11 @@
|
||||
"expert"
|
||||
]
|
||||
},
|
||||
"itemfunction": {
|
||||
"flute_mode": {
|
||||
"type": "selectbox",
|
||||
"options": [
|
||||
"normal",
|
||||
"hard",
|
||||
"expert"
|
||||
"active"
|
||||
]
|
||||
},
|
||||
"timer": {
|
||||
@@ -97,14 +96,6 @@
|
||||
"timed-countdown"
|
||||
]
|
||||
},
|
||||
"progressives": {
|
||||
"type": "selectbox",
|
||||
"options": [
|
||||
"on",
|
||||
"off",
|
||||
"random"
|
||||
]
|
||||
},
|
||||
"accessibility": {
|
||||
"type": "selectbox",
|
||||
"options": [
|
||||
|
||||
@@ -68,6 +68,7 @@ class CustomSettings(object):
|
||||
args.logic[p] = get_setting(settings['logic'], args.logic[p])
|
||||
args.mode[p] = get_setting(settings['mode'], args.mode[p])
|
||||
args.swords[p] = get_setting(settings['swords'], args.swords[p])
|
||||
args.flute_mode[p] = get_setting(settings['flute_mode'], args.flute_mode[p])
|
||||
args.item_functionality[p] = get_setting(settings['item_functionality'], args.item_functionality[p])
|
||||
args.goal[p] = get_setting(settings['goal'], args.goal[p])
|
||||
args.difficulty[p] = get_setting(settings['difficulty'], args.difficulty[p])
|
||||
@@ -189,6 +190,7 @@ class CustomSettings(object):
|
||||
settings_dict[p]['logic'] = world.logic[p]
|
||||
settings_dict[p]['mode'] = world.mode[p]
|
||||
settings_dict[p]['swords'] = world.swords[p]
|
||||
settings_dict[p]['flute_mode'] = world.flute_mode[p]
|
||||
settings_dict[p]['difficulty'] = world.difficulty[p]
|
||||
settings_dict[p]['goal'] = world.goal[p]
|
||||
settings_dict[p]['accessibility'] = world.accessibility[p]
|
||||
|
||||
@@ -67,9 +67,8 @@ SETTINGSTOPROCESS = {
|
||||
"crystals_ganon": "crystals_ganon",
|
||||
"weapons": "swords",
|
||||
"itempool": "difficulty",
|
||||
"itemfunction": "item_functionality",
|
||||
"flute_mode": "flute_mode",
|
||||
"timer": "timer",
|
||||
"progressives": "progressive",
|
||||
"accessibility": "accessibility",
|
||||
"sortingalgo": "algorithm",
|
||||
"beemizer": "beemizer",
|
||||
|
||||
@@ -454,6 +454,7 @@ vanilla_mapping = {
|
||||
'Hookshot': ['Swamp Palace - Big Chest'],
|
||||
'Magic Mirror': ['Old Man'],
|
||||
'Ocarina': ['Flute Spot'],
|
||||
'Ocarina (Activated)': ['Flute Spot'],
|
||||
'Pegasus Boots': ['Sahasrahla'],
|
||||
'Power Glove': ['Desert Palace - Big Chest'],
|
||||
'Cape': ["King's Tomb"],
|
||||
@@ -779,7 +780,7 @@ major_items = {'Bombos', 'Book of Mudora', 'Cane of Somaria', 'Ether', 'Fire Rod
|
||||
'Bug Catching Net', 'Cane of Byrna', 'Blue Boomerang', 'Red Boomerang', 'Progressive Glove',
|
||||
'Power Glove', 'Titans Mitts', 'Bottle', 'Bottle (Red Potion)', 'Bottle (Green Potion)', 'Magic Mirror',
|
||||
'Bottle (Blue Potion)', 'Bottle (Fairy)', 'Bottle (Bee)', 'Bottle (Good Bee)', 'Magic Upgrade (1/2)',
|
||||
'Sanctuary Heart Container', 'Boss Heart Container', 'Progressive Shield',
|
||||
'Sanctuary Heart Container', 'Boss Heart Container', 'Progressive Shield', 'Ocarina (Activated)',
|
||||
'Mirror Shield', 'Progressive Armor', 'Blue Mail', 'Red Mail', 'Progressive Sword', 'Fighter Sword',
|
||||
'Master Sword', 'Tempered Sword', 'Golden Sword', 'Bow', 'Silver Arrows', 'Triforce Piece', 'Moon Pearl',
|
||||
'Progressive Bow', 'Progressive Bow (Alt)'}
|
||||
|
||||
@@ -144,6 +144,7 @@ def roll_settings(weights):
|
||||
}[swords]
|
||||
|
||||
ret.difficulty = get_choice('item_pool')
|
||||
ret.flute_mode = get_choice_default('flute_mode', default='normal')
|
||||
|
||||
ret.item_functionality = get_choice('item_functionality')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user