|
@ -781,7 +781,7 @@ class Spoiler(object):
|
|||
outfile.write('\n\nPaths:\n\n')
|
||||
|
||||
path_listings = []
|
||||
for location, path in self.paths.items():
|
||||
for location, path in sorted(self.paths.items()):
|
||||
path_lines = []
|
||||
for region, exit in path:
|
||||
if exit is not None:
|
||||
|
|
36
Gui.py
|
@ -86,7 +86,7 @@ def guiMain(args=None):
|
|||
romEntry = Entry(romDialogFrame, textvariable=romVar)
|
||||
|
||||
def RomSelect():
|
||||
rom = filedialog.askopenfilename()
|
||||
rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")])
|
||||
romVar.set(rom)
|
||||
romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect)
|
||||
|
||||
|
@ -303,7 +303,7 @@ def guiMain(args=None):
|
|||
romEntry2 = Entry(romDialogFrame2, textvariable=romVar2)
|
||||
|
||||
def RomSelect2():
|
||||
rom = filedialog.askopenfilename()
|
||||
rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")])
|
||||
romVar2.set(rom)
|
||||
romSelectButton2 = Button(romDialogFrame2, text='Select Rom', command=RomSelect2)
|
||||
|
||||
|
@ -415,6 +415,7 @@ class SpriteSelector(object):
|
|||
self.window.wm_title("TAKE ANY ONE YOU WANT")
|
||||
self.window['padx'] = 5
|
||||
self.window['pady'] = 5
|
||||
self.all_sprites = []
|
||||
|
||||
def open_unofficial_sprite_dir(_evt):
|
||||
open_file(self.unofficial_sprite_dir)
|
||||
|
@ -440,11 +441,14 @@ class SpriteSelector(object):
|
|||
button = Button(frame, text="Update official sprites", command=self.update_official_sprites)
|
||||
button.pack(side=RIGHT, padx=(5, 0))
|
||||
|
||||
button = Button(frame, text="Use default Link sprite", command=self.use_default_link_sprite)
|
||||
button = Button(frame, text="Default Link sprite", command=self.use_default_link_sprite)
|
||||
button.pack(side=LEFT, padx=(0, 5))
|
||||
|
||||
button = Button(frame, text="Random sprite", command=self.use_random_sprite)
|
||||
button.pack(side=LEFT, padx=(0, 5))
|
||||
|
||||
if adjuster:
|
||||
button = Button(frame, text="Use current sprite from rom", command=self.use_default_sprite)
|
||||
button = Button(frame, text="Current sprite from rom", command=self.use_default_sprite)
|
||||
button.pack(side=LEFT, padx=(0, 5))
|
||||
|
||||
set_icon(self.window)
|
||||
|
@ -454,14 +458,21 @@ class SpriteSelector(object):
|
|||
frame = LabelFrame(self.window, labelwidget=frame_label, padx=5, pady=5)
|
||||
frame.pack(side=TOP, fill=X)
|
||||
|
||||
i = 0
|
||||
sprites = []
|
||||
|
||||
for file in glob(output_path(path)):
|
||||
sprite = Sprite(file)
|
||||
sprites.append(Sprite(file))
|
||||
|
||||
sprites.sort(key=lambda s: str.lower(s.name or ""))
|
||||
|
||||
i = 0
|
||||
for sprite in sprites:
|
||||
image = get_image_for_sprite(sprite)
|
||||
if image is None:
|
||||
continue
|
||||
self.all_sprites.append(sprite)
|
||||
button = Button(frame, image=image, command=lambda spr=sprite: self.select_sprite(spr))
|
||||
ToolTips.register(button, sprite.name + ("\nBy: %s" % sprite.author_name if sprite.author_name is not None else ""))
|
||||
ToolTips.register(button, sprite.name + ("\nBy: %s" % sprite.author_name if sprite.author_name else ""))
|
||||
button.image = image
|
||||
button.grid(row=i // 16, column=i % 16)
|
||||
i += 1
|
||||
|
@ -544,7 +555,12 @@ class SpriteSelector(object):
|
|||
|
||||
|
||||
def browse_for_sprite(self):
|
||||
sprite = filedialog.askopenfilename()
|
||||
sprite = filedialog.askopenfilename(
|
||||
filetypes=[("All Sprite Sources", (".zspr", ".spr", ".sfc", ".smc")),
|
||||
("ZSprite files", ".zspr"),
|
||||
("Sprite files", ".spr"),
|
||||
("Rom Files", (".sfc", ".smc")),
|
||||
("All Files", "*")])
|
||||
try:
|
||||
self.callback(Sprite(sprite))
|
||||
except Exception:
|
||||
|
@ -560,6 +576,10 @@ class SpriteSelector(object):
|
|||
self.callback(Sprite.default_link_sprite())
|
||||
self.window.destroy()
|
||||
|
||||
def use_random_sprite(self):
|
||||
self.callback(random.choice(self.all_sprites) if self.all_sprites else None)
|
||||
self.window.destroy()
|
||||
|
||||
def select_sprite(self, spritename):
|
||||
self.callback(spritename)
|
||||
self.window.destroy()
|
||||
|
|
26
Main.py
|
@ -15,16 +15,24 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute
|
|||
from ItemList import generate_itempool, difficulties
|
||||
from Utils import output_path
|
||||
|
||||
__version__ = '0.5.1-dev'
|
||||
__version__ = '0.5.2-dev'
|
||||
|
||||
logic_hash = [117, 227, 77, 12, 94, 219, 67, 70, 58, 42, 7, 75, 132, 55, 130, 97, 235, 46, 206, 185, 243, 64, 109, 161, 107, 91, 224, 142, 25, 84, 4, 78,
|
||||
160, 245, 143, 18, 251, 114, 165, 157, 13, 26, 119, 92, 188, 216, 27, 39, 76, 238, 152, 113, 231, 193, 191, 103, 118, 182, 213, 134, 41, 90, 246, 82,
|
||||
57, 225, 150, 139, 99, 151, 184, 11, 85, 209, 144, 147, 47, 56, 129, 247, 121, 177, 79, 1, 215, 207, 126, 136, 105, 100, 180, 5, 2, 14, 153, 6,
|
||||
163, 192, 198, 88, 98, 174, 149, 201, 249, 200, 158, 116, 196, 80, 220, 31, 111, 214, 194, 248, 221, 167, 250, 115, 38, 10, 32, 218, 133, 19, 253, 122,
|
||||
239, 16, 52, 48, 156, 205, 127, 3, 138, 237, 234, 190, 37, 112, 189, 86, 223, 236, 195, 54, 71, 181, 43, 49, 226, 255, 0, 135, 186, 203, 175, 87,
|
||||
21, 229, 120, 124, 145, 171, 252, 155, 22, 62, 199, 51, 35, 179, 159, 44, 69, 30, 172, 242, 140, 74, 9, 83, 183, 93, 202, 137, 108, 241, 173, 23,
|
||||
164, 45, 222, 232, 166, 176, 230, 63, 154, 96, 170, 34, 66, 50, 17, 211, 95, 53, 208, 244, 36, 123, 81, 187, 106, 131, 169, 29, 104, 72, 101, 141,
|
||||
68, 24, 168, 125, 217, 240, 15, 162, 148, 8, 40, 102, 33, 89, 128, 61, 210, 204, 73, 228, 59, 146, 28, 110, 233, 178, 254, 65, 197, 20, 212, 60]
|
||||
logic_hash = [84, 16, 141, 33, 92, 37, 243, 181, 99, 63, 34, 196, 242, 156, 170, 54,
|
||||
249, 188, 62, 89, 236, 131, 109, 118, 24, 116, 239, 48, 227, 30, 126, 43,
|
||||
160, 20, 12, 130, 201, 166, 23, 76, 195, 21, 238, 145, 228, 178, 229, 47,
|
||||
230, 32, 207, 191, 204, 152, 240, 64, 124, 215, 55, 245, 176, 150, 198, 19,
|
||||
67, 151, 222, 175, 127, 246, 26, 162, 112, 173, 205, 83, 86, 121, 79, 75,
|
||||
185, 102, 157, 85, 69, 4, 125, 211, 115, 155, 78, 220, 45, 169, 143, 18,
|
||||
31, 187, 184, 50, 154, 193, 57, 72, 182, 119, 90, 216, 101, 194, 49, 107,
|
||||
15, 98, 117, 226, 241, 134, 167, 29, 17, 68, 234, 11, 66, 28, 172, 53,
|
||||
97, 183, 250, 14, 221, 110, 104, 203, 200, 153, 137, 128, 105, 6, 8, 142,
|
||||
88, 7, 0, 212, 46, 251, 135, 147, 95, 202, 93, 189, 114, 225, 25, 161,
|
||||
158, 218, 210, 174, 146, 214, 252, 74, 164, 237, 35, 165, 70, 171, 65, 219,
|
||||
27, 38, 224, 51, 248, 82, 122, 148, 73, 60, 168, 247, 163, 41, 44, 133,
|
||||
209, 139, 2, 106, 22, 80, 81, 180, 103, 9, 235, 213, 138, 94, 208, 132,
|
||||
77, 61, 254, 96, 186, 253, 217, 199, 42, 40, 223, 177, 3, 159, 255, 113,
|
||||
58, 129, 197, 91, 52, 233, 1, 144, 59, 123, 87, 149, 140, 231, 5, 10,
|
||||
36, 111, 136, 232, 108, 192, 39, 56, 13, 120, 71, 190, 179, 206, 244, 100]
|
||||
|
||||
|
||||
def main(args, seed=None):
|
||||
|
|
4
Rom.py
|
@ -15,7 +15,7 @@ from Items import ItemFactory
|
|||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = '00bf3203026a0d1ee0d988943518806b'
|
||||
RANDOMIZERBASEHASH = '214e4b2a50cb65cd13a8194bc88cb030'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
|
@ -732,7 +732,7 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
|
||||
# set rom name
|
||||
# 21 bytes
|
||||
rom.write_bytes(0x7FC0, bytearray('ER_050_%09d\0' % world.seed, 'utf8') + world.option_identifier.to_bytes(4, 'big'))
|
||||
rom.write_bytes(0x7FC0, bytearray('ER_052_%09d\0' % world.seed, 'utf8') + world.option_identifier.to_bytes(4, 'big'))
|
||||
|
||||
# store hash table for main menu hash
|
||||
rom.write_bytes(0x187F00, hashtable)
|
||||
|
|
23
Rules.py
|
@ -186,15 +186,19 @@ def global_rules(world):
|
|||
set_rule(world.get_entrance('Isolated Ledge Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Superbunny Cave Exit (Bottom)'), lambda state: False) # Cannot get to bottom exit from top. Just exists for shuffling
|
||||
set_rule(world.get_location('Spike Cave'), lambda state:
|
||||
state.has('Hammer') and state.can_lift_rocks()
|
||||
and ((state.has('Cape') and
|
||||
(state.can_extend_magic(16)
|
||||
or (state.can_extend_magic(12) and (state.world.can_take_damage or state.has_Boots()))
|
||||
or (state.can_extend_magic(10) and state.world.can_take_damage and state.has_Boots())))
|
||||
or (state.has('Cane of Byrna') and
|
||||
state.can_extend_magic(12)
|
||||
or (state.can_extend_magic(10) and (state.has_Boots() or state.world.can_take_damage))
|
||||
or (state.world.can_take_damage and (state.has_Boots() or state.has_hearts(4)))))
|
||||
state.has('Hammer') and state.can_lift_rocks() and
|
||||
(
|
||||
(
|
||||
state.has('Cape')
|
||||
and (state.can_extend_magic(16)
|
||||
or (state.can_extend_magic(12) and (state.world.can_take_damage or state.has_Boots()))
|
||||
or (state.can_extend_magic(10) and state.world.can_take_damage and state.has_Boots()))
|
||||
) or (
|
||||
state.has('Cane of Byrna')
|
||||
and (state.can_extend_magic(12)
|
||||
or (state.can_extend_magic(10) and (state.has_Boots() or state.world.can_take_damage))
|
||||
or (state.world.can_take_damage and (state.has_Boots() or state.has_hearts(4)))))
|
||||
)
|
||||
)
|
||||
|
||||
set_rule(world.get_location('Hookshot Cave - Top Right'), lambda state: state.has('Hookshot'))
|
||||
|
@ -458,6 +462,7 @@ def swordless_rules(world):
|
|||
set_rule(world.get_entrance('Misery Mire'), lambda state: state.has_Pearl() and state.has_misery_mire_medallion()) # sword not required to use medallion for opening in swordless (!)
|
||||
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_entrance('Ice Palace Entrance Room'), lambda state: state.has('Fire Rod') or state.has('Bombos')) #in swordless mode bombos pads are present in the relevant parts of ice palace
|
||||
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('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'))
|
||||
|
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |