Remove starhunt, replaced by triforce hunt. Change to match VT normal settings (collect 20 out of 30 pieces). Rename restrictive algorithm to vt25. Add crystals goal, which removes aga2 requirement for hurting ganon. No noticeable difference without --shuffleganon enabled.
This commit is contained in:
parent
93dea89b8c
commit
abff299f25
|
@ -32,7 +32,7 @@ class World(object):
|
|||
self.light_world_light_cone = False
|
||||
self.dark_world_light_cone = False
|
||||
self.treasure_hunt_count = 0
|
||||
self.treasure_hunt_icon = 'Power Star'
|
||||
self.treasure_hunt_icon = 'Triforce Piece'
|
||||
self.clock_mode = 'off'
|
||||
self.aga_randomness = True
|
||||
self.lock_aga_door_in_escape = False
|
||||
|
@ -186,7 +186,7 @@ class World(object):
|
|||
return True
|
||||
elif location.item.name in ['Triforce Piece', 'Power Star']:
|
||||
treasure_pieces_collected += 1
|
||||
if self.goal in ['starhunt', 'triforcehunt'] and treasure_pieces_collected >= self.treasure_hunt_count:
|
||||
if self.goal in ['triforcehunt'] and treasure_pieces_collected >= self.treasure_hunt_count:
|
||||
return True
|
||||
sphere.append(location)
|
||||
|
||||
|
@ -205,10 +205,10 @@ class World(object):
|
|||
logic = 0 if self.logic == 'noglitches' else 1
|
||||
mode = ['standard', 'open', 'swordless'].index(self.mode)
|
||||
dungeonitems = 0 if self.place_dungeon_items else 1
|
||||
goal = ['ganon', 'pedestal', 'dungeons', 'starhunt', 'triforcehunt'].index(self.goal)
|
||||
goal = ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'].index(self.goal)
|
||||
shuffle = ['vanilla', 'simple', 'restricted', 'full', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple'].index(self.shuffle)
|
||||
difficulty = ['normal', 'timed', 'timed-ohko', 'timed-countdown'].index(self.difficulty)
|
||||
algorithm = ['freshness', 'flood', 'vt21', 'vt22', 'restrictive'].index(self.algorithm)
|
||||
algorithm = ['freshness', 'flood', 'vt21', 'vt22', 'vt25'].index(self.algorithm)
|
||||
beatableonly = 1 if self.check_beatable_only else 0
|
||||
shuffleganon = 1 if self.shuffle_ganon else 0
|
||||
return logic | (beatableonly << 1) | (dungeonitems << 2) | (shuffleganon << 3) | (goal << 4) | (shuffle << 7) | (difficulty << 11) | (algorithm << 13) | (mode << 16)
|
||||
|
|
|
@ -39,18 +39,17 @@ if __name__ == '__main__':
|
|||
Bombos Tablet are unreachable but contain trash items
|
||||
always.
|
||||
''')
|
||||
parser.add_argument('--goal', default='ganon', const='ganon', nargs='?', choices=['ganon', 'pedestal', 'dungeons', 'starhunt', 'triforcehunt'],
|
||||
parser.add_argument('--goal', default='ganon', const='ganon', nargs='?', choices=['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'],
|
||||
help='''\
|
||||
Select completion goal. (default: %(default)s)
|
||||
Ganon: Collect all crystals, beat Agahnim 2 then
|
||||
defeat Ganon.
|
||||
Crystals: Collect all crystals then defeat Ganon.
|
||||
Pedestal: Places the Triforce at the Master Sword Pedestal.
|
||||
All Dungeons: Collect all crystals, pendants, beat both
|
||||
Agahnim fights and then defeat Ganon.
|
||||
Star Hunt: Places 15 Power Stars in the world, collect 10 of
|
||||
them to beat the game.
|
||||
Triforce Hunt: Places 3 Triforce Pieces in the world, collect
|
||||
them all to beat the game.
|
||||
Triforce Hunt: Places 30 Triforce Pieces in the world, collect
|
||||
20 of them to beat the game.
|
||||
''')
|
||||
parser.add_argument('--difficulty', default='normal', const='normal', nargs='?', choices=['normal', 'timed', 'timed-ohko', 'timed-countdown'],
|
||||
help='''\
|
||||
|
@ -72,10 +71,10 @@ if __name__ == '__main__':
|
|||
Timed mode. If time runs out, you lose (but can
|
||||
still keep playing).
|
||||
''')
|
||||
parser.add_argument('--algorithm', default='restrictive', const='restrictive', nargs='?', choices=['freshness', 'flood', 'vt21', 'vt22', 'restrictive'],
|
||||
parser.add_argument('--algorithm', default='vt25', const='vt25', nargs='?', choices=['freshness', 'flood', 'vt21', 'vt22', 'vt25'],
|
||||
help='''\
|
||||
Select item filling algorithm. (default: %(default)s)
|
||||
Restrictive: Shuffle items and place them in a random location
|
||||
vt25: Shuffle items and place them in a random location
|
||||
that it is not impossible to be in.
|
||||
vt21: Unbiased in its selection, but has tendency to put
|
||||
Ice Rod in Turtle Rock.
|
||||
|
|
6
Gui.py
6
Gui.py
|
@ -90,7 +90,7 @@ def guiMain(args=None):
|
|||
goalFrame = Frame(drowDownFrame)
|
||||
goalVar = StringVar()
|
||||
goalVar.set('ganon')
|
||||
goalOptionMenu = OptionMenu(goalFrame, goalVar, 'ganon', 'pedestal', 'dungeons', 'starhunt', 'triforcehunt')
|
||||
goalOptionMenu = OptionMenu(goalFrame, goalVar, 'ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals')
|
||||
goalOptionMenu.pack(side=RIGHT)
|
||||
goalLabel = Label(goalFrame, text='Game goal')
|
||||
goalLabel.pack(side=LEFT)
|
||||
|
@ -105,8 +105,8 @@ def guiMain(args=None):
|
|||
|
||||
algorithmFrame = Frame(drowDownFrame)
|
||||
algorithmVar = StringVar()
|
||||
algorithmVar.set('restrictive')
|
||||
algorithmOptionMenu = OptionMenu(algorithmFrame, algorithmVar, 'freshness', 'flood', 'vt21', 'vt22', 'restrictive')
|
||||
algorithmVar.set('vt25')
|
||||
algorithmOptionMenu = OptionMenu(algorithmFrame, algorithmVar, 'freshness', 'flood', 'vt21', 'vt22', 'vt25')
|
||||
algorithmOptionMenu.pack(side=RIGHT)
|
||||
algorithmLabel = Label(algorithmFrame, text='Item distribution algorithm')
|
||||
algorithmLabel.pack(side=LEFT)
|
||||
|
|
14
Main.py
14
Main.py
|
@ -67,7 +67,7 @@ def main(args, seed=None):
|
|||
distribute_items_cutoff(world, 0.66)
|
||||
elif args.algorithm == 'freshness':
|
||||
distribute_items_staleness(world)
|
||||
elif args.algorithm == 'restrictive':
|
||||
elif args.algorithm == 'vt25':
|
||||
distribute_items_restrictive(world, 0)
|
||||
|
||||
logger.info('Calculating playthrough.')
|
||||
|
@ -398,7 +398,7 @@ def flood_items(world):
|
|||
|
||||
|
||||
def generate_itempool(world):
|
||||
if world.difficulty not in ['normal', 'timed', 'timed-ohko', 'timed-countdown'] or world.goal not in ['ganon', 'pedestal', 'dungeons', 'starhunt', 'triforcehunt'] or world.mode not in ['open', 'standard', 'swordless']:
|
||||
if world.difficulty not in ['normal', 'timed', 'timed-ohko', 'timed-countdown'] or world.goal not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'] or world.mode not in ['open', 'standard', 'swordless']:
|
||||
raise NotImplementedError('Not supported yet')
|
||||
|
||||
world.push_item('Ganon', ItemFactory('Triforce'), False)
|
||||
|
@ -463,14 +463,10 @@ def generate_itempool(world):
|
|||
|
||||
if world.goal == 'pedestal':
|
||||
world.push_item('Altar', ItemFactory('Triforce'), False)
|
||||
elif world.goal == 'starhunt':
|
||||
world.treasure_hunt_count = 10
|
||||
world.treasure_hunt_icon = 'Power Star'
|
||||
world.itempool.extend(ItemFactory(['Power Star'] * 15))
|
||||
elif world.goal == 'triforcehunt':
|
||||
world.treasure_hunt_count = 3
|
||||
world.treasure_hunt_count = 20
|
||||
world.treasure_hunt_icon = 'Triforce Piece'
|
||||
world.itempool.extend(ItemFactory(['Triforce Piece'] * 3))
|
||||
world.itempool.extend(ItemFactory(['Triforce Piece'] * 30))
|
||||
|
||||
if random.randint(0, 3) == 0:
|
||||
world.itempool.append(ItemFactory('Magic Upgrade (1/4)'))
|
||||
|
@ -568,7 +564,7 @@ def create_playthrough(world):
|
|||
world = copy_world(world)
|
||||
|
||||
# in treasure hunt and pedestal goals, ganon is invincible
|
||||
if world.goal in ['pedestal', 'starhunt', 'triforcehunt']:
|
||||
if world.goal in ['pedestal', 'triforcehunt']:
|
||||
world.get_location('Ganon').item = None
|
||||
|
||||
# if we only check for beatable, we can do this sanity check first before writing down spheres
|
||||
|
|
8
Rom.py
8
Rom.py
|
@ -285,11 +285,13 @@ def patch_rom(world, rom, hashtable, quickswap=False, beep='normal', sprite=None
|
|||
rom.write_byte(0x180086, 0x00 if world.aga_randomness else 0x01) # set blue ball and ganon warp randomness
|
||||
rom.write_byte(0x1800A1, 0x01) # enable overworld screen transition draining for water level inside swamp
|
||||
if world.goal in ['ganon']:
|
||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals are collected
|
||||
elif world.goal in ['pedestal', 'starhunt', 'triforcehunt']:
|
||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||
elif world.goal in ['pedestal', 'triforcehunt']:
|
||||
rom.write_byte(0x18003E, 0x01) # make ganon invincible
|
||||
elif world.goal in ['dungeons']:
|
||||
rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat
|
||||
elif world.goal in ['crystals']:
|
||||
rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals
|
||||
rom.write_byte(0x18016A, 0x00) # disable free roaming item text boxes
|
||||
rom.write_byte(0x18003B, 0x00) # disable maps showing crystals on overworld
|
||||
rom.write_byte(0x18003C, 0x00) # disable compasses showing dungeon count
|
||||
|
@ -425,7 +427,7 @@ def write_strings(rom, world):
|
|||
write_string_to_rom(rom, 'PyramidFairy', PyramidFairy_texts[random.randint(0, len(PyramidFairy_texts) - 1)])
|
||||
write_string_to_rom(rom, 'Sahasrahla2', Sahasrahla2_texts[random.randint(0, len(Sahasrahla2_texts) - 1)])
|
||||
write_string_to_rom(rom, 'Blind', Blind_texts[random.randint(0, len(Blind_texts) - 1)])
|
||||
if world.goal in ['pedestal', 'starhunt', 'triforcehunt']:
|
||||
if world.goal in ['pedestal', 'triforcehunt']:
|
||||
write_string_to_rom(rom, 'Ganon1Invincible', 'Why are you even here?\n You can\'t even hurt me!')
|
||||
write_string_to_rom(rom, 'Ganon2Invincible', 'Seriously? Go Away, I will not Die.')
|
||||
else:
|
||||
|
|
9
Rules.py
9
Rules.py
|
@ -22,7 +22,10 @@ def set_rules(world):
|
|||
|
||||
if world.goal == 'dungeons':
|
||||
# require all dungeons to beat ganon
|
||||
add_rule(world.get_location('Ganon'), lambda state: state.can_reach('Altar', 'Location') and state.has('Beat Agahnim 1'))
|
||||
add_rule(world.get_location('Ganon'), lambda state: state.can_reach('Altar', 'Location') and state.has('Beat Agahnim 1') and state.has('Beat Agahnim 2'))
|
||||
elif world.goal == 'ganon':
|
||||
# require aga2 to beat ganon
|
||||
add_rule(world.get_location('Ganon'), lambda state: state.has('Beat Agahnim 2'))
|
||||
|
||||
set_big_bomb_rules(world)
|
||||
|
||||
|
@ -306,7 +309,7 @@ def global_rules(world):
|
|||
'[dungeon-A2-6F] Ganons Tower - Room before Moldorm', '[dungeon-A2-6F] Ganons Tower - Moldorm Room']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Ganons Tower)')
|
||||
|
||||
set_rule(world.get_location('Ganon'), lambda state: state.has_beam_sword() and state.has_fire_source() and state.has('Beat Agahnim 2') and state.has('Crystal 1') and state.has('Crystal 2')
|
||||
set_rule(world.get_location('Ganon'), lambda state: state.has_beam_sword() and state.has_fire_source() and state.has('Crystal 1') and state.has('Crystal 2')
|
||||
and state.has('Crystal 3') and state.has('Crystal 4') and state.has('Crystal 5') and state.has('Crystal 6') and state.has('Crystal 7')
|
||||
and (state.has('Tempered Sword') or state.has('Golden Sword') or (state.has('Silver Arrows') and state.has('Bow')) or state.has('Lamp') or state.has('Bottle') or state.has('Half Magic') or state.has('Quarter Magic'))) # need to light torch a sufficient amount of times
|
||||
set_rule(world.get_entrance('Ganon Drop'), lambda state: state.has_beam_sword()) # need to damage ganon to get tiles to drop
|
||||
|
@ -383,7 +386,7 @@ def swordless_rules(world):
|
|||
set_rule(world.get_entrance('Turtle Rock'), lambda state: state.has_Pearl() and state.has_turtle_rock_medallion() and state.can_reach('Turtle Rock (Top)', 'Region')) # sword not required to use medallion for opening in swordless (!)
|
||||
set_rule(world.get_entrance('Skull Woods Torch Room'), lambda state: state.has('Small Key (Skull Woods)', 3) and state.has('Fire Rod')) # no curtain
|
||||
set_rule(world.get_location('Agahnim 2'), lambda state: state.has('Hammer') or state.has('Bug Catching Net'))
|
||||
set_rule(world.get_location('Ganon'), lambda state: state.has('Hammer') and state.has_fire_source() and state.has('Silver Arrows') and state.has('Bow') and state.has('Beat Agahnim 2') and state.has('Crystal 1') and state.has('Crystal 2')
|
||||
set_rule(world.get_location('Ganon'), lambda state: state.has('Hammer') and state.has_fire_source() and state.has('Silver Arrows') and state.has('Bow') and state.has('Crystal 1') and state.has('Crystal 2')
|
||||
and state.has('Crystal 3') and state.has('Crystal 4') and state.has('Crystal 5') and state.has('Crystal 6') and state.has('Crystal 7'))
|
||||
set_rule(world.get_entrance('Ganon Drop'), lambda state: state.has('Hammer')) # need to damage ganon to get tiles to drop
|
||||
|
||||
|
|
Loading…
Reference in New Issue