Whitespace fixes

Removing trailing whitepace.
This commit is contained in:
Kevin Cathcart 2017-11-18 20:43:37 -05:00
parent 3e31502fc0
commit 9d4d3b8456
8 changed files with 50 additions and 50 deletions

View File

@ -185,7 +185,7 @@ class World(object):
return True
return False
def has_beaten_game(self, state):
if state.has('Triforce'): return True
if self.goal in ['triforcehunt']:
@ -329,7 +329,7 @@ class CollectionState(object):
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])

View File

@ -20,9 +20,9 @@ if __name__ == '__main__':
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='''\
@ -37,19 +37,19 @@ if __name__ == '__main__':
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='''\
@ -58,7 +58,7 @@ if __name__ == '__main__':
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', 'ohko', 'timed-countdown'],
help='''\
@ -78,7 +78,7 @@ if __name__ == '__main__':
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='''\
@ -92,7 +92,7 @@ if __name__ == '__main__':
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='''\
@ -115,7 +115,7 @@ if __name__ == '__main__':
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='''\
@ -137,7 +137,7 @@ if __name__ == '__main__':
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.')
@ -147,7 +147,7 @@ if __name__ == '__main__':
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')
@ -157,33 +157,33 @@ if __name__ == '__main__':
''', 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()

View File

@ -167,7 +167,7 @@ def fill_restrictive(world, base_state, locations, itempool):
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)

View File

@ -228,4 +228,4 @@ def create_playthrough(world):
old_world.required_locations = [location.name for sphere in collection_spheres for location in sphere]
# we can finally output our playthrough
old_world.spoiler.playthrough = OrderedDict([(str(i + 1), {str(location): str(location.item) for location in sphere}) for i, sphere in enumerate(collection_spheres)])
old_world.spoiler.playthrough = OrderedDict([(str(i + 1), {str(location): str(location.item) for location in sphere}) for i, sphere in enumerate(collection_spheres)])

View File

@ -209,7 +209,7 @@ randomized.
--algorithm [{freshness,flood,vt21,vt22,vt25,vt26,balanced}]
```
Select item filling algorithm.
Select item filling algorithm.
### Balanced (Default)
This is a variation of vt26 that aims to strike a balance between the overworld heavy vt25 and the dungeon heavy vt26 algorithm.
@ -220,7 +220,7 @@ Items and locations are shuffled like in VT25, and dungeon items are now placed
shuffled it includes a slight deliberate bias against having too many desireable items in Ganon's Tower to help counterbalance
the sheer number of chests in that single location.
### VT25
### VT25
Items and locations are shuffled and placed from the top of the lists. The only thing preventing an item from being placed into a spot
is if is absolutely impossible to be there given the previous made placement choices. Leads to very uniform but guaranteed solvable distributions.
@ -243,7 +243,7 @@ staleness, decreasing the likelihood of receiving a progress item.
--shuffle [{default,simple,restricted,full,madness,insanity,dungeonsfull,dungeonssimple}]
```
Select Entrance Shuffling Algorithm.
Select Entrance Shuffling Algorithm.
### Default
@ -256,7 +256,7 @@ on the overworld. On Death Mountain, entrances are connected more freely.
### Full (Default)
Mixes cave and dungeon entrances freely.
Mixes cave and dungeon entrances freely.
### Restricted
@ -296,7 +296,7 @@ Define seed number to generate. (default: None) Using the same seed with same se
--count COUNT
```
Use to batch generate multiple seeds with same settings.
Use to batch generate multiple seeds with same settings.
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). (default: None)
```

8
Rom.py
View File

@ -21,10 +21,10 @@ class JsonRom(object):
def write_bytes(self, startaddress, values):
self.patches[str(startaddress)] = list(values)
def write_int16_to_rom(self, address, value):
self.write_bytes(address, int16_as_bytes(value))
def write_int32_to_rom(self, address, value):
self.write_bytes(address, int32_as_bytes(value))
@ -47,7 +47,7 @@ class LocalRom(object):
def write_int16_to_rom(self, address, value):
self.write_bytes(address, int16_as_bytes(value))
def write_int32_to_rom(self, address, value):
self.write_bytes(address, int32_as_bytes(value))
@ -86,7 +86,7 @@ class LocalRom(object):
def int16_as_bytes(value):
value = value & 0xFFFF
return [value & 0xFF, (value >> 8) & 0xFF]
def int32_as_bytes(value):
value = value & 0xFFFFFFFF
return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF]

View File

@ -301,7 +301,7 @@ def global_rules(world):
set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 5) or (state.world.get_location('Palace of Darkness - Big Key Chest').item is not None and (state.world.get_location('Palace of Darkness - Big Key Chest').item.name in ['Small Key (Palace of Darkness)'])))
set_rule(world.get_entrance('Palace of Darkness (North)'), lambda state: state.has('Small Key (Palace of Darkness)', 4))
set_rule(world.get_location('Palace of Darkness - Big Chest'), lambda state: state.has('Big Key (Palace of Darkness)'))
if world.keysanity:
set_rule(world.get_entrance('Palace of Darkness Spike Statue Room Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6) or (state.world.get_location('Palace of Darkness - Harmless Hellway').item is not None and (state.world.get_location('Palace of Darkness - Harmless Hellway').item.name in ['Small Key (Palace of Darkness)'])))
set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 6) or (state.world.get_location('Palace of Darkness - Big Key Chest').item is not None and (state.world.get_location('Palace of Darkness - Big Key Chest').item.name in ['Small Key (Palace of Darkness)'])))
@ -310,7 +310,7 @@ def global_rules(world):
set_rule(world.get_entrance('Palace of Darkness Spike Statue Room Door'), lambda state: state.has('Small Key (Palace of Darkness)', 5) or (state.world.get_location('Palace of Darkness - Harmless Hellway').item is not None and (state.world.get_location('Palace of Darkness - Harmless Hellway').item.name in ['Small Key (Palace of Darkness)'])))
set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 5) or (state.world.get_location('Palace of Darkness - Big Key Chest').item is not None and (state.world.get_location('Palace of Darkness - Big Key Chest').item.name in ['Small Key (Palace of Darkness)'])))
set_rule(world.get_entrance('Palace of Darkness Maze Door'), lambda state: state.has('Small Key (Palace of Darkness)', 5))
for location in ['Palace of Darkness - Big Chest', 'Palace of Darkness - Helmasaur']:
forbid_item(world.get_location(location), 'Big Key (Palace of Darkness)')
@ -320,7 +320,7 @@ def global_rules(world):
# these key rules are conservative, you might be able to get away with more lenient rules
randomizer_room_chests = ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right', 'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right']
compass_room_chests = ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right', 'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right']
set_rule(world.get_location('Ganons Tower - Bob\'s Torch'), lambda state: state.has_Boots())
set_rule(world.get_entrance('Ganons Tower (Tile Room)'), lambda state: state.has('Cane of Somaria'))
set_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hammer'))
@ -328,24 +328,24 @@ def global_rules(world):
set_rule(world.get_entrance('Ganons Tower (Map Room)'), lambda state: state.has('Small Key (Ganons Tower)', 4) or (state.world.get_location('Ganons Tower - Map Chest').item is not None and state.world.get_location('Ganons Tower - Map Chest').item.name == 'Big Key (Ganons Tower)' and state.has('Small Key (Ganons Tower)', 3)) or (state.world.get_location('Ganons Tower - Map Chest').item is not None and state.world.get_location('Ganons Tower - Map Chest').item.name == 'Small Key (Ganons Tower)'))
else:
set_rule(world.get_entrance('Ganons Tower (Map Room)'), lambda state: state.has('Small Key (Ganons Tower)', 3) or (state.world.get_location('Ganons Tower - Map Chest').item is not None and state.world.get_location('Ganons Tower - Map Chest').item.name == 'Small Key (Ganons Tower)'))
# It is possible to need more than 2 keys to get through this entance if you spend keys elsewhere We reflect this in the chest requirements.
# However we need to leave these at the lower values derive that with 3 keys it is always possible to reach Bob and Ice Armos.
set_rule(world.get_entrance('Ganons Tower (Double Switch Room)'), lambda state: state.has('Small Key (Ganons Tower)', 2))
# It is possible to need more than 3 keys ....
set_rule(world.get_entrance('Ganons Tower (Firesnake Room)'), lambda state: state.has('Small Key (Ganons Tower)', 3))
#The actual requirements for these rooms to avoid key-lock
set_rule(world.get_location('Ganons Tower - Firesnake Room'), lambda state: state.has('Small Key (Ganons Tower)', 3) or (item_in_locations(state, 'Big Key (Ganons Tower)', randomizer_room_chests) and state.has('Small Key (Ganons Tower)', 2)))
for location in randomizer_room_chests:
set_rule(world.get_location(location), lambda state: state.has('Small Key (Ganons Tower)', 4) or (item_in_locations(state, 'Big Key (Ganons Tower)', randomizer_room_chests) and state.has('Small Key (Ganons Tower)', 3)))
# Once again it is possible to need more than 3 keys...
set_rule(world.get_entrance('Ganons Tower (Tile Room) Key Door'), lambda state: state.has('Small Key (Ganons Tower)', 3) and state.has('Fire Rod'))
# Actual requirements
for location in compass_room_chests:
set_rule(world.get_location(location), lambda state: state.has('Fire Rod') and (state.has('Small Key (Ganons Tower)', 4) or (item_in_locations(state, 'Big Key (Ganons Tower)', compass_room_chests) and state.has('Small Key (Ganons Tower)', 3))))
set_rule(world.get_location('Ganons Tower - Big Chest'), lambda state: state.has('Big Key (Ganons Tower)'))
set_rule(world.get_location('Ganons Tower - Big Key Room - Left'), lambda state: state.has('Bow') or state.has_blunt_weapon())
set_rule(world.get_location('Ganons Tower - Big Key Chest'), lambda state: state.has('Bow') or state.has_blunt_weapon())
@ -429,7 +429,7 @@ def open_rules(world):
# softlock protection as you can reach the sewers small key door with a guard drop key
forbid_item(world.get_location('Hyrule Castle - Boomerang Chest'), 'Small Key (Escape)')
forbid_item(world.get_location('Hyrule Castle - Zelda\'s Chest'), 'Small Key (Escape)')
# to prevent key-lock in keysanity we need to prevent these chests from having an item that
# blocks the small key
if (world.keysanity):
@ -443,7 +443,7 @@ def swordless_rules(world):
# should there ever be fixes that apply to open mode but not swordless, this
# can be revisited.
open_rules(world)
set_rule(world.get_entrance('Agahnims Tower'), lambda state: state.has('Cape') or state.has('Hammer') or state.has('Beat Agahnim 1')) # barrier gets removed after killing agahnim, relevant for entrance shuffle
set_rule(world.get_entrance('Agahnim 1'), lambda state: state.has('Hammer') or state.has('Bug Catching Net') and state.has('Small Key (Agahnims Tower)', 2))
set_rule(world.get_location('Ether Tablet'), lambda state: state.has('Book of Mudora') and state.has('Hammer'))
@ -479,7 +479,7 @@ def set_trock_key_rules(world):
# if we have backdoor access we can waste a key on the trinexx door, then have no lamp to reverse traverse the maze room. We simply require an additional key just to be super safe then. The backdoor access to the chest is otherwise free
if not can_reach_back:
set_rule(world.get_entrance('Turtle Rock Pokey Room'), lambda state: state.has('Small Key (Turtle Rock)', 1))
set_rule(world.get_entrance('Turtle Rock Pokey Room'), lambda state: state.has('Small Key (Turtle Rock)', 1))
else:
set_rule(world.get_entrance('Turtle Rock Pokey Room'), lambda state: state.has('Small Key (Turtle Rock)', 2))
@ -496,8 +496,8 @@ def set_trock_key_rules(world):
# however in keysanity being able to reach all other chests while only having three keys does not imply this contains
# a key, so we again need all four keys unless it contains the big key
if can_reach_back:
set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 4) or (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Small Key (Turtle Rock)'])))
elif world.keysanity:
set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 4) or (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Small Key (Turtle Rock)'])))
elif world.keysanity:
set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 2) if (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Big Key (Turtle Rock)'])) else state.has('Small Key (Turtle Rock)', 4) or (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Small Key (Turtle Rock)'])))
else:
set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 2) if (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Big Key (Turtle Rock)'])) else state.has('Small Key (Turtle Rock)', 3) or (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Small Key (Turtle Rock)'])))

10
Text.py
View File

@ -141,11 +141,11 @@ class Credits(object):
class CreditLine(object):
"""Base class of credit lines"""
def __init__(self, text, align='center'):
self.text = text
self.align = align
@property
def x(self):
x = 0
@ -157,7 +157,7 @@ class CreditLine(object):
x = (32 - len(self.text)) // 2
return x
class SceneCreditLine(CreditLine):
"""Base class for credit lines for the scene portion of the credits"""
def __init__(self, y, text, align='center'):
@ -214,7 +214,7 @@ class SceneLargeCreditLine(SceneCreditLine):
buf += LargeCreditBottomMapper.convert(self.text)
return buf
def string_to_alttp_text(s, maxbytes=256):
lines = s.upper().split('\n')
outbuf = bytearray()
@ -489,7 +489,7 @@ class GreenCreditMapper(TextMapper):
char_map = {' ': 0x9F,
'.': 0x52}
alpha_offset = -0x29
class RedCreditMapper(TextMapper):
char_map = {' ': 0x9F} #fixme
alpha_offset= -0x61