Ganonhunt
This commit is contained in:
@@ -55,7 +55,7 @@ def start():
|
||||
Palace, to allow for an alternative to firerod.
|
||||
Vanilla: Swords are in vanilla locations.
|
||||
''')
|
||||
parser.add_argument('--goal', default='ganon', const='ganon', nargs='?', choices=['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals', 'all_items', 'completionist'],
|
||||
parser.add_argument('--goal', default='ganon', const='ganon', nargs='?', choices=['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'ganonhunt', 'crystals', 'all_items', 'completionist'],
|
||||
help='''\
|
||||
Select completion goal. (default: %(default)s)
|
||||
Ganon: Collect all crystals, beat Agahnim 2 then
|
||||
@@ -66,6 +66,8 @@ def start():
|
||||
Agahnim fights and then defeat Ganon.
|
||||
Triforce Hunt: Places 30 Triforce Pieces in the world, collect
|
||||
20 of them to beat the game.
|
||||
Ganonhunt: Places 30 Triforce Pieces in the world, collect
|
||||
20 of them to beat Ganon.
|
||||
All Items: Requires collecting 216 items to defeat Ganon.
|
||||
Completionist: Same as above, plus All Dungeons
|
||||
''')
|
||||
|
||||
21
ItemList.py
21
ItemList.py
@@ -35,8 +35,8 @@ Difficulty = namedtuple('Difficulty',
|
||||
['baseitems', 'bottles', 'bottle_count', 'same_bottle', 'progressiveshield',
|
||||
'basicshield', 'progressivearmor', 'basicarmor', 'swordless',
|
||||
'progressivesword', 'basicsword', 'basicbow', 'timedohko', 'timedother',
|
||||
'triforcehunt', 'triforce_pieces_required', 'retro',
|
||||
'extras', 'progressive_sword_limit', 'progressive_shield_limit',
|
||||
'triforcehunt', 'ganonhunt', 'triforce_pieces_required', 'ganonhunt_pieces_required',
|
||||
'retro', 'extras', 'progressive_sword_limit', 'progressive_shield_limit',
|
||||
'progressive_armor_limit', 'progressive_bottle_limit',
|
||||
'progressive_bow_limit', 'heart_piece_limit', 'boss_heart_container_limit'])
|
||||
|
||||
@@ -59,7 +59,9 @@ difficulties = {
|
||||
timedohko = ['Green Clock'] * 25,
|
||||
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt = ['Triforce Piece'] * 30,
|
||||
ganonhunt = ['Triforce Piece'] * 50,
|
||||
triforce_pieces_required = 20,
|
||||
ganonhunt_pieces_required = 40,
|
||||
retro = ['Small Key (Universal)'] * 17 + ['Rupees (20)'] * 10,
|
||||
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit = 4,
|
||||
@@ -86,7 +88,9 @@ difficulties = {
|
||||
timedohko = ['Green Clock'] * 25,
|
||||
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt = ['Triforce Piece'] * 30,
|
||||
ganonhunt = ['Triforce Piece'] * 50,
|
||||
triforce_pieces_required = 20,
|
||||
ganonhunt_pieces_required = 40,
|
||||
retro = ['Small Key (Universal)'] * 12 + ['Rupees (5)'] * 15,
|
||||
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit = 3,
|
||||
@@ -113,7 +117,9 @@ difficulties = {
|
||||
timedohko = ['Green Clock'] * 20 + ['Red Clock'] * 5,
|
||||
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt = ['Triforce Piece'] * 30,
|
||||
ganonhunt = ['Triforce Piece'] * 50,
|
||||
triforce_pieces_required = 20,
|
||||
ganonhunt_pieces_required = 40,
|
||||
retro = ['Small Key (Universal)'] * 12 + ['Rupees (5)'] * 15,
|
||||
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit = 2,
|
||||
@@ -127,7 +133,7 @@ difficulties = {
|
||||
}
|
||||
|
||||
def generate_itempool(world, player):
|
||||
if (world.difficulty not in ['normal', 'hard', 'expert'] or world.goal not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals', 'all_items', 'completionist']
|
||||
if (world.difficulty not in ['normal', 'hard', 'expert'] or world.goal not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'ganonhunt', 'crystals', 'all_items', 'completionist']
|
||||
or world.mode 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')
|
||||
|
||||
@@ -457,11 +463,16 @@ def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, r
|
||||
pool.extend(diff.timedohko)
|
||||
extraitems -= len(diff.timedohko)
|
||||
clock_mode = 'countdown-ohko'
|
||||
if goal == 'triforcehunt':
|
||||
if goal in ['triforcehunt']:
|
||||
pool.extend(diff.triforcehunt)
|
||||
extraitems -= len(diff.triforcehunt)
|
||||
treasure_hunt_count = diff.triforce_pieces_required
|
||||
treasure_hunt_icon = 'Triforce Piece'
|
||||
if goal in ['ganonhunt']:
|
||||
pool.extend(diff.ganonhunt)
|
||||
extraitems -= len(diff.ganonhunt)
|
||||
treasure_hunt_count = diff.ganonhunt_pieces_required
|
||||
treasure_hunt_icon = 'Triforce Piece'
|
||||
|
||||
for extra in diff.extras:
|
||||
if extraitems > 0:
|
||||
@@ -582,7 +593,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
treasure_hunt_count = max(min(customitemarray[65], 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[64] < treasure_hunt_count) and (goal == 'triforcehunt') and (customitemarray[66] == 0):
|
||||
if (customitemarray[64] < treasure_hunt_count) and (goal in ['triforcehunt', 'ganonhunt']) and (customitemarray[66] == 0):
|
||||
extrapieces = treasure_hunt_count - customitemarray[64]
|
||||
pool.extend(['Triforce Piece'] * extrapieces)
|
||||
itemtotal = itemtotal + extrapieces
|
||||
|
||||
18
Rom.py
18
Rom.py
@@ -905,6 +905,8 @@ def patch_rom(world, player, rom):
|
||||
rom.write_byte(0x18003E, 0x0A) # make ganon invincible until all items
|
||||
elif world.goal in ['completionist']:
|
||||
rom.write_byte(0x18003E, 0x0B) # make ganon invincible until all items and dungeons
|
||||
elif world.goal in ['ganonhunt']:
|
||||
rom.write_byte(0x18003E, 0x05) # make ganon invincible until goal triforce pieces
|
||||
else:
|
||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||
|
||||
@@ -1040,7 +1042,7 @@ def patch_rom(world, player, rom):
|
||||
# write total item count and item counter hud mode
|
||||
item_total = len(world.get_filled_locations()) - 18 # minus non-item locations
|
||||
rom.write_int16(0x180196, item_total+1)
|
||||
if world.item_counter_hud[player] and world.goal != 'triforcehunt':
|
||||
if world.item_counter_hud[player] and world.goal not in ['triforcehunt', 'ganonhunt']:
|
||||
rom.write_byte(0x180039, 0x01)
|
||||
else:
|
||||
rom.write_byte(0x180039, 0x00)
|
||||
@@ -1337,10 +1339,11 @@ def write_strings(rom, world, player):
|
||||
if world.goal == 'ganon':
|
||||
ganon_crystals_singular = 'To beat Ganon you must collect %d crystal and defeat his minion at the top of his tower.'
|
||||
ganon_crystals_plural = 'To beat Ganon you must collect %d crystals and defeat his minion at the top of his tower.'
|
||||
|
||||
tt['sign_ganon'] = (ganon_crystals_singular if world.crystals_needed_for_ganon == 1 else ganon_crystals_plural) % world.crystals_needed_for_ganon
|
||||
|
||||
|
||||
tt['sign_ganon'] = (ganon_crystals_singular if world.crystals_needed_for_ganon == 1 else ganon_crystals_plural) % world.crystals_needed_for_ganon
|
||||
if world.goal == 'ganonhunt':
|
||||
ganon_triforce_singular = 'To beat Ganon you must collect %d triforce pieces and defeat his minion at the top of his tower.'
|
||||
ganon_triforce_plural = 'To beat Ganon you must collect %d triforce pieces and defeat his minion at the top of his tower.'
|
||||
tt['sign_ganon'] = (ganon_triforce_singular if world.treasure_hunt_count == 1 else ganon_triforce_plural) % world.treasure_hunt_count
|
||||
|
||||
if world.goal in ['dungeons']:
|
||||
tt['sign_ganon'] = 'You need to complete all the dungeons.'
|
||||
@@ -1358,6 +1361,11 @@ def write_strings(rom, world, player):
|
||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||
tt['sign_ganon'] = 'Go find the Triforce pieces... Ganon is invincible!'
|
||||
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." % world.treasure_hunt_count
|
||||
elif world.goal in ['ganonhunt']:
|
||||
tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)]
|
||||
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Get the Triforce Pieces.'
|
||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||
tt['sign_ganon'] = 'You need %d triforce pieces to beat Ganon.'
|
||||
elif world.goal in ['pedestal']:
|
||||
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Your goal is at the pedestal.'
|
||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||
|
||||
12
Rules.py
12
Rules.py
@@ -466,7 +466,10 @@ def global_rules(world, player):
|
||||
forbid_item(world.get_location(location, player), 'Big Key (Ganons Tower)', player)
|
||||
|
||||
set_rule(world.get_location('Ganon', player), lambda state: state.has_beam_sword(player) and state.has_fire_source(player) and state.has_crystals(world.crystals_needed_for_ganon, player)
|
||||
and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or (state.has('Silver Arrows', player) and state.can_shoot_arrows(player)) or state.has('Lamp', player) or state.can_extend_magic(player, 12))) # need to light torch a sufficient amount of times
|
||||
and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or (state.has('Silver Arrows', player) and state.can_shoot_arrows(player)) or state.has('Lamp', player) or state.can_extend_magic(player, 12))
|
||||
and (False if world.goal == 'completionist' and (world.accessibility != 'locations') else True)
|
||||
and (False if (world.goal == 'ganonhunt' and not state.has('Triforce Piece', player, world.treasure_hunt_count)) else True)
|
||||
)
|
||||
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop
|
||||
|
||||
set_rule(world.get_entrance('Ganons Tower', player), lambda state: False) # This is a safety for the TR function below to not require GT entrance in its key logic.
|
||||
@@ -876,7 +879,10 @@ def inverted_rules(world, player):
|
||||
forbid_item(world.get_location(location, player), 'Big Key (Ganons Tower)', player)
|
||||
|
||||
set_rule(world.get_location('Ganon', player), lambda state: state.has_beam_sword(player) and state.has_fire_source(player) and state.has_crystals(world.crystals_needed_for_ganon, player)
|
||||
and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or (state.has('Silver Arrows', player) and state.can_shoot_arrows(player)) or state.has('Lamp', player) or state.can_extend_magic(player, 12))) # need to light torch a sufficient amount of times
|
||||
and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or (state.has('Silver Arrows', player) and state.can_shoot_arrows(player)) or state.has('Lamp', player) or state.can_extend_magic(player, 12))
|
||||
and (False if world.goal == 'completionist' and (world.accessibility != 'locations') else True)
|
||||
and (False if (world.goal == 'ganonhunt' and not state.has('Triforce Piece', player, world.treasure_hunt_count)) else True)
|
||||
)
|
||||
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop
|
||||
|
||||
set_rule(world.get_entrance('Inverted Ganons Tower', player), lambda state: False) # This is a safety for the TR function below to not require GT entrance in its key logic.
|
||||
@@ -1055,7 +1061,7 @@ def set_trock_key_rules(world, player):
|
||||
# No matter what, the Big Key cannot be in the Big Chest or held by Trinexx.
|
||||
non_big_key_locations = ['Turtle Rock - Big Chest', 'Turtle Rock - Boss']
|
||||
|
||||
def tr_big_key_chest_keys_needed(world, state):
|
||||
def tr_big_key_chest_keys_needed(state):
|
||||
# This function handles the key requirements for the TR Big Chest in the situations it having the Big Key should logically require 2 keys, small key
|
||||
# should logically require no keys, and anything else should logically require 4 keys.
|
||||
item = item_name(state, 'Turtle Rock - Big Key Chest', player)
|
||||
|
||||
Reference in New Issue
Block a user