Trinity goal added
This commit is contained in:
@@ -2535,7 +2535,7 @@ class Spoiler(object):
|
|||||||
outfile.write('Retro: %s\n' % ('Yes' if self.metadata['retro'][player] else 'No'))
|
outfile.write('Retro: %s\n' % ('Yes' if self.metadata['retro'][player] else 'No'))
|
||||||
outfile.write('Swords: %s\n' % self.metadata['weapons'][player])
|
outfile.write('Swords: %s\n' % self.metadata['weapons'][player])
|
||||||
outfile.write('Goal: %s\n' % self.metadata['goal'][player])
|
outfile.write('Goal: %s\n' % self.metadata['goal'][player])
|
||||||
if self.metadata['goal'][player] == 'triforcehunt':
|
if self.metadata['goal'][player] in ['triforcehunt', 'trinity']:
|
||||||
outfile.write('Triforce Pieces Required: %s\n' % self.metadata['triforcegoal'][player])
|
outfile.write('Triforce Pieces Required: %s\n' % self.metadata['triforcegoal'][player])
|
||||||
outfile.write('Triforce Pieces Total: %s\n' % self.metadata['triforcepool'][player])
|
outfile.write('Triforce Pieces Total: %s\n' % self.metadata['triforcepool'][player])
|
||||||
outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player])
|
outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player])
|
||||||
@@ -2551,7 +2551,8 @@ class Spoiler(object):
|
|||||||
outfile.write('Crystals required for GT: %s\n' % (str(self.metadata['gt_crystals'][player]) + addition))
|
outfile.write('Crystals required for GT: %s\n' % (str(self.metadata['gt_crystals'][player]) + addition))
|
||||||
addition = ' (Random)' if self.world.crystals_ganon_orig[player] == 'random' else ''
|
addition = ' (Random)' if self.world.crystals_ganon_orig[player] == 'random' else ''
|
||||||
outfile.write('Crystals required for Ganon: %s\n' % (str(self.metadata['ganon_crystals'][player]) + addition))
|
outfile.write('Crystals required for Ganon: %s\n' % (str(self.metadata['ganon_crystals'][player]) + addition))
|
||||||
outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No'))
|
if self.metadata['goal'][player] != 'trinity':
|
||||||
|
outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No'))
|
||||||
outfile.write('Accessibility: %s\n' % self.metadata['accessibility'][player])
|
outfile.write('Accessibility: %s\n' % self.metadata['accessibility'][player])
|
||||||
outfile.write(f"Restricted Boss Items: {self.metadata['restricted_boss_items'][player]}\n")
|
outfile.write(f"Restricted Boss Items: {self.metadata['restricted_boss_items'][player]}\n")
|
||||||
outfile.write('Map shuffle: %s\n' % ('Yes' if self.metadata['mapshuffle'][player] else 'No'))
|
outfile.write('Map shuffle: %s\n' % ('Yes' if self.metadata['mapshuffle'][player] else 'No'))
|
||||||
@@ -2754,7 +2755,7 @@ world_mode = {"open": 0, "standard": 1, "inverted": 2}
|
|||||||
sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3}
|
sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3}
|
||||||
|
|
||||||
# byte 2: GGGD DFFH (goal, diff, item_func, hints)
|
# byte 2: GGGD DFFH (goal, diff, item_func, hints)
|
||||||
goal_mode = {"ganon": 0, "pedestal": 1, "dungeons": 2, "triforcehunt": 3, "crystals": 4}
|
goal_mode = {'ganon': 0, 'pedestal': 1, 'dungeons': 2, 'triforcehunt': 3, 'crystals': 4, 'trinity': 5}
|
||||||
diff_mode = {"normal": 0, "hard": 1, "expert": 2}
|
diff_mode = {"normal": 0, "hard": 1, "expert": 2}
|
||||||
func_mode = {"normal": 0, "hard": 1, "expert": 2}
|
func_mode = {"normal": 0, "hard": 1, "expert": 2}
|
||||||
|
|
||||||
|
|||||||
4
CLI.py
4
CLI.py
@@ -179,8 +179,8 @@ def parse_settings():
|
|||||||
"mixed_travel": "prevent",
|
"mixed_travel": "prevent",
|
||||||
"standardize_palettes": "standardize",
|
"standardize_palettes": "standardize",
|
||||||
|
|
||||||
"triforce_pool": 30,
|
"triforce_pool": 0,
|
||||||
"triforce_goal": 20,
|
"triforce_goal": 0,
|
||||||
"triforce_pool_min": 0,
|
"triforce_pool_min": 0,
|
||||||
"triforce_pool_max": 0,
|
"triforce_pool_max": 0,
|
||||||
"triforce_goal_min": 0,
|
"triforce_goal_min": 0,
|
||||||
|
|||||||
5
Fill.py
5
Fill.py
@@ -392,7 +392,10 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
|||||||
else:
|
else:
|
||||||
max_trash = gt_count
|
max_trash = gt_count
|
||||||
scaled_trash = math.floor(max_trash * scale_factor)
|
scaled_trash = math.floor(max_trash * scale_factor)
|
||||||
gftower_trash_count = (random.randint(scaled_trash, max_trash) if world.goal[player] == 'triforcehunt' else random.randint(0, scaled_trash))
|
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||||
|
gftower_trash_count = random.randint(scaled_trash, max_trash)
|
||||||
|
else:
|
||||||
|
gftower_trash_count = random.randint(0, scaled_trash)
|
||||||
|
|
||||||
gtower_locations = [location for location in fill_locations if location.parent_region.dungeon
|
gtower_locations = [location for location in fill_locations if location.parent_region.dungeon
|
||||||
and location.parent_region.dungeon.name == 'Ganons Tower' and location.player == player]
|
and location.parent_region.dungeon.name == 'Ganons Tower' and location.player == player]
|
||||||
|
|||||||
89
ItemList.py
89
ItemList.py
@@ -180,7 +180,7 @@ def get_custom_array_key(item):
|
|||||||
|
|
||||||
|
|
||||||
def generate_itempool(world, player):
|
def generate_itempool(world, player):
|
||||||
if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals']
|
if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'trinity', 'crystals']
|
||||||
or world.mode[player] not in ['open', 'standard', 'inverted'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']):
|
or world.mode[player] not in ['open', 'standard', 'inverted'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']):
|
||||||
raise NotImplementedError('Not supported yet')
|
raise NotImplementedError('Not supported yet')
|
||||||
|
|
||||||
@@ -192,8 +192,8 @@ def generate_itempool(world, player):
|
|||||||
else:
|
else:
|
||||||
world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False)
|
world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False)
|
||||||
|
|
||||||
if world.goal[player] in ['triforcehunt']:
|
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||||
region = world.get_region('Light World',player)
|
region = world.get_region('Light World', player)
|
||||||
loc = Location(player, "Murahdahla", parent=region)
|
loc = Location(player, "Murahdahla", parent=region)
|
||||||
region.locations.append(loc)
|
region.locations.append(loc)
|
||||||
world.dynamic_locations.append(loc)
|
world.dynamic_locations.append(loc)
|
||||||
@@ -336,14 +336,11 @@ def generate_itempool(world, player):
|
|||||||
if clock_mode is not None:
|
if clock_mode is not None:
|
||||||
world.clock_mode = clock_mode
|
world.clock_mode = clock_mode
|
||||||
|
|
||||||
if world.goal[player] == 'triforcehunt':
|
goal = world.goal[player]
|
||||||
if world.treasure_hunt_count[player] == 0:
|
if goal in ['triforcehunt', 'trinity']:
|
||||||
world.treasure_hunt_count[player] = 20
|
g, t = set_default_triforce(goal, world.treasure_hunt_count[player], world.treasure_hunt_total[player])
|
||||||
if world.treasure_hunt_total[player] == 0:
|
world.treasure_hunt_count[player], world.treasure_hunt_total[player] = g, t
|
||||||
world.treasure_hunt_total[player] = 30
|
|
||||||
world.treasure_hunt_icon[player] = 'Triforce Piece'
|
world.treasure_hunt_icon[player] = 'Triforce Piece'
|
||||||
if world.custom:
|
|
||||||
world.treasure_hunt_count[player] = treasure_hunt_count
|
|
||||||
|
|
||||||
world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player
|
world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player
|
||||||
and ((item.smallkey and world.keyshuffle[player])
|
and ((item.smallkey and world.keyshuffle[player])
|
||||||
@@ -774,9 +771,9 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
|||||||
placed_items = {}
|
placed_items = {}
|
||||||
precollected_items = []
|
precollected_items = []
|
||||||
clock_mode = None
|
clock_mode = None
|
||||||
if goal == 'triforcehunt':
|
if goal in ['triforcehunt', 'trinity']:
|
||||||
if treasure_hunt_total == 0:
|
if treasure_hunt_total == 0:
|
||||||
treasure_hunt_total = 30
|
treasure_hunt_total = 30 if goal == 'triforcehunt' else 10
|
||||||
triforcepool = ['Triforce Piece'] * int(treasure_hunt_total)
|
triforcepool = ['Triforce Piece'] * int(treasure_hunt_total)
|
||||||
|
|
||||||
pool.extend(alwaysitems)
|
pool.extend(alwaysitems)
|
||||||
@@ -856,7 +853,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
|||||||
place_item('Link\'s Uncle', swords_to_use.pop())
|
place_item('Link\'s Uncle', swords_to_use.pop())
|
||||||
place_item('Blacksmith', swords_to_use.pop())
|
place_item('Blacksmith', swords_to_use.pop())
|
||||||
place_item('Pyramid Fairy - Left', swords_to_use.pop())
|
place_item('Pyramid Fairy - Left', swords_to_use.pop())
|
||||||
if goal != 'pedestal':
|
if goal not in ['pedestal', 'trinity']:
|
||||||
place_item('Master Sword Pedestal', swords_to_use.pop())
|
place_item('Master Sword Pedestal', swords_to_use.pop())
|
||||||
else:
|
else:
|
||||||
place_item('Master Sword Pedestal', 'Triforce')
|
place_item('Master Sword Pedestal', 'Triforce')
|
||||||
@@ -878,7 +875,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
|||||||
elif timer == 'timed-ohko':
|
elif timer == 'timed-ohko':
|
||||||
pool.extend(diff.timedohko)
|
pool.extend(diff.timedohko)
|
||||||
clock_mode = 'countdown-ohko'
|
clock_mode = 'countdown-ohko'
|
||||||
if goal == 'triforcehunt':
|
if goal in ['triforcehunt', 'trinity']:
|
||||||
pool.extend(triforcepool)
|
pool.extend(triforcepool)
|
||||||
|
|
||||||
for extra in diff.extras:
|
for extra in diff.extras:
|
||||||
@@ -886,7 +883,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
|||||||
|
|
||||||
# note: massage item pool now handles shrinking the pool appropriately
|
# note: massage item pool now handles shrinking the pool appropriately
|
||||||
|
|
||||||
if goal == 'pedestal' and swords != 'vanilla':
|
if goal in ['pedestal', 'trinity'] and swords != 'vanilla':
|
||||||
place_item('Master Sword Pedestal', 'Triforce')
|
place_item('Master Sword Pedestal', 'Triforce')
|
||||||
if retro:
|
if retro:
|
||||||
pool = [item.replace('Single Arrow','Rupees (5)') for item in pool]
|
pool = [item.replace('Single Arrow','Rupees (5)') for item in pool]
|
||||||
@@ -935,6 +932,11 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
|||||||
if customitemarray["triforce"] > total_items_to_place:
|
if customitemarray["triforce"] > total_items_to_place:
|
||||||
customitemarray["triforce"] = total_items_to_place
|
customitemarray["triforce"] = total_items_to_place
|
||||||
|
|
||||||
|
# Triforce Pieces
|
||||||
|
if goal in ['triforcehunt', 'trinity']:
|
||||||
|
g, t = set_default_triforce(goal, customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"])
|
||||||
|
customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"] = g, t
|
||||||
|
|
||||||
itemtotal = 0
|
itemtotal = 0
|
||||||
# Bow to Silver Arrows Upgrade, including Generic Keys & Rupoors
|
# Bow to Silver Arrows Upgrade, including Generic Keys & Rupoors
|
||||||
for x in [*range(0, 66 + 1), 68, 69]:
|
for x in [*range(0, 66 + 1), 68, 69]:
|
||||||
@@ -969,7 +971,8 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
|||||||
treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], 254), 1)
|
treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], 254), 1)
|
||||||
treasure_hunt_icon = 'Triforce Piece'
|
treasure_hunt_icon = 'Triforce Piece'
|
||||||
# Ensure game is always possible to complete here, force sufficient pieces if the player is unwilling.
|
# Ensure game is always possible to complete here, force sufficient pieces if the player is unwilling.
|
||||||
if (customitemarray["triforcepieces"] < treasure_hunt_count) and (goal == 'triforcehunt') and (customitemarray["triforce"] == 0):
|
if ((customitemarray["triforcepieces"] < treasure_hunt_count) and (goal in ['triforcehunt', 'trinity'])
|
||||||
|
and (customitemarray["triforce"] == 0)):
|
||||||
extrapieces = treasure_hunt_count - customitemarray["triforcepieces"]
|
extrapieces = treasure_hunt_count - customitemarray["triforcepieces"]
|
||||||
pool.extend(['Triforce Piece'] * extrapieces)
|
pool.extend(['Triforce Piece'] * extrapieces)
|
||||||
itemtotal = itemtotal + extrapieces
|
itemtotal = itemtotal + extrapieces
|
||||||
@@ -981,7 +984,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
|||||||
elif timer == 'ohko':
|
elif timer == 'ohko':
|
||||||
clock_mode = 'ohko'
|
clock_mode = 'ohko'
|
||||||
|
|
||||||
if goal == 'pedestal':
|
if goal in ['pedestal', 'trinity']:
|
||||||
place_item('Master Sword Pedestal', 'Triforce')
|
place_item('Master Sword Pedestal', 'Triforce')
|
||||||
itemtotal = itemtotal + 1
|
itemtotal = itemtotal + 1
|
||||||
|
|
||||||
@@ -1016,10 +1019,58 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
|||||||
|
|
||||||
return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms)
|
return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms)
|
||||||
|
|
||||||
|
|
||||||
|
def make_customizer_pool(world, player):
|
||||||
|
pool = []
|
||||||
|
placed_items = {}
|
||||||
|
precollected_items = []
|
||||||
|
clock_mode = None
|
||||||
|
|
||||||
|
def place_item(loc, item):
|
||||||
|
assert loc not in placed_items
|
||||||
|
placed_items[loc] = item
|
||||||
|
|
||||||
|
diff = difficulties[world.difficulty[player]]
|
||||||
|
for item_name, amount in world.customizer.get_item_pool()[player].items():
|
||||||
|
if isinstance(amount, int):
|
||||||
|
if item_name == 'Bottle (Random)':
|
||||||
|
for _ in range(amount):
|
||||||
|
pool.append(random.choice(diff.bottles))
|
||||||
|
else:
|
||||||
|
pool.extend([item_name] * amount)
|
||||||
|
|
||||||
|
timer = world.timer[player]
|
||||||
|
if timer in ['display', 'timed', 'timed-countdown']:
|
||||||
|
clock_mode = 'countdown' if timer == 'timed-countdown' else 'stopwatch'
|
||||||
|
elif timer == 'timed-ohko':
|
||||||
|
clock_mode = 'countdown-ohko'
|
||||||
|
elif timer == 'ohko':
|
||||||
|
clock_mode = 'ohko'
|
||||||
|
|
||||||
|
if world.goal[player] == 'pedestal':
|
||||||
|
place_item('Master Sword Pedestal', 'Triforce')
|
||||||
|
|
||||||
|
return pool, placed_items, precollected_items, clock_mode, 1
|
||||||
|
|
||||||
|
|
||||||
|
# To display, count must be between 1 and 254 - larger values are not yet supported
|
||||||
|
def set_default_triforce(goal, custom_goal, custom_total):
|
||||||
|
triforce_goal, triforce_total = 0, 0
|
||||||
|
if goal == 'triforcehunt':
|
||||||
|
triforce_goal, triforce_total = 20, 30
|
||||||
|
elif goal == 'trinity':
|
||||||
|
triforce_goal, triforce_total = 8, 10
|
||||||
|
if custom_goal > 0:
|
||||||
|
triforce_goal = max(min(custom_goal, 254), 1)
|
||||||
|
if custom_total > 0:
|
||||||
|
triforce_total = max(min(custom_total, 254), triforce_goal)
|
||||||
|
return triforce_goal, triforce_total
|
||||||
|
|
||||||
|
|
||||||
# A quick test to ensure all combinations generate the correct amount of items.
|
# A quick test to ensure all combinations generate the correct amount of items.
|
||||||
def test():
|
def test():
|
||||||
for difficulty in ['normal', 'hard', 'expert']:
|
for difficulty in ['normal', 'hard', 'expert']:
|
||||||
for goal in ['ganon', 'triforcehunt', 'pedestal']:
|
for goal in ['ganon', 'triforcehunt', 'pedestal', 'trinity']:
|
||||||
for timer in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown']:
|
for timer in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown']:
|
||||||
for mode in ['open', 'standard', 'inverted', 'retro']:
|
for mode in ['open', 'standard', 'inverted', 'retro']:
|
||||||
for swords in ['random', 'assured', 'swordless', 'vanilla']:
|
for swords in ['random', 'assured', 'swordless', 'vanilla']:
|
||||||
@@ -1033,7 +1084,7 @@ def test():
|
|||||||
count = len(out[0]) + len(out[1])
|
count = len(out[0]) + len(out[1])
|
||||||
|
|
||||||
correct_count = total_items_to_place
|
correct_count = total_items_to_place
|
||||||
if goal == 'pedestal' and swords != 'vanilla':
|
if goal in ['pedestal', 'trinity'] and swords != 'vanilla':
|
||||||
# pedestal goals generate one extra item
|
# pedestal goals generate one extra item
|
||||||
correct_count += 1
|
correct_count += 1
|
||||||
if retro:
|
if retro:
|
||||||
|
|||||||
@@ -191,9 +191,10 @@ def roll_settings(weights):
|
|||||||
'fast_ganon': 'crystals',
|
'fast_ganon': 'crystals',
|
||||||
'dungeons': 'dungeons',
|
'dungeons': 'dungeons',
|
||||||
'pedestal': 'pedestal',
|
'pedestal': 'pedestal',
|
||||||
'triforce-hunt': 'triforcehunt'
|
'triforce-hunt': 'triforcehunt',
|
||||||
|
'trinity': 'trinity'
|
||||||
}[goal]
|
}[goal]
|
||||||
ret.openpyramid = goal == 'fast_ganon' if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
ret.openpyramid = goal in ['fast_ganon', 'trinity'] if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
||||||
|
|
||||||
ret.crystals_gt = get_choice('tower_open')
|
ret.crystals_gt = get_choice('tower_open')
|
||||||
|
|
||||||
|
|||||||
12
Rom.py
12
Rom.py
@@ -722,7 +722,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' else DROptions.Town_Portal
|
dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' else DROptions.Town_Portal
|
||||||
if world.doorShuffle[player] == 'crossed':
|
if world.doorShuffle[player] == 'crossed':
|
||||||
dr_flags |= DROptions.Map_Info
|
dr_flags |= DROptions.Map_Info
|
||||||
if world.collection_rate[player] and world.goal[player] != 'triforcehunt':
|
if world.collection_rate[player] and world.goal[player] not in ['triforcehunt', 'trinity']:
|
||||||
dr_flags |= DROptions.Debug
|
dr_flags |= DROptions.Debug
|
||||||
if world.doorShuffle[player] == 'crossed' and world.logic[player] != 'nologic'\
|
if world.doorShuffle[player] == 'crossed' and world.logic[player] != 'nologic'\
|
||||||
and world.mixed_travel[player] == 'prevent':
|
and world.mixed_travel[player] == 'prevent':
|
||||||
@@ -1234,7 +1234,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
|
|
||||||
# set up goals for treasure hunt
|
# set up goals for treasure hunt
|
||||||
rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon[player] == 'Triforce Piece' else [0x0D, 0x28])
|
rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon[player] == 'Triforce Piece' else [0x0D, 0x28])
|
||||||
if world.goal[player] == 'triforcehunt':
|
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||||
rom.write_byte(0x180167, int(world.treasure_hunt_count[player]) % 256)
|
rom.write_byte(0x180167, int(world.treasure_hunt_count[player]) % 256)
|
||||||
rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled)
|
rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled)
|
||||||
|
|
||||||
@@ -1261,7 +1261,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_bytes(0x50563, [0x3F, 0x14]) # disable below ganon chest
|
rom.write_bytes(0x50563, [0x3F, 0x14]) # disable below ganon chest
|
||||||
rom.write_byte(0x50599, 0x00) # disable below ganon chest
|
rom.write_byte(0x50599, 0x00) # disable below ganon chest
|
||||||
rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest
|
rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest
|
||||||
rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] else 0x00) # pre-open Pyramid Hole
|
rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] or world.goal[player] == 'trinity' else 0x00) # pre-open Pyramid Hole
|
||||||
rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0
|
rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0
|
||||||
rom.write_byte(0xF5D73, 0xF0) # bees are catchable
|
rom.write_byte(0xF5D73, 0xF0) # bees are catchable
|
||||||
rom.write_byte(0xF5F10, 0xF0) # bees are catchable
|
rom.write_byte(0xF5F10, 0xF0) # bees are catchable
|
||||||
@@ -1447,7 +1447,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_byte(0x18003E, 0x01) # make ganon invincible
|
rom.write_byte(0x18003E, 0x01) # make ganon invincible
|
||||||
elif world.goal[player] in ['dungeons']:
|
elif world.goal[player] in ['dungeons']:
|
||||||
rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat
|
rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat
|
||||||
elif world.goal[player] in ['crystals']:
|
elif world.goal[player] in ['crystals', 'trinity']:
|
||||||
rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals
|
rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals
|
||||||
else:
|
else:
|
||||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||||
@@ -2404,6 +2404,10 @@ def write_strings(rom, world, player, team):
|
|||||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||||
tt['sign_ganon'] = 'You need to get to the pedestal... Ganon is invincible!'
|
tt['sign_ganon'] = 'You need to get to the pedestal... Ganon is invincible!'
|
||||||
else:
|
else:
|
||||||
|
if world.goal[player] == 'trinity':
|
||||||
|
trinity_crystal_text = ('%d crystal to beat Ganon.' if world.crystals_needed_for_ganon[player] == 1 else '%d crystals to beat Ganon.') % world.crystals_needed_for_ganon[player]
|
||||||
|
tt['sign_ganon'] = 'Three ways to victory! %s Get to it!' % trinity_crystal_text
|
||||||
|
tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % int(world.treasure_hunt_count[player])
|
||||||
tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)]
|
tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)]
|
||||||
tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!'
|
tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!'
|
||||||
tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!'
|
tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!'
|
||||||
|
|||||||
6
Rules.py
6
Rules.py
@@ -58,7 +58,7 @@ def set_rules(world, player):
|
|||||||
elif world.goal[player] == 'ganon':
|
elif world.goal[player] == 'ganon':
|
||||||
# require aga2 to beat ganon
|
# require aga2 to beat ganon
|
||||||
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
||||||
elif world.goal[player] == 'triforcehunt':
|
elif world.goal[player] in ['triforcehunt', 'trinity']:
|
||||||
add_rule(world.get_location('Murahdahla', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player]))
|
add_rule(world.get_location('Murahdahla', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player]))
|
||||||
|
|
||||||
if world.mode[player] != 'inverted':
|
if world.mode[player] != 'inverted':
|
||||||
@@ -871,7 +871,7 @@ def default_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_Pearl(player) and state.has_sword(player) and state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!)
|
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_Pearl(player) and state.has_sword(player) and state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!)
|
||||||
|
|
||||||
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player])
|
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: world.open_pyramid[player] or world.goal[player] == 'trinity' or state.has('Beat Agahnim 2', player))
|
||||||
if world.swords[player] == 'swordless':
|
if world.swords[player] == 'swordless':
|
||||||
swordless_rules(world, player)
|
swordless_rules(world, player)
|
||||||
|
|
||||||
@@ -1023,7 +1023,7 @@ def inverted_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.can_flute(player))
|
||||||
set_rule(world.get_entrance('Hammer Peg Area Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('Hammer Peg Area Flute', player), lambda state: state.can_flute(player))
|
||||||
|
|
||||||
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player])
|
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: world.open_pyramid[player] or world.goal[player] == 'trinity' or state.has('Beat Agahnim 2', player))
|
||||||
if world.swords[player] == 'swordless':
|
if world.swords[player] == 'swordless':
|
||||||
swordless_rules(world, player)
|
swordless_rules(world, player)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
description: Example door rando weights
|
description: Example door rando weights
|
||||||
|
algorithm:
|
||||||
|
balanced: 12
|
||||||
|
vanilla_fill: 1
|
||||||
|
major_only: 1
|
||||||
|
dungeon_only: 1
|
||||||
|
district: 1
|
||||||
door_shuffle:
|
door_shuffle:
|
||||||
vanilla: 0
|
vanilla: 0
|
||||||
basic: 2
|
basic: 2
|
||||||
@@ -52,6 +58,7 @@
|
|||||||
dungeons: 1
|
dungeons: 1
|
||||||
pedestal: 2
|
pedestal: 2
|
||||||
triforce-hunt: 2
|
triforce-hunt: 2
|
||||||
|
trinity: 2
|
||||||
triforce_goal_min: 10
|
triforce_goal_min: 10
|
||||||
triforce_goal_max: 30
|
triforce_goal_max: 30
|
||||||
triforce_pool_min: 20
|
triforce_pool_min: 20
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
"pedestal",
|
"pedestal",
|
||||||
"dungeons",
|
"dungeons",
|
||||||
"triforcehunt",
|
"triforcehunt",
|
||||||
|
"trinity",
|
||||||
"crystals"
|
"crystals"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -104,7 +104,9 @@
|
|||||||
"All Dungeons: Collect all crystals, pendants, beat both",
|
"All Dungeons: Collect all crystals, pendants, beat both",
|
||||||
" Agahnim fights and then defeat Ganon.",
|
" Agahnim fights and then defeat Ganon.",
|
||||||
"Triforce Hunt: Places 30 Triforce Pieces in the world, collect",
|
"Triforce Hunt: Places 30 Triforce Pieces in the world, collect",
|
||||||
" 20 of them to beat the game."
|
" 20 of them to beat the game.",
|
||||||
|
"Trinity: Can beat the game by defeating Ganon, pulling",
|
||||||
|
" Pedestal, or delivering Triforce Pieces."
|
||||||
],
|
],
|
||||||
"difficulty": [
|
"difficulty": [
|
||||||
"Select game difficulty. Affects available itempool. (default: %(default)s)",
|
"Select game difficulty. Affects available itempool. (default: %(default)s)",
|
||||||
|
|||||||
@@ -232,6 +232,7 @@
|
|||||||
"randomizer.item.goal.pedestal": "Master Sword Pedestal",
|
"randomizer.item.goal.pedestal": "Master Sword Pedestal",
|
||||||
"randomizer.item.goal.dungeons": "All Dungeons",
|
"randomizer.item.goal.dungeons": "All Dungeons",
|
||||||
"randomizer.item.goal.triforcehunt": "Triforce Hunt",
|
"randomizer.item.goal.triforcehunt": "Triforce Hunt",
|
||||||
|
"randomizer.item.goal.trinity": "Trinity",
|
||||||
"randomizer.item.goal.crystals": "Crystals",
|
"randomizer.item.goal.crystals": "Crystals",
|
||||||
|
|
||||||
"randomizer.item.crystals_gt": "Crystals to open GT",
|
"randomizer.item.crystals_gt": "Crystals to open GT",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"pedestal",
|
"pedestal",
|
||||||
"dungeons",
|
"dungeons",
|
||||||
"triforcehunt",
|
"triforcehunt",
|
||||||
|
"trinity",
|
||||||
"crystals"
|
"crystals"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user