Added new Trinity goal
This commit is contained in:
@@ -2968,7 +2968,7 @@ class Spoiler(object):
|
||||
outfile.write('Retro:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['retro'][player] else 'No'))
|
||||
outfile.write('Swords:'.ljust(line_width) + '%s\n' % self.metadata['weapons'][player])
|
||||
outfile.write('Goal:'.ljust(line_width) + '%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:'.ljust(line_width) + '%s\n' % self.metadata['triforcegoal'][player])
|
||||
outfile.write('Triforce Pieces Total:'.ljust(line_width) + '%s\n' % self.metadata['triforcepool'][player])
|
||||
outfile.write('Crystals Required for GT:'.ljust(line_width) + '%s\n' % str(self.world.crystals_gt_orig[player]))
|
||||
@@ -3215,7 +3215,7 @@ world_mode = {"open": 0, "standard": 1, "inverted": 2}
|
||||
sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3}
|
||||
|
||||
# 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}
|
||||
func_mode = {"normal": 0, "hard": 1, "expert": 2}
|
||||
|
||||
|
||||
2
Fill.py
2
Fill.py
@@ -358,7 +358,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
||||
if not gftower_trash or not world.ganonstower_vanilla[player] or world.doorShuffle[player] == 'crossed' or world.logic[player] in ['owglitches', 'nologic']:
|
||||
continue
|
||||
|
||||
gftower_trash_count = (random.randint(15, 50) if world.goal[player] == 'triforcehunt' else random.randint(0, 15))
|
||||
gftower_trash_count = (random.randint(15, 50) if world.goal[player] in ['triforcehunt', 'trinity'] else random.randint(0, 15))
|
||||
|
||||
gtower_locations = [location for location in fill_locations if 'Ganons Tower' in location.name and location.player == player]
|
||||
random.shuffle(gtower_locations)
|
||||
|
||||
22
ItemList.py
22
ItemList.py
@@ -178,7 +178,7 @@ def get_custom_array_key(item):
|
||||
|
||||
|
||||
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']):
|
||||
raise NotImplementedError('Not supported yet')
|
||||
|
||||
@@ -190,7 +190,7 @@ def generate_itempool(world, player):
|
||||
else:
|
||||
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('Hyrule Castle Courtyard',player)
|
||||
|
||||
loc = Location(player, "Murahdahla", parent=region)
|
||||
@@ -337,7 +337,7 @@ def generate_itempool(world, player):
|
||||
if clock_mode is not None:
|
||||
world.clock_mode = clock_mode
|
||||
|
||||
if world.goal[player] == 'triforcehunt':
|
||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||
if world.treasure_hunt_count[player] == 0:
|
||||
world.treasure_hunt_count[player] = 20
|
||||
if world.treasure_hunt_total[player] == 0:
|
||||
@@ -759,7 +759,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
placed_items = {}
|
||||
precollected_items = []
|
||||
clock_mode = None
|
||||
if goal == 'triforcehunt':
|
||||
if goal in ['triforcehunt', 'trinity']:
|
||||
if treasure_hunt_total == 0:
|
||||
treasure_hunt_total = 30
|
||||
triforcepool = ['Triforce Piece'] * int(treasure_hunt_total)
|
||||
@@ -841,7 +841,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
place_item('Link\'s Uncle', swords_to_use.pop())
|
||||
place_item('Blacksmith', 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())
|
||||
else:
|
||||
place_item('Master Sword Pedestal', 'Triforce')
|
||||
@@ -866,7 +866,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
pool.extend(diff.timedohko)
|
||||
extraitems -= len(diff.timedohko)
|
||||
clock_mode = 'countdown-ohko'
|
||||
if goal == 'triforcehunt':
|
||||
if goal in ['triforcehunt', 'trinity']:
|
||||
pool.extend(triforcepool)
|
||||
extraitems -= len(triforcepool)
|
||||
|
||||
@@ -877,7 +877,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
pool.extend(extra)
|
||||
extraitems -= len(extra)
|
||||
|
||||
if goal == 'pedestal' and swords != 'vanilla':
|
||||
if goal in ['pedestal', 'trinity'] and swords != 'vanilla':
|
||||
place_item('Master Sword Pedestal', 'Triforce')
|
||||
if retro:
|
||||
pool = [item.replace('Single Arrow','Rupees (5)') for item in pool]
|
||||
@@ -958,7 +958,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], 99), 1) #To display, count must be between 1 and 99.
|
||||
treasure_hunt_icon = 'Triforce Piece'
|
||||
# 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"]
|
||||
pool.extend(['Triforce Piece'] * extrapieces)
|
||||
itemtotal = itemtotal + extrapieces
|
||||
@@ -970,7 +970,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
elif timer == 'ohko':
|
||||
clock_mode = 'ohko'
|
||||
|
||||
if goal == 'pedestal':
|
||||
if goal in ['pedestal', 'trinity']:
|
||||
place_item('Master Sword Pedestal', 'Triforce')
|
||||
itemtotal = itemtotal + 1
|
||||
|
||||
@@ -1008,7 +1008,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
# A quick test to ensure all combinations generate the correct amount of items.
|
||||
def test():
|
||||
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 mode in ['open', 'standard', 'inverted', 'retro']:
|
||||
for swords in ['random', 'assured', 'swordless', 'vanilla']:
|
||||
@@ -1022,7 +1022,7 @@ def test():
|
||||
count = len(out[0]) + len(out[1])
|
||||
|
||||
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
|
||||
correct_count += 1
|
||||
if retro:
|
||||
|
||||
@@ -179,9 +179,10 @@ def roll_settings(weights):
|
||||
'fast_ganon': 'crystals',
|
||||
'dungeons': 'dungeons',
|
||||
'pedestal': 'pedestal',
|
||||
'triforce-hunt': 'triforcehunt'
|
||||
'triforce-hunt': 'triforcehunt',
|
||||
'trinity': 'trinity'
|
||||
}[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.shuffleganon = get_choice('shuffleganon') == 'on'
|
||||
|
||||
|
||||
11
Rom.py
11
Rom.py
@@ -755,7 +755,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
|
||||
if world.doorShuffle[player] == 'crossed':
|
||||
dr_flags |= DROptions.Map_Info
|
||||
if world.experimental[player] and world.goal[player] != 'triforcehunt':
|
||||
if world.experimental[player] and world.goal[player] not in ['triforcehunt', 'trinity']:
|
||||
dr_flags |= DROptions.Debug
|
||||
if world.doorShuffle[player] == 'crossed' and world.logic[player] != 'nologic'\
|
||||
and world.mixed_travel[player] == 'prevent':
|
||||
@@ -1235,7 +1235,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
|
||||
# set up goals for treasure hunt
|
||||
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(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_byte(0x50599, 0x00) # 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(0xF5D73, 0xF0) # bees are catchable
|
||||
rom.write_byte(0xF5F10, 0xF0) # bees are catchable
|
||||
@@ -1446,7 +1446,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
rom.write_byte(0x18003E, 0x01) # make ganon invincible
|
||||
elif world.goal[player] in ['dungeons']:
|
||||
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
|
||||
else:
|
||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||
@@ -2374,6 +2374,9 @@ def write_strings(rom, world, player, team):
|
||||
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!'
|
||||
else:
|
||||
if world.goal[player] in ['trinity']:
|
||||
tt['sign_ganon'] = 'Three ways Ganon can die! Get to it!'
|
||||
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_alt'] = 'You cannot defeat me until you finish your goal!'
|
||||
tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!'
|
||||
|
||||
6
Rules.py
6
Rules.py
@@ -55,7 +55,7 @@ def set_rules(world, player):
|
||||
elif world.goal[player] == 'ganon':
|
||||
# require aga2 to beat ganon
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
||||
elif world.goal[player] == 'triforcehunt':
|
||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||
if ('Murahdahla', player) in world._location_cache:
|
||||
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]))
|
||||
|
||||
@@ -1009,7 +1009,7 @@ def ow_rules(world, player):
|
||||
if not world.is_tile_swapped(0x1b, player):
|
||||
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: False)
|
||||
set_rule(world.get_entrance('Inverted Pyramid Entrance', player), lambda state: False)
|
||||
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))
|
||||
|
||||
set_rule(world.get_entrance('HC Area Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('HC Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -1020,7 +1020,7 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||
set_rule(world.get_entrance('Top of Pyramid (Inner)', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||
else:
|
||||
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))
|
||||
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: False)
|
||||
set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False)
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
dungeons: 1
|
||||
pedestal: 2
|
||||
triforce-hunt: 2
|
||||
trinity: 1
|
||||
triforce_goal_min: 10
|
||||
triforce_goal_max: 30
|
||||
triforce_pool_min: 20
|
||||
|
||||
@@ -103,7 +103,9 @@
|
||||
"All Dungeons: Collect all crystals, pendants, beat both",
|
||||
" Agahnim fights and then defeat Ganon.",
|
||||
"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": [
|
||||
"Select game difficulty. Affects available itempool. (default: %(default)s)",
|
||||
|
||||
@@ -238,6 +238,7 @@
|
||||
"randomizer.item.goal.pedestal": "Master Sword Pedestal",
|
||||
"randomizer.item.goal.dungeons": "All Dungeons",
|
||||
"randomizer.item.goal.triforcehunt": "Triforce Hunt",
|
||||
"randomizer.item.goal.trinity": "Trinity",
|
||||
"randomizer.item.goal.crystals": "Crystals",
|
||||
|
||||
"randomizer.item.crystals_gt": "Crystals to open GT",
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"pedestal",
|
||||
"dungeons",
|
||||
"triforcehunt",
|
||||
"trinity",
|
||||
"crystals"
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user