Skip to content

Commit

Permalink
Merge pull request #4 from AmazingAmpharos/Dev
Browse files Browse the repository at this point in the history
Version 0.5.1 update
  • Loading branch information
AmazingAmpharos authored Dec 2, 2017
2 parents 1752196 + d9182a4 commit df8a16c
Show file tree
Hide file tree
Showing 26 changed files with 867 additions and 667 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ dist
build
.idea
*.sfc
*_Spoiler.txt
*_Spoiler.txt
bundle/components.wxs
*.wixobj
README.html
12 changes: 7 additions & 5 deletions BaseClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class World(object):

def __init__(self, shuffle, logic, mode, difficulty, timer, progressive, goal, algorithm, place_dungeon_items, check_beatable_only, shuffle_ganon, quickswap, fastmenu, keysanity):
def __init__(self, shuffle, logic, mode, difficulty, timer, progressive, goal, algorithm, place_dungeon_items, check_beatable_only, shuffle_ganon, quickswap, fastmenu, disable_music, keysanity):
self.shuffle = shuffle
self.logic = logic
self.mode = mode
Expand Down Expand Up @@ -51,6 +51,7 @@ def __init__(self, shuffle, logic, mode, difficulty, timer, progressive, goal, a
self.can_access_trock_eyebridge = None
self.quickswap = quickswap
self.fastmenu = fastmenu
self.disable_music = disable_music
self.keysanity = keysanity
self.spoiler = Spoiler(self)

Expand Down Expand Up @@ -185,7 +186,7 @@ def unlocks_new_location(self, item):
return True

return False

def has_beaten_game(self, state):
if state.has('Triforce'): return True
if self.goal in ['triforcehunt']:
Expand Down Expand Up @@ -232,7 +233,7 @@ def option_identifier(self):
goal = ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'].index(self.goal)
shuffle = ['vanilla', 'simple', 'restricted', 'full', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple'].index(self.shuffle)
difficulty = ['easy', 'normal', 'hard', 'expert', 'insane'].index(self.difficulty)
timer = ['none', 'display', 'timed', 'timed-ohko', 'timed-countdown'].index(self.timer)
timer = ['none', 'display', 'timed', 'timed-ohko', 'timed-countdown','ohko'].index(self.timer)
progressive = ['on', 'off', 'random'].index(self.progressive)
algorithm = ['freshness', 'flood', 'vt21', 'vt22', 'vt25', 'vt26', 'balanced'].index(self.algorithm)
beatableonly = 1 if self.check_beatable_only else 0
Expand Down Expand Up @@ -329,15 +330,15 @@ def has(self, item, count=1):
return item in self.prog_items
else:
return self.item_count(item) >= count

def item_count(self, item):
return len([pritem for pritem in self.prog_items if pritem == item])

def can_lift_rocks(self):
return self.has('Power Glove') or self.has('Titans Mitts')

def has_bottle(self):
return self.has('Bottle') or self.has('BottleRedPotion') or self.has('BottleGreenPotion') or self.has('BottleBluePotion') or self.has('BottleFairy') or self.has('BottleBee') or self.has('BottleGoodBee')
return self.has('Bottle') or self.has('Bottle (Red Potion)') or self.has('Bottle (Green Potion)') or self.has('Bottle (Blue Potion)') or self.has('Bottle (Fairy)') or self.has('Bottle (Bee)') or self.has('Bottle (Good Bee)')

def can_lift_heavy_rocks(self):
return self.has('Titans Mitts')
Expand Down Expand Up @@ -672,6 +673,7 @@ def parse_data(self):
'dungeonitems': self.world.place_dungeon_items,
'quickswap': self.world.quickswap,
'fastmenu': self.world.fastmenu,
'disable_music': self.world.disable_music,
'keysanity': self.world.keysanity}

def to_json(self):
Expand Down
60 changes: 37 additions & 23 deletions EntranceRandomizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import logging
import random
import textwrap
import sys

from Main import main
from Gui import guiMain
from Utils import is_bundled, close_console


class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
Expand All @@ -20,9 +22,9 @@ def _get_help_string(self, action):
parser.add_argument('--logic', default='noglitches', const='noglitches', nargs='?', choices=['noglitches', 'minorglitches'],
help='''\
Select Enforcement of Item Requirements. (default: %(default)s)
No Glitches:
No Glitches:
Minor Glitches: May require Fake Flippers, Bunny Revival
and Dark Room Navigation.
and Dark Room Navigation.
''')
parser.add_argument('--mode', default='open', const='open', nargs='?', choices=['standard', 'open', 'swordless'],
help='''\
Expand All @@ -37,19 +39,19 @@ def _get_help_string(self, action):
Agahnim\'s Tower barrier can be destroyed with
hammer. Misery Mire and Turtle Rock can be opened
without a sword. Hammer damages Ganon. Ether and
Bombos Tablet can be activated with Hammer (and Book).
Bombos Tablet can be activated with Hammer (and Book).
''')
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
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.
Triforce Hunt: Places 30 Triforce Pieces in the world, collect
20 of them 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=['easy', 'normal', 'hard', 'expert', 'insane'],
help='''\
Expand All @@ -58,9 +60,9 @@ def _get_help_string(self, action):
Normal: Normal difficulty.
Hard: A harder setting with less equipment and reduced health.
Expert: A harder yet setting with minimum equipment and health.
Insane: A setting with the absolute minimum in equipment and no extra health.
Insane: A setting with the absolute minimum in equipment and no extra health.
''')
parser.add_argument('--timer', default='none', const='normal', nargs='?', choices=['none', 'display', 'timed', 'timed-ohko', 'timed-countdown'],
parser.add_argument('--timer', default='none', const='normal', nargs='?', choices=['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'],
help='''\
Select game timer setting. Affects available itempool. (default: %(default)s)
None: No timer.
Expand All @@ -74,9 +76,11 @@ def _get_help_string(self, action):
Timed OHKO: Starts clock at 10 minutes. Green Clocks add
5 minutes (Total: 25). As long as clock is at 0,
Link will die in one hit.
OHKO: Like Timed OHKO, but no clock items are present
and the clock is permenantly at zero.
Timed Countdown: Starts with clock at 40 minutes. Same clocks as
Timed mode. If time runs out, you lose (but can
still keep playing).
still keep playing).
''')
parser.add_argument('--progressive', default='on', const='normal', nargs='?', choices=['on', 'off', 'random'],
help='''\
Expand All @@ -90,7 +94,7 @@ def _get_help_string(self, action):
be found at any time. Downgrades are not possible.
Random: Swords, Shields, Armor, and Gloves will, per
category, be randomly progressive or not.
Link will die in one hit.
Link will die in one hit.
''')
parser.add_argument('--algorithm', default='balanced', const='balanced', nargs='?', choices=['freshness', 'flood', 'vt21', 'vt22', 'vt25', 'vt26', 'balanced'],
help='''\
Expand All @@ -113,7 +117,7 @@ def _get_help_string(self, action):
them the more often they were found unreachable.
Flood: Push out items starting from Link\'s House and
slightly biased to placing progression items with
less restrictions.
less restrictions.
''')
parser.add_argument('--shuffle', default='full', const='full', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple'],
help='''\
Expand All @@ -135,7 +139,7 @@ def _get_help_string(self, action):
discretion.
Experimental.
The dungeon variants only mix up dungeons and keep the rest of
the overworld vanilla.
the overworld vanilla.
''')
parser.add_argument('--rom', default='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc', help='Path to an ALttP JAP(1.0) rom to use as a base.')
parser.add_argument('--loglevel', default='info', const='info', nargs='?', choices=['error', 'info', 'warning', 'debug'], help='Select level of logging for output.')
Expand All @@ -145,55 +149,65 @@ def _get_help_string(self, action):
If --seed is provided, it will be used for the first seed, then
used to derive the next seed (i.e. generating 10 seeds with
--seed given will produce the same 10 (different) roms each
time).
time).
''', type=int)
parser.add_argument('--fastmenu', help='Enable instant menu', action='store_true')
parser.add_argument('--quickswap', help='Enable quick item swapping with L and R.', action='store_true')
parser.add_argument('--disablemusic', help='Disables game music.', action='store_true')
parser.add_argument('--keysanity', help='''\
Keys (and other dungeon items) are no longer restricted to
their dungeons, but can be anywhere
''', action='store_true')
parser.add_argument('--nodungeonitems', help='''\
Remove Maps and Compasses from Itempool, replacing them by
empty slots.
empty slots.
''', action='store_true')
parser.add_argument('--beatableonly', help='''\
Only check if the game is beatable with placement. Do not
ensure all locations are reachable. This only has an effect
on the restrictive algorithm currently.
on the restrictive algorithm currently.
''', action='store_true')
parser.add_argument('--shuffleganon', help='''\
If set, include the Pyramid Hole and Ganon's Tower in the
entrance shuffle pool.
If set, include the Pyramid Hole and Ganon's Tower in the
entrance shuffle pool.
''', action='store_true')
parser.add_argument('--heartbeep', default='normal', const='normal', nargs='?', choices=['normal', 'half', 'quarter', 'off'],
help='''\
Select the rate at which the heart beep sound is played at
low health. (default: %(default)s)
low health. (default: %(default)s)
''')
parser.add_argument('--sprite', help='''\
Path to a sprite sheet to use for Link. Needs to be in
binary format and have a length of 0x7000 (28672) bytes,
binary format and have a length of 0x7000 (28672) bytes,
or 0x7078 (28792) bytes including palette data.
Alternatively, can be a ALttP Rom patched with a Link
sprite that will be extracted.
sprite that will be extracted.
''')
parser.add_argument('--suppress_rom', help='Do not create an output rom file.', action='store_true')
parser.add_argument('--gui', help='Launch the GUI', action='store_true')
parser.add_argument('--jsonout', action='store_true', help='''\
Output .json patch to stdout instead of a patched rom. Used
Output .json patch to stdout instead of a patched rom. Used
for VT site integration, do not use otherwise.
''')
args = parser.parse_args()

if is_bundled and len(sys.argv) == 1 :
# for the bundled builds, if we have no arguments, the user
# probably wants the gui. Users of the bundled build who want the command line
# interface shouuld specify at least one option, possibly setting a value to a
# default if they like all the defaults
close_console()
guiMain()
sys.exit(0)

# ToDo: Validate files further than mere existance
if not args.jsonout and not os.path.isfile(args.rom):
input('Could not find valid base rom for patching at expected path %s. Please run with -h to see help for further information. \nPress Enter to exit.' % args.rom)
exit(1)
sys.exit(1)
if args.sprite is not None and not os.path.isfile(args.sprite):
if not args.jsonout:
input('Could not find link sprite sheet at given location. \nPress Enter to exit.' % args.sprite)
exit(1)
sys.exit(1)
else:
raise IOError('Cannot find sprite file at %s' % args.sprite)

Expand Down
2 changes: 1 addition & 1 deletion Fill.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def sweep_from_pool():
while itempool and locations:
item_to_place = itempool.pop()
maximum_exploration_state = sweep_from_pool()

if world.check_beatable_only:
can_beat_without = world.has_beaten_game(maximum_exploration_state)

Expand Down
Loading

0 comments on commit df8a16c

Please sign in to comment.