1832 lines
		
	
	
		
			78 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1832 lines
		
	
	
		
			78 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python3
 | |
| from argparse import Namespace
 | |
| from glob import glob
 | |
| import json
 | |
| import logging
 | |
| import random
 | |
| import os
 | |
| import shutil
 | |
| from tkinter import Checkbutton, OptionMenu, Toplevel, LabelFrame, PhotoImage, Tk, LEFT, RIGHT, BOTTOM, TOP, StringVar, IntVar, Frame, Label, W, E, X, BOTH, Entry, Spinbox, Button, filedialog, messagebox, ttk
 | |
| from urllib.parse import urlparse
 | |
| from urllib.request import urlopen
 | |
| from concurrent.futures import ThreadPoolExecutor, as_completed
 | |
| 
 | |
| import ModuleUpdate
 | |
| ModuleUpdate.update()
 | |
| 
 | |
| from AdjusterMain import adjust
 | |
| from EntranceRandomizer import parse_arguments
 | |
| from GuiUtils import ToolTips, set_icon, BackgroundTaskProgress
 | |
| from Main import main, get_seed, __version__ as MWVersion
 | |
| from Rom import Sprite
 | |
| from Utils import is_bundled, local_path, output_path, open_file
 | |
| 
 | |
| 
 | |
| def guiMain(args=None):
 | |
|     mainWindow = Tk()
 | |
|     mainWindow.wm_title("Berserker's Multiworld %s" % MWVersion)
 | |
| 
 | |
|     set_icon(mainWindow)
 | |
| 
 | |
|     notebook = ttk.Notebook(mainWindow)
 | |
|     randomizerWindow = ttk.Frame(notebook)
 | |
|     adjustWindow = ttk.Frame(notebook)
 | |
|     customWindow = ttk.Frame(notebook)
 | |
|     notebook.add(randomizerWindow, text='Randomize')
 | |
|     notebook.add(adjustWindow, text='Adjust')
 | |
|     notebook.add(customWindow, text='Custom')
 | |
|     notebook.pack()
 | |
| 
 | |
|     # Shared Controls
 | |
| 
 | |
|     farBottomFrame = Frame(mainWindow)
 | |
| 
 | |
|     def open_output():
 | |
|         open_file(output_path(''))
 | |
| 
 | |
|     openOutputButton = Button(farBottomFrame, text='Open Output Directory', command=open_output)
 | |
| 
 | |
|     if os.path.exists(local_path('README.html')):
 | |
|         def open_readme():
 | |
|             open_file(local_path('README.html'))
 | |
|         openReadmeButton = Button(farBottomFrame, text='Open Documentation', command=open_readme)
 | |
|         openReadmeButton.pack(side=LEFT)
 | |
| 
 | |
|     farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5)
 | |
| 
 | |
|     # randomizer controls
 | |
| 
 | |
|     topFrame = Frame(randomizerWindow)
 | |
|     rightHalfFrame = Frame(topFrame)
 | |
|     checkBoxFrame = Frame(rightHalfFrame)
 | |
| 
 | |
|     createSpoilerVar = IntVar()
 | |
|     createSpoilerCheckbutton = Checkbutton(checkBoxFrame, text="Create Spoiler Log", variable=createSpoilerVar)
 | |
|     suppressRomVar = IntVar()
 | |
|     suppressRomCheckbutton = Checkbutton(checkBoxFrame, text="Do not create patched Rom", variable=suppressRomVar)
 | |
|     openpyramidVar = IntVar()
 | |
|     openpyramidCheckbutton = Checkbutton(checkBoxFrame, text="Pre-open Pyramid Hole", variable=openpyramidVar)
 | |
|     mcsbshuffleFrame = Frame(checkBoxFrame)
 | |
|     mcsbLabel = Label(mcsbshuffleFrame, text="Shuffle: ")
 | |
| 
 | |
|     mapshuffleVar = IntVar()
 | |
|     mapshuffleCheckbutton = Checkbutton(mcsbshuffleFrame, text="Maps", variable=mapshuffleVar)
 | |
| 
 | |
|     compassshuffleVar = IntVar()
 | |
|     compassshuffleCheckbutton = Checkbutton(mcsbshuffleFrame, text="Compasses", variable=compassshuffleVar)
 | |
| 
 | |
|     bigkeyshuffleVar = IntVar()
 | |
|     bigkeyshuffleCheckbutton = Checkbutton(mcsbshuffleFrame, text="Big Keys", variable=bigkeyshuffleVar)
 | |
| 
 | |
|     keyshuffleFrame = Frame(checkBoxFrame)
 | |
|     keyshuffleVar = StringVar()
 | |
|     keyshuffleVar.set('off')
 | |
|     modeOptionMenu = OptionMenu(keyshuffleFrame, keyshuffleVar, 'off', 'universal', 'on')
 | |
|     modeLabel = Label(keyshuffleFrame, text='Small Key Shuffle')
 | |
|     modeLabel.pack(side=LEFT)
 | |
|     modeOptionMenu.pack(side=LEFT)
 | |
| 
 | |
|     retroVar = IntVar()
 | |
|     retroCheckbutton = Checkbutton(checkBoxFrame, text="Retro mode", variable=retroVar)
 | |
| 
 | |
|     shuffleGanonVar = IntVar()
 | |
|     shuffleGanonVar.set(1)  # set default
 | |
|     shuffleGanonCheckbutton = Checkbutton(checkBoxFrame, text="Include Ganon's Tower and Pyramid Hole in shuffle pool",
 | |
|                                           variable=shuffleGanonVar)
 | |
|     hintsVar = IntVar()
 | |
|     hintsVar.set(1)  # set default
 | |
|     hintsCheckbutton = Checkbutton(checkBoxFrame, text="Include Helpful Hints", variable=hintsVar)
 | |
|     customVar = IntVar()
 | |
|     customCheckbutton = Checkbutton(checkBoxFrame, text="Use custom item pool", variable=customVar)
 | |
|     balancingVar = IntVar()
 | |
|     balancingVar.set(1)  # set default
 | |
|     balancingCheckbutton = Checkbutton(checkBoxFrame, text="Multiworld Progression Balancing", variable=balancingVar)
 | |
|     patchesVar = IntVar()
 | |
|     patchesVar.set(1)  # set default
 | |
|     patchesCheckbutton = Checkbutton(checkBoxFrame, text="Create Delta Patches", variable=patchesVar)
 | |
|     createSpoilerCheckbutton.pack(expand=True, anchor=W)
 | |
|     suppressRomCheckbutton.pack(expand=True, anchor=W)
 | |
|     openpyramidCheckbutton.pack(expand=True, anchor=W)
 | |
|     mcsbshuffleFrame.pack(expand=True, anchor=W)
 | |
|     mcsbLabel.grid(row=0, column=0)
 | |
|     mapshuffleCheckbutton.grid(row=0, column=1)
 | |
|     compassshuffleCheckbutton.grid(row=0, column=2)
 | |
|     bigkeyshuffleCheckbutton.grid(row=0, column=4)
 | |
|     keyshuffleFrame.pack(expand=True, anchor=W)
 | |
|     retroCheckbutton.pack(expand=True, anchor=W)
 | |
|     shuffleGanonCheckbutton.pack(expand=True, anchor=W)
 | |
|     hintsCheckbutton.pack(expand=True, anchor=W)
 | |
|     customCheckbutton.pack(expand=True, anchor=W)
 | |
|     balancingCheckbutton.pack(expand=True, anchor=W)
 | |
|     patchesCheckbutton.pack(expand=True, anchor=W)
 | |
| 
 | |
|     romOptionsFrame = LabelFrame(rightHalfFrame, text="Rom options")
 | |
|     romOptionsFrame.columnconfigure(0, weight=1)
 | |
|     romOptionsFrame.columnconfigure(1, weight=1)
 | |
|     for i in range(5):
 | |
|         romOptionsFrame.rowconfigure(i, weight=1)
 | |
| 
 | |
|     disableMusicVar = IntVar()
 | |
|     disableMusicCheckbutton = Checkbutton(romOptionsFrame, text="Disable music", variable=disableMusicVar)
 | |
|     disableMusicCheckbutton.grid(row=0, column=0, sticky=E)
 | |
| 
 | |
|     spriteDialogFrame = Frame(romOptionsFrame)
 | |
|     spriteDialogFrame.grid(row=0, column=1)
 | |
|     baseSpriteLabel = Label(spriteDialogFrame, text='Sprite:')
 | |
| 
 | |
|     spriteNameVar = StringVar()
 | |
|     sprite = None
 | |
|     def set_sprite(sprite_param):
 | |
|         nonlocal sprite
 | |
|         if isinstance(sprite_param, str):
 | |
|             sprite = sprite_param
 | |
|             spriteNameVar.set(sprite_param)
 | |
|         elif sprite_param is None or not sprite_param.valid:
 | |
|             sprite = None
 | |
|             spriteNameVar.set('(unchanged)')
 | |
|         else:
 | |
|             sprite = sprite_param
 | |
|             spriteNameVar.set(sprite.name)
 | |
| 
 | |
|     set_sprite(None)
 | |
|     spriteNameVar.set('(unchanged)')
 | |
|     spriteEntry = Label(spriteDialogFrame, textvariable=spriteNameVar)
 | |
| 
 | |
|     def SpriteSelect():
 | |
|         SpriteSelector(mainWindow, set_sprite)
 | |
| 
 | |
|     spriteSelectButton = Button(spriteDialogFrame, text='...', command=SpriteSelect)
 | |
| 
 | |
|     baseSpriteLabel.pack(side=LEFT)
 | |
|     spriteEntry.pack(side=LEFT)
 | |
|     spriteSelectButton.pack(side=LEFT)
 | |
| 
 | |
|     quickSwapVar = IntVar(value=1)
 | |
|     quickSwapCheckbutton = Checkbutton(romOptionsFrame, text="L/R Quickswapping", variable=quickSwapVar)
 | |
|     quickSwapCheckbutton.grid(row=1, column=0, sticky=E)
 | |
| 
 | |
|     fastMenuFrame = Frame(romOptionsFrame)
 | |
|     fastMenuFrame.grid(row=1, column=1, sticky=E)
 | |
|     fastMenuLabel = Label(fastMenuFrame, text='Menu speed')
 | |
|     fastMenuLabel.pack(side=LEFT)
 | |
|     fastMenuVar = StringVar()
 | |
|     fastMenuVar.set('normal')
 | |
|     fastMenuOptionMenu = OptionMenu(fastMenuFrame, fastMenuVar, 'normal', 'instant', 'double', 'triple', 'quadruple', 'half')
 | |
|     fastMenuOptionMenu.pack(side=LEFT)
 | |
| 
 | |
|     heartcolorFrame = Frame(romOptionsFrame)
 | |
|     heartcolorFrame.grid(row=2, column=0, sticky=E)
 | |
|     heartcolorLabel = Label(heartcolorFrame, text='Heart color')
 | |
|     heartcolorLabel.pack(side=LEFT)
 | |
|     heartcolorVar = StringVar()
 | |
|     heartcolorVar.set('red')
 | |
|     heartcolorOptionMenu = OptionMenu(heartcolorFrame, heartcolorVar, 'red', 'blue', 'green', 'yellow', 'random')
 | |
|     heartcolorOptionMenu.pack(side=LEFT)
 | |
| 
 | |
|     heartbeepFrame = Frame(romOptionsFrame)
 | |
|     heartbeepFrame.grid(row=2, column=1, sticky=E)
 | |
|     heartbeepLabel = Label(heartbeepFrame, text='Heartbeep')
 | |
|     heartbeepLabel.pack(side=LEFT)
 | |
|     heartbeepVar = StringVar()
 | |
|     heartbeepVar.set('normal')
 | |
|     heartbeepOptionMenu = OptionMenu(heartbeepFrame, heartbeepVar, 'double', 'normal', 'half', 'quarter', 'off')
 | |
|     heartbeepOptionMenu.pack(side=LEFT)
 | |
| 
 | |
|     owPalettesFrame = Frame(romOptionsFrame)
 | |
|     owPalettesFrame.grid(row=3, column=0, sticky=E)
 | |
|     owPalettesLabel = Label(owPalettesFrame, text='Overworld palettes')
 | |
|     owPalettesLabel.pack(side=LEFT)
 | |
|     owPalettesVar = StringVar()
 | |
|     owPalettesVar.set('default')
 | |
|     owPalettesOptionMenu = OptionMenu(owPalettesFrame, owPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     owPalettesOptionMenu.pack(side=LEFT)
 | |
| 
 | |
|     uwPalettesFrame = Frame(romOptionsFrame)
 | |
|     uwPalettesFrame.grid(row=3, column=1, sticky=E)
 | |
|     uwPalettesLabel = Label(uwPalettesFrame, text='Dungeon palettes')
 | |
|     uwPalettesLabel.pack(side=LEFT)
 | |
|     uwPalettesVar = StringVar()
 | |
|     uwPalettesVar.set('default')
 | |
|     uwPalettesOptionMenu = OptionMenu(uwPalettesFrame, uwPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     uwPalettesOptionMenu.pack(side=LEFT)
 | |
| 
 | |
|     hudPalettesFrame = Frame(romOptionsFrame)
 | |
|     hudPalettesFrame.grid(row=4, column=0, sticky=E)
 | |
|     hudPalettesLabel = Label(hudPalettesFrame, text='HUD palettes')
 | |
|     hudPalettesLabel.pack(side=LEFT)
 | |
|     hudPalettesVar = StringVar()
 | |
|     hudPalettesVar.set('default')
 | |
|     hudPalettesOptionMenu = OptionMenu(hudPalettesFrame, hudPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     hudPalettesOptionMenu.pack(side=LEFT)
 | |
| 
 | |
|     swordPalettesFrame = Frame(romOptionsFrame)
 | |
|     swordPalettesFrame.grid(row=4, column=1, sticky=E)
 | |
|     swordPalettesLabel = Label(swordPalettesFrame, text='Sword palettes')
 | |
|     swordPalettesLabel.pack(side=LEFT)
 | |
|     swordPalettesVar = StringVar()
 | |
|     swordPalettesVar.set('default')
 | |
|     swordPalettesOptionMenu = OptionMenu(swordPalettesFrame, swordPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     swordPalettesOptionMenu.pack(side=LEFT)
 | |
| 
 | |
|     shieldPalettesFrame = Frame(romOptionsFrame)
 | |
|     shieldPalettesFrame.grid(row=5, column=0, sticky=E)
 | |
|     shieldPalettesLabel = Label(shieldPalettesFrame, text='Shield palettes')
 | |
|     shieldPalettesLabel.pack(side=LEFT)
 | |
|     shieldPalettesVar = StringVar()
 | |
|     shieldPalettesVar.set('default')
 | |
|     shieldPalettesOptionMenu = OptionMenu(shieldPalettesFrame, shieldPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     shieldPalettesOptionMenu.pack(side=LEFT)
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|     romDialogFrame = Frame(romOptionsFrame)
 | |
|     romDialogFrame.grid(row=6, column=0, columnspan=2, sticky=W+E)
 | |
| 
 | |
|     baseRomLabel = Label(romDialogFrame, text='Base Rom: ')
 | |
|     romVar = StringVar(value="Zelda no Densetsu - Kamigami no Triforce (Japan).sfc")
 | |
|     romEntry = Entry(romDialogFrame, textvariable=romVar)
 | |
| 
 | |
|     def RomSelect():
 | |
|         rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")])
 | |
|         import Patch
 | |
|         try:
 | |
|             Patch.get_base_rom_bytes(rom)  # throws error on checksum fail
 | |
|         except Exception as e:
 | |
|             logging.exception(e)
 | |
|             messagebox.showerror(title="Error while reading ROM", message=str(e))
 | |
|         else:
 | |
|             romVar.set(rom)
 | |
|             romSelectButton['state'] = "disabled"
 | |
|             romSelectButton["text"] = "ROM verified"
 | |
|     romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect)
 | |
| 
 | |
|     baseRomLabel.pack(side=LEFT)
 | |
|     romEntry.pack(side=LEFT, expand=True, fill=X)
 | |
|     romSelectButton.pack(side=LEFT)
 | |
| 
 | |
|     checkBoxFrame.pack(side=TOP, anchor=W, padx=5, pady=10)
 | |
|     romOptionsFrame.pack(expand=True, fill=BOTH, padx=3)
 | |
| 
 | |
|     drowDownFrame = Frame(topFrame)
 | |
| 
 | |
|     modeFrame = Frame(drowDownFrame)
 | |
|     modeVar = StringVar()
 | |
|     modeVar.set('open')
 | |
|     modeOptionMenu = OptionMenu(modeFrame, modeVar, 'standard', 'open', 'inverted')
 | |
|     modeOptionMenu.pack(side=RIGHT)
 | |
|     modeLabel = Label(modeFrame, text='Game mode')
 | |
|     modeLabel.pack(side=LEFT)
 | |
| 
 | |
|     logicFrame = Frame(drowDownFrame)
 | |
|     logicVar = StringVar()
 | |
|     logicVar.set('noglitches')
 | |
|     logicOptionMenu = OptionMenu(logicFrame, logicVar, 'noglitches', 'minorglitches', 'owglitches', 'nologic')
 | |
|     logicOptionMenu.pack(side=RIGHT)
 | |
|     logicLabel = Label(logicFrame, text='Game logic')
 | |
|     logicLabel.pack(side=LEFT)
 | |
| 
 | |
|     darklogicFrame = Frame(drowDownFrame)
 | |
|     darklogicVar = StringVar()
 | |
|     darklogicVar.set('Lamp')
 | |
|     darklogicOptionMenu = OptionMenu(darklogicFrame, darklogicVar, 'Lamp', 'Lamp or easy Fire Rod torches',
 | |
|                                      'dark traversal')
 | |
|     darklogicOptionMenu.pack(side=RIGHT)
 | |
|     darklogicLabel = Label(darklogicFrame, text='Dark Room Logic')
 | |
|     darklogicLabel.pack(side=LEFT)
 | |
| 
 | |
|     goalFrame = Frame(drowDownFrame)
 | |
|     goalVar = StringVar()
 | |
|     goalVar.set('ganon')
 | |
|     goalOptionMenu = OptionMenu(goalFrame, goalVar, 'ganon', 'pedestal', 'dungeons', 'triforcehunt',
 | |
|                                 'localtriforcehunt', 'ganontriforcehunt', 'localganontriforcehunt', 'crystals', 'ganonpedestal')
 | |
|     goalOptionMenu.pack(side=RIGHT)
 | |
|     goalLabel = Label(goalFrame, text='Game goal')
 | |
|     goalLabel.pack(side=LEFT)
 | |
| 
 | |
|     crystalsGTFrame = Frame(drowDownFrame)
 | |
|     crystalsGTVar = StringVar()
 | |
|     crystalsGTVar.set('7')
 | |
|     crystalsGTOptionMenu = OptionMenu(crystalsGTFrame, crystalsGTVar, '0', '1', '2', '3', '4', '5', '6', '7', 'random')
 | |
|     crystalsGTOptionMenu.pack(side=RIGHT)
 | |
|     crystalsGTLabel = Label(crystalsGTFrame, text='Crystals to open Ganon\'s Tower')
 | |
|     crystalsGTLabel.pack(side=LEFT)
 | |
| 
 | |
|     crystalsGanonFrame = Frame(drowDownFrame)
 | |
|     crystalsGanonVar = StringVar()
 | |
|     crystalsGanonVar.set('7')
 | |
|     crystalsGanonOptionMenu = OptionMenu(crystalsGanonFrame, crystalsGanonVar, '0', '1', '2', '3', '4', '5', '6', '7', 'random')
 | |
|     crystalsGanonOptionMenu.pack(side=RIGHT)
 | |
|     crystalsGanonLabel = Label(crystalsGanonFrame, text='Crystals to fight Ganon')
 | |
|     crystalsGanonLabel.pack(side=LEFT)
 | |
| 
 | |
|     swordFrame = Frame(drowDownFrame)
 | |
|     swordVar = StringVar()
 | |
|     swordVar.set('random')
 | |
|     swordOptionMenu = OptionMenu(swordFrame, swordVar, 'random', 'assured', 'swordless', 'vanilla')
 | |
|     swordOptionMenu.pack(side=RIGHT)
 | |
|     swordLabel = Label(swordFrame, text='Sword availability')
 | |
|     swordLabel.pack(side=LEFT)
 | |
| 
 | |
|     difficultyFrame = Frame(drowDownFrame)
 | |
|     difficultyVar = StringVar()
 | |
|     difficultyVar.set('normal')
 | |
|     difficultyOptionMenu = OptionMenu(difficultyFrame, difficultyVar, 'easy', 'normal', 'hard', 'expert')
 | |
|     difficultyOptionMenu.pack(side=RIGHT)
 | |
|     difficultyLabel = Label(difficultyFrame, text='Difficulty: item pool')
 | |
|     difficultyLabel.pack(side=LEFT)
 | |
| 
 | |
|     itemfunctionFrame = Frame(drowDownFrame)
 | |
|     itemfunctionVar = StringVar()
 | |
|     itemfunctionVar.set('normal')
 | |
|     itemfunctionOptionMenu = OptionMenu(itemfunctionFrame, itemfunctionVar, 'easy', 'normal', 'hard', 'expert')
 | |
|     itemfunctionOptionMenu.pack(side=RIGHT)
 | |
|     itemfunctionLabel = Label(itemfunctionFrame, text='Difficulty: item functionality')
 | |
|     itemfunctionLabel.pack(side=LEFT)
 | |
| 
 | |
|     timerFrame = Frame(drowDownFrame)
 | |
|     timerVar = StringVar()
 | |
|     timerVar.set('none')
 | |
|     timerOptionMenu = OptionMenu(timerFrame, timerVar, 'none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown')
 | |
|     timerOptionMenu.pack(side=RIGHT)
 | |
|     timerLabel = Label(timerFrame, text='Timer setting')
 | |
|     timerLabel.pack(side=LEFT)
 | |
| 
 | |
|     dungeonCounterFrame = Frame(drowDownFrame)
 | |
|     dungeonCounterVar = StringVar()
 | |
|     dungeonCounterVar.set('auto')
 | |
|     dungeonCounterOptionMenu = OptionMenu(dungeonCounterFrame, dungeonCounterVar, 'auto', 'off', 'on', 'on_compass_pickup')
 | |
|     dungeonCounterOptionMenu.pack(side=RIGHT)
 | |
|     dungeonCounterLabel = Label(dungeonCounterFrame, text='Dungeon Chest Counters')
 | |
|     dungeonCounterLabel.pack(side=LEFT)
 | |
| 
 | |
|     progressiveFrame = Frame(drowDownFrame)
 | |
|     progressiveVar = StringVar()
 | |
|     progressiveVar.set('on')
 | |
|     progressiveOptionMenu = OptionMenu(progressiveFrame, progressiveVar, 'on', 'off', 'random')
 | |
|     progressiveOptionMenu.pack(side=RIGHT)
 | |
|     progressiveLabel = Label(progressiveFrame, text='Progressive equipment')
 | |
|     progressiveLabel.pack(side=LEFT)
 | |
| 
 | |
|     accessibilityFrame = Frame(drowDownFrame)
 | |
|     accessibilityVar = StringVar()
 | |
|     accessibilityVar.set('items')
 | |
|     accessibilityOptionMenu = OptionMenu(accessibilityFrame, accessibilityVar, 'items', 'locations', 'none')
 | |
|     accessibilityOptionMenu.pack(side=RIGHT)
 | |
|     accessibilityLabel = Label(accessibilityFrame, text='Item accessibility')
 | |
|     accessibilityLabel.pack(side=LEFT)
 | |
| 
 | |
|     algorithmFrame = Frame(drowDownFrame)
 | |
|     algorithmVar = StringVar()
 | |
|     algorithmVar.set('balanced')
 | |
|     algorithmOptionMenu = OptionMenu(algorithmFrame, algorithmVar, 'flood', 'vt25', 'vt26', 'balanced')
 | |
|     algorithmOptionMenu.pack(side=RIGHT)
 | |
|     algorithmLabel = Label(algorithmFrame, text='Item distribution algorithm')
 | |
|     algorithmLabel.pack(side=LEFT)
 | |
| 
 | |
|     shuffleFrame = Frame(drowDownFrame)
 | |
|     shuffleVar = StringVar()
 | |
|     shuffleVar.set('vanilla')
 | |
|     shuffleOptionMenu = OptionMenu(shuffleFrame, shuffleVar, 'vanilla', 'simple', 'restricted', 'full', 'crossed',
 | |
|                                    'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy',
 | |
|                                    'dungeonsfull', 'dungeonssimple')
 | |
|     shuffleOptionMenu.pack(side=RIGHT)
 | |
|     shuffleLabel = Label(shuffleFrame, text='Entrance shuffle')
 | |
|     shuffleLabel.pack(side=LEFT)
 | |
| 
 | |
|     prizeFrame = Frame(drowDownFrame)
 | |
|     prizeVar = StringVar()
 | |
|     prizeVar.set('general')
 | |
|     prizeOptionMenu = OptionMenu(prizeFrame, prizeVar, 'none', 'general', 'bonk', 'both')
 | |
|     prizeOptionMenu.pack(side=RIGHT)
 | |
|     prizeLabel = Label(prizeFrame, text='Shuffle Prizes/Drops')
 | |
|     prizeLabel.pack(side=LEFT)
 | |
| 
 | |
| 
 | |
|     modeFrame.pack(expand=True, anchor=E)
 | |
|     logicFrame.pack(expand=True, anchor=E)
 | |
|     darklogicFrame.pack(expand=True, anchor=E)
 | |
|     goalFrame.pack(expand=True, anchor=E)
 | |
|     crystalsGTFrame.pack(expand=True, anchor=E)
 | |
|     crystalsGanonFrame.pack(expand=True, anchor=E)
 | |
|     swordFrame.pack(expand=True, anchor=E)
 | |
|     difficultyFrame.pack(expand=True, anchor=E)
 | |
|     itemfunctionFrame.pack(expand=True, anchor=E)
 | |
|     timerFrame.pack(expand=True, anchor=E)
 | |
|     dungeonCounterFrame.pack(expand=True, anchor=E)
 | |
|     progressiveFrame.pack(expand=True, anchor=E)
 | |
|     accessibilityFrame.pack(expand=True, anchor=E)
 | |
|     algorithmFrame.pack(expand=True, anchor=E)
 | |
|     shuffleFrame.pack(expand=True, anchor=E)
 | |
|     prizeFrame.pack(expand=True, anchor=E)
 | |
| 
 | |
|     enemizerFrame = LabelFrame(randomizerWindow, text="Enemizer", padx=5, pady=2)
 | |
| 
 | |
| 
 | |
|     enemizerPathFrame = Frame(enemizerFrame)
 | |
|     enemizerPathFrame.grid(row=0, column=0, columnspan=4, sticky=W + E, padx=3)
 | |
|     enemizerCLIlabel = Label(enemizerPathFrame, text="EnemizerCLI path: ")
 | |
|     enemizerCLIlabel.pack(side=LEFT)
 | |
|     enemizerCLIpathVar = StringVar(value="EnemizerCLI/EnemizerCLI.Core")
 | |
|     enemizerCLIpathEntry = Entry(enemizerPathFrame, textvariable=enemizerCLIpathVar)
 | |
|     enemizerCLIpathEntry.pack(side=LEFT, expand=True, fill=X)
 | |
| 
 | |
|     def EnemizerSelectPath():
 | |
|         path = filedialog.askopenfilename(filetypes=[("EnemizerCLI executable", "*EnemizerCLI*")])
 | |
|         if path:
 | |
|             enemizerCLIpathVar.set(path)
 | |
| 
 | |
|     enemizerCLIbrowseButton = Button(enemizerPathFrame, text='...', command=EnemizerSelectPath)
 | |
|     enemizerCLIbrowseButton.pack(side=LEFT)
 | |
| 
 | |
|     enemizerEnemyFrame = Frame(enemizerFrame)
 | |
|     enemizerEnemyFrame.grid(row=1, column=0, pady=5)
 | |
| 
 | |
|     enemyShuffleVar = IntVar()
 | |
|     enemizerEnemyButton = Checkbutton(enemizerEnemyFrame, text="Enemy shuffle", variable=enemyShuffleVar)
 | |
|     enemizerEnemyButton.pack(side=LEFT)
 | |
| 
 | |
|     enemizerBossFrame = Frame(enemizerFrame)
 | |
|     enemizerBossFrame.grid(row=1, column=1)
 | |
|     enemizerBossVar = StringVar()
 | |
|     enemizerBossVar.set('none')
 | |
|     enemizerBossOption = OptionMenu(enemizerBossFrame, enemizerBossVar, 'none', 'basic', 'normal', 'chaos',
 | |
|                                     "singularity")
 | |
|     enemizerBossLabel = Label(enemizerBossFrame, text='Boss shuffle')
 | |
|     enemizerBossLabel.pack(side=LEFT)
 | |
|     enemizerBossOption.pack(side=LEFT)
 | |
| 
 | |
|     enemizerDamageFrame = Frame(enemizerFrame)
 | |
|     enemizerDamageFrame.grid(row=1, column=2)
 | |
|     enemizerDamageVar = StringVar()
 | |
|     enemizerDamageVar.set('default')
 | |
|     enemizerDamageOption = OptionMenu(enemizerDamageFrame, enemizerDamageVar, 'default', 'shuffled', 'chaos')
 | |
|     enemizerDamageLabel = Label(enemizerDamageFrame, text='Enemy damage')
 | |
|     enemizerDamageLabel.pack(side=LEFT)
 | |
|     enemizerDamageOption.pack(side=LEFT)
 | |
| 
 | |
|     enemizerHealthFrame = Frame(enemizerFrame)
 | |
|     enemizerHealthFrame.grid(row=1, column=3)
 | |
|     enemizerHealthVar = StringVar()
 | |
|     enemizerHealthVar.set('default')
 | |
|     enemizerHealthOption = OptionMenu(enemizerHealthFrame, enemizerHealthVar, 'default', 'easy', 'normal', 'hard',
 | |
|                                       'expert')
 | |
|     enemizerHealthLabel = Label(enemizerHealthFrame, text='Enemy health')
 | |
|     enemizerHealthLabel.pack(side=LEFT)
 | |
|     enemizerHealthOption.pack(side=LEFT)
 | |
| 
 | |
|     potShuffleVar = IntVar()
 | |
|     potShuffleButton = Checkbutton(enemizerFrame, text="Pot shuffle", variable=potShuffleVar)
 | |
|     potShuffleButton.grid(row=2, column=0, sticky=W)
 | |
| 
 | |
|     tileShuffleVar = IntVar()
 | |
|     tileShuffleButton = Checkbutton(enemizerFrame, text="Tile shuffle", variable=tileShuffleVar)
 | |
|     tileShuffleButton.grid(row=2, column=1, sticky=W)
 | |
| 
 | |
|     bushShuffleVar = IntVar()
 | |
|     bushShuffleButton = Checkbutton(enemizerFrame, text="Bush shuffle", variable=bushShuffleVar)
 | |
|     bushShuffleButton.grid(row=2, column=2, sticky=W)
 | |
| 
 | |
|     killableThievesVar = IntVar()
 | |
|     killable_thievesShuffleButton = Checkbutton(enemizerFrame, text="Killable Thieves", variable=killableThievesVar)
 | |
|     killable_thievesShuffleButton.grid(row=2, column=3, sticky=W)
 | |
| 
 | |
|     shopframe = LabelFrame(randomizerWindow, text="Shops", padx=5, pady=2)
 | |
| 
 | |
|     shopPriceShuffleVar = IntVar()
 | |
|     shopPriceShuffleButton = Checkbutton(shopframe, text="Random Prices", variable=shopPriceShuffleVar)
 | |
|     shopPriceShuffleButton.grid(row=0, column=0, sticky=W)
 | |
| 
 | |
|     shopShuffleVar = IntVar()
 | |
|     shopShuffleButton = Checkbutton(shopframe, text="Shuffle Inventories", variable=shopShuffleVar)
 | |
|     shopShuffleButton.grid(row=0, column=1, sticky=W)
 | |
| 
 | |
|     shopUpgradeShuffleVar = IntVar()
 | |
|     shopUpgradeShuffleButton = Checkbutton(shopframe, text="Lootable Upgrades", variable=shopUpgradeShuffleVar)
 | |
|     shopUpgradeShuffleButton.grid(row=0, column=2, sticky=W)
 | |
| 
 | |
|     multiworldframe = LabelFrame(randomizerWindow, text="Multiworld", padx=5, pady=2)
 | |
| 
 | |
|     worldLabel = Label(multiworldframe, text='Worlds')
 | |
|     worldVar = StringVar()
 | |
|     worldSpinbox = Spinbox(multiworldframe, from_=1, to=255, width=5, textvariable=worldVar)
 | |
|     namesLabel = Label(multiworldframe, text='Player names')
 | |
|     namesVar = StringVar()
 | |
|     namesEntry = Entry(multiworldframe, textvariable=namesVar)
 | |
|     seedLabel = Label(multiworldframe, text='Seed #')
 | |
|     seedVar = StringVar()
 | |
|     seedEntry = Entry(multiworldframe, width=20, textvariable=seedVar)
 | |
|     countLabel = Label(multiworldframe, text='Count')
 | |
|     countVar = StringVar()
 | |
|     countSpinbox = Spinbox(multiworldframe, from_=1, to=100, width=5, textvariable=countVar)
 | |
| 
 | |
|     def generateRom():
 | |
|         guiargs = Namespace()
 | |
|         guiargs.multi = int(worldVar.get())
 | |
|         guiargs.names = namesVar.get()
 | |
|         guiargs.seed = int(seedVar.get()) if seedVar.get() else None
 | |
|         guiargs.count = int(countVar.get()) if countVar.get() != '1' else None
 | |
|         guiargs.mode = modeVar.get()
 | |
|         guiargs.logic = logicVar.get()
 | |
|         guiargs.dark_room_logic = {"Lamp": "lamp",
 | |
|                                    "Lamp or easy Fire Rod torches": "torches",
 | |
|                                    "dark traversal": "none"}[darklogicVar.get()]
 | |
|         guiargs.goal = goalVar.get()
 | |
|         guiargs.crystals_gt = crystalsGTVar.get()
 | |
|         guiargs.crystals_ganon = crystalsGanonVar.get()
 | |
|         guiargs.swords = swordVar.get()
 | |
|         guiargs.difficulty = difficultyVar.get()
 | |
|         guiargs.item_functionality = itemfunctionVar.get()
 | |
|         guiargs.timer = timerVar.get()
 | |
|         guiargs.skip_progression_balancing = not balancingVar.get()
 | |
|         if guiargs.timer == "none":
 | |
|             guiargs.timer = False
 | |
|         guiargs.dungeon_counters = dungeonCounterVar.get()
 | |
|         if guiargs.dungeon_counters == "on_compass_pickup":
 | |
|             guiargs.dungeon_counters = "pickup"
 | |
|         elif guiargs.dungeon_counters == "on":
 | |
|             guiargs.dungeon_counters = True
 | |
|         elif guiargs.dungeon_counters == "off":
 | |
|             guiargs.dungeon_counters = False
 | |
|         guiargs.progressive = progressiveVar.get()
 | |
|         guiargs.accessibility = accessibilityVar.get()
 | |
|         guiargs.algorithm = algorithmVar.get()
 | |
|         guiargs.shuffle = shuffleVar.get()
 | |
|         guiargs.heartbeep = heartbeepVar.get()
 | |
|         guiargs.heartcolor = heartcolorVar.get()
 | |
|         guiargs.fastmenu = fastMenuVar.get()
 | |
|         guiargs.create_spoiler = bool(createSpoilerVar.get())
 | |
|         guiargs.skip_playthrough = not bool(createSpoilerVar.get())
 | |
|         guiargs.suppress_rom = bool(suppressRomVar.get())
 | |
|         guiargs.open_pyramid = bool(openpyramidVar.get())
 | |
|         guiargs.mapshuffle = bool(mapshuffleVar.get())
 | |
|         guiargs.compassshuffle = bool(compassshuffleVar.get())
 | |
|         guiargs.keyshuffle = {"on": True, "universal": "universal", "off": False}[keyshuffleVar.get()]
 | |
|         guiargs.bigkeyshuffle = bool(bigkeyshuffleVar.get())
 | |
|         guiargs.retro = bool(retroVar.get())
 | |
|         guiargs.quickswap = bool(quickSwapVar.get())
 | |
|         guiargs.disablemusic = bool(disableMusicVar.get())
 | |
|         guiargs.ow_palettes = owPalettesVar.get()
 | |
|         guiargs.uw_palettes = uwPalettesVar.get()
 | |
|         guiargs.hud_palettes = hudPalettesVar.get()
 | |
|         guiargs.sword_palettes = swordPalettesVar.get()
 | |
|         guiargs.shield_palettes = shieldPalettesVar.get()
 | |
|         guiargs.shuffleganon = bool(shuffleGanonVar.get())
 | |
|         guiargs.hints = bool(hintsVar.get())
 | |
|         guiargs.enemizercli = enemizerCLIpathVar.get()
 | |
|         guiargs.shufflebosses = enemizerBossVar.get()
 | |
|         guiargs.enemy_shuffle = enemyShuffleVar.get()
 | |
|         guiargs.bush_shuffle = bushShuffleVar.get()
 | |
|         guiargs.tile_shuffle = tileShuffleVar.get()
 | |
|         guiargs.killable_thieves = killableThievesVar.get()
 | |
|         guiargs.enemy_health = enemizerHealthVar.get()
 | |
|         guiargs.enemy_damage = enemizerDamageVar.get()
 | |
|         guiargs.shufflepots = bool(potShuffleVar.get())
 | |
|         guiargs.custom = bool(customVar.get())
 | |
|         guiargs.triforce_pieces_required = min(90, int(triforcecountVar.get()))
 | |
|         guiargs.triforce_pieces_available = min(90, int(triforcepieceVar.get()))
 | |
|         guiargs.shop_shuffle = ""
 | |
|         if shopShuffleVar.get():
 | |
|             guiargs.shop_shuffle += "i"
 | |
|         if shopPriceShuffleVar.get():
 | |
|             guiargs.shop_shuffle += "p"
 | |
|         if shopUpgradeShuffleVar.get():
 | |
|             guiargs.shop_shuffle += "u"
 | |
|         guiargs.shuffle_prizes = {"none": "",
 | |
|                                   "bonk": "b",
 | |
|                                   "general": "g",
 | |
|                                   "both": "bg"}[prizeVar.get()]
 | |
|         guiargs.sprite_pool = []
 | |
|         guiargs.customitemarray = [int(bowVar.get()), int(silverarrowVar.get()), int(boomerangVar.get()),
 | |
|                                    int(magicboomerangVar.get()), int(hookshotVar.get()), int(mushroomVar.get()),
 | |
|                                    int(magicpowderVar.get()), int(firerodVar.get()),
 | |
|                                    int(icerodVar.get()), int(bombosVar.get()), int(etherVar.get()), int(quakeVar.get()),
 | |
|                                    int(lampVar.get()), int(hammerVar.get()), int(shovelVar.get()), int(fluteVar.get()),
 | |
|                                    int(bugnetVar.get()),
 | |
|                                    int(bookVar.get()), int(bottleVar.get()), int(somariaVar.get()), int(byrnaVar.get()),
 | |
|                                    int(capeVar.get()), int(mirrorVar.get()), int(bootsVar.get()),
 | |
|                                    int(powergloveVar.get()), int(titansmittVar.get()),
 | |
|                                    int(proggloveVar.get()), int(flippersVar.get()), int(pearlVar.get()),
 | |
|                                    int(heartpieceVar.get()), int(fullheartVar.get()), int(sancheartVar.get()),
 | |
|                                    int(sword1Var.get()), int(sword2Var.get()),
 | |
|                                    int(sword3Var.get()), int(sword4Var.get()), int(progswordVar.get()),
 | |
|                                    int(shield1Var.get()), int(shield2Var.get()), int(shield3Var.get()),
 | |
|                                    int(progshieldVar.get()), int(bluemailVar.get()),
 | |
|                                    int(redmailVar.get()), int(progmailVar.get()), int(halfmagicVar.get()),
 | |
|                                    int(quartermagicVar.get()), int(bcap5Var.get()), int(bcap10Var.get()),
 | |
|                                    int(acap5Var.get()), int(acap10Var.get()),
 | |
|                                    int(arrow1Var.get()), int(arrow10Var.get()), int(bomb1Var.get()),
 | |
|                                    int(bomb3Var.get()), int(rupee1Var.get()), int(rupee5Var.get()),
 | |
|                                    int(rupee20Var.get()), int(rupee50Var.get()), int(rupee100Var.get()),
 | |
|                                    int(rupee300Var.get()), int(rupoorVar.get()), int(blueclockVar.get()),
 | |
|                                    int(greenclockVar.get()), int(redclockVar.get()), int(progbowVar.get()),
 | |
|                                    int(bomb10Var.get()), int(universalkeyVar.get()),
 | |
|                                    int(rupoorcostVar.get()), int(triforceVar.get())]
 | |
|         guiargs.rom = romVar.get()
 | |
|         guiargs.create_diff = patchesVar.get()
 | |
|         guiargs.sprite = sprite
 | |
|         # get default values for missing parameters
 | |
|         for k,v in vars(parse_arguments(['--multi', str(guiargs.multi)])).items():
 | |
|             if k not in vars(guiargs):
 | |
|                 setattr(guiargs, k, v)
 | |
|             elif type(v) is dict: # use same settings for every player
 | |
|                 setattr(guiargs, k, {player: getattr(guiargs, k) for player in range(1, guiargs.multi + 1)})
 | |
|         try:
 | |
|             if not guiargs.suppress_rom and not os.path.exists(guiargs.rom):
 | |
|                 raise FileNotFoundError(f"Could not find specified rom file {guiargs.rom}")
 | |
|             if guiargs.count is not None:
 | |
|                 seed = guiargs.seed
 | |
|                 for _ in range(guiargs.count):
 | |
|                     main(seed=seed, args=guiargs)
 | |
|                     seed = get_seed()
 | |
|             else:
 | |
|                 main(seed=guiargs.seed, args=guiargs)
 | |
|         except Exception as e:
 | |
|             logging.exception(e)
 | |
|             messagebox.showerror(title="Error while creating multiworld", message=str(e))
 | |
|         else:
 | |
|             messagebox.showinfo(title="Success", message="Multiworld created successfully")
 | |
| 
 | |
|     generateButton = Button(farBottomFrame, text='Generate Patched Rom', command=generateRom)
 | |
| 
 | |
|     worldLabel.pack(side=LEFT)
 | |
|     worldSpinbox.pack(side=LEFT)
 | |
|     namesLabel.pack(side=LEFT)
 | |
|     namesEntry.pack(side=LEFT, expand=True, fill=X)
 | |
|     seedLabel.pack(side=LEFT,  padx=(5, 0))
 | |
|     seedEntry.pack(side=LEFT)
 | |
|     countLabel.pack(side=LEFT, padx=(5, 0))
 | |
|     countSpinbox.pack(side=LEFT)
 | |
|     generateButton.pack(side=RIGHT, padx=(5, 0))
 | |
| 
 | |
|     openOutputButton.pack(side=LEFT)
 | |
| 
 | |
|     drowDownFrame.pack(side=LEFT)
 | |
|     rightHalfFrame.pack(side=RIGHT)
 | |
|     topFrame.pack(side=TOP)
 | |
|     multiworldframe.pack(side=BOTTOM, expand=True, fill=X)
 | |
|     enemizerFrame.pack(side=BOTTOM, fill=BOTH)
 | |
|     shopframe.pack(side=BOTTOM, expand=True, fill=X)
 | |
| 
 | |
|     # Adjuster Controls
 | |
| 
 | |
|     topFrame2 = Frame(adjustWindow)
 | |
|     rightHalfFrame2 = Frame(topFrame2)
 | |
|     checkBoxFrame2 = Frame(rightHalfFrame2)
 | |
| 
 | |
|     quickSwapCheckbutton2 = Checkbutton(checkBoxFrame2, text="L/R Item quickswapping", variable=quickSwapVar)
 | |
|     disableMusicCheckbutton2 = Checkbutton(checkBoxFrame2, text="Disable game music", variable=disableMusicVar)
 | |
| 
 | |
|     quickSwapCheckbutton2.pack(expand=True, anchor=W)
 | |
|     disableMusicCheckbutton2.pack(expand=True, anchor=W)
 | |
| 
 | |
|     fileDialogFrame2 = Frame(rightHalfFrame2)
 | |
| 
 | |
|     romDialogFrame2 = Frame(fileDialogFrame2)
 | |
|     baseRomLabel2 = Label(romDialogFrame2, text='Rom to adjust')
 | |
|     romVar2 = StringVar()
 | |
|     romEntry2 = Entry(romDialogFrame2, textvariable=romVar2)
 | |
| 
 | |
|     def RomSelect2():
 | |
|         rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc", ".bmbp")), ("All Files", "*")])
 | |
|         romVar2.set(rom)
 | |
|     romSelectButton2 = Button(romDialogFrame2, text='Select Rom', command=RomSelect2)
 | |
| 
 | |
|     baseRomLabel2.pack(side=LEFT)
 | |
|     romEntry2.pack(side=LEFT)
 | |
|     romSelectButton2.pack(side=LEFT)
 | |
| 
 | |
|     spriteDialogFrame2 = Frame(fileDialogFrame2)
 | |
|     baseSpriteLabel2 = Label(spriteDialogFrame2, text='Link Sprite')
 | |
|     spriteEntry2 = Label(spriteDialogFrame2, textvariable=spriteNameVar)
 | |
| 
 | |
|     def SpriteSelectAdjuster():
 | |
|         SpriteSelector(mainWindow, set_sprite, adjuster=True)
 | |
| 
 | |
|     spriteSelectButton2 = Button(spriteDialogFrame2, text='Select Sprite', command=SpriteSelectAdjuster)
 | |
| 
 | |
|     baseSpriteLabel2.pack(side=LEFT)
 | |
|     spriteEntry2.pack(side=LEFT)
 | |
|     spriteSelectButton2.pack(side=LEFT)
 | |
| 
 | |
|     romDialogFrame2.pack()
 | |
|     spriteDialogFrame2.pack()
 | |
| 
 | |
|     checkBoxFrame2.pack()
 | |
|     fileDialogFrame2.pack()
 | |
| 
 | |
|     drowDownFrame2 = Frame(topFrame2)
 | |
|     heartbeepFrame2 = Frame(drowDownFrame2)
 | |
|     heartbeepOptionMenu2 = OptionMenu(heartbeepFrame2, heartbeepVar, 'double', 'normal', 'half', 'quarter', 'off')
 | |
|     heartbeepOptionMenu2.pack(side=RIGHT)
 | |
|     heartbeepLabel2 = Label(heartbeepFrame2, text='Heartbeep sound rate')
 | |
|     heartbeepLabel2.pack(side=LEFT)
 | |
| 
 | |
|     heartcolorFrame2 = Frame(drowDownFrame2)
 | |
|     heartcolorOptionMenu2 = OptionMenu(heartcolorFrame2, heartcolorVar, 'red', 'blue', 'green', 'yellow', 'random')
 | |
|     heartcolorOptionMenu2.pack(side=RIGHT)
 | |
|     heartcolorLabel2 = Label(heartcolorFrame2, text='Heart color')
 | |
|     heartcolorLabel2.pack(side=LEFT)
 | |
| 
 | |
|     fastMenuFrame2 = Frame(drowDownFrame2)
 | |
|     fastMenuOptionMenu2 = OptionMenu(fastMenuFrame2, fastMenuVar, 'normal', 'instant', 'double', 'triple', 'quadruple', 'half')
 | |
|     fastMenuOptionMenu2.pack(side=RIGHT)
 | |
|     fastMenuLabel2 = Label(fastMenuFrame2, text='Menu speed')
 | |
|     fastMenuLabel2.pack(side=LEFT)
 | |
| 
 | |
|     owPalettesFrame2 = Frame(drowDownFrame2)
 | |
|     owPalettesOptionMenu2 = OptionMenu(owPalettesFrame2, owPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     owPalettesOptionMenu2.pack(side=RIGHT)
 | |
|     owPalettesLabel2 = Label(owPalettesFrame2, text='Overworld palettes')
 | |
|     owPalettesLabel2.pack(side=LEFT)
 | |
| 
 | |
|     uwPalettesFrame2 = Frame(drowDownFrame2)
 | |
|     uwPalettesOptionMenu2 = OptionMenu(uwPalettesFrame2, uwPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     uwPalettesOptionMenu2.pack(side=RIGHT)
 | |
|     uwPalettesLabel2 = Label(uwPalettesFrame2, text='Dungeon palettes')
 | |
|     uwPalettesLabel2.pack(side=LEFT)
 | |
| 
 | |
|     hudPalettesFrame2 = Frame(drowDownFrame2)
 | |
|     hudPalettesOptionMenu2 = OptionMenu(hudPalettesFrame2, hudPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     hudPalettesOptionMenu2.pack(side=RIGHT)
 | |
|     hudPalettesLabel2 = Label(hudPalettesFrame2, text='HUD palettes')
 | |
|     hudPalettesLabel2.pack(side=LEFT)
 | |
| 
 | |
|     swordPalettesFrame2 = Frame(drowDownFrame2)
 | |
|     swordPalettesOptionMenu2 = OptionMenu(swordPalettesFrame2, swordPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     swordPalettesOptionMenu2.pack(side=RIGHT)
 | |
|     swordPalettesLabel2 = Label(swordPalettesFrame2, text='Sword palettes')
 | |
|     swordPalettesLabel2.pack(side=LEFT)
 | |
| 
 | |
|     shieldPalettesFrame2 = Frame(drowDownFrame2)
 | |
|     shieldPalettesOptionMenu2 = OptionMenu(shieldPalettesFrame2, shieldPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | |
|     shieldPalettesOptionMenu2.pack(side=RIGHT)
 | |
|     shieldPalettesLabel2 = Label(shieldPalettesFrame2, text='Shield palettes')
 | |
|     shieldPalettesLabel2.pack(side=LEFT)
 | |
| 
 | |
|     heartbeepFrame2.pack(expand=True, anchor=E)
 | |
|     heartcolorFrame2.pack(expand=True, anchor=E)
 | |
|     fastMenuFrame2.pack(expand=True, anchor=E)
 | |
|     owPalettesFrame2.pack(expand=True, anchor=E)
 | |
|     uwPalettesFrame2.pack(expand=True, anchor=E)
 | |
|     hudPalettesFrame2.pack(expand=True, anchor=E)
 | |
|     swordPalettesFrame2.pack(expand=True, anchor=E)
 | |
|     shieldPalettesFrame2.pack(expand=True, anchor=E)
 | |
| 
 | |
|     bottomFrame2 = Frame(topFrame2)
 | |
| 
 | |
|     def adjustRom():
 | |
|         guiargs = Namespace()
 | |
|         guiargs.heartbeep = heartbeepVar.get()
 | |
|         guiargs.heartcolor = heartcolorVar.get()
 | |
|         guiargs.fastmenu = fastMenuVar.get()
 | |
|         guiargs.ow_palettes = owPalettesVar.get()
 | |
|         guiargs.uw_palettes = uwPalettesVar.get()
 | |
|         guiargs.hud_palettes = hudPalettesVar.get()
 | |
|         guiargs.sword_palettes = swordPalettesVar.get()
 | |
|         guiargs.shield_palettes = shieldPalettesVar.get()
 | |
|         guiargs.quickswap = bool(quickSwapVar.get())
 | |
|         guiargs.disablemusic = bool(disableMusicVar.get())
 | |
|         guiargs.rom = romVar2.get()
 | |
|         guiargs.baserom = romVar.get()
 | |
|         guiargs.sprite = sprite
 | |
|         try:
 | |
|             guiargs, path = adjust(args=guiargs)
 | |
|         except Exception as e:
 | |
|             logging.exception(e)
 | |
|             messagebox.showerror(title="Error while adjusting Rom", message=str(e))
 | |
|         else:
 | |
|             messagebox.showinfo(title="Success", message="Rom patched successfully")
 | |
|             from Utils import persistent_store
 | |
|             persistent_store("adjuster", "last_settings", guiargs)
 | |
| 
 | |
|     adjustButton = Button(bottomFrame2, text='Adjust Rom', command=adjustRom)
 | |
| 
 | |
|     adjustButton.pack(side=LEFT, padx=(5, 0))
 | |
| 
 | |
|     drowDownFrame2.pack(side=LEFT, pady=(0, 40))
 | |
|     rightHalfFrame2.pack(side=RIGHT)
 | |
|     topFrame2.pack(side=TOP, pady=70)
 | |
|     bottomFrame2.pack(side=BOTTOM, pady=(180, 0))
 | |
| 
 | |
|     # Custom Controls
 | |
| 
 | |
|     topFrame3 = Frame(customWindow)
 | |
| 
 | |
|     def validation(P):
 | |
|         if str.isdigit(P) or P == "":
 | |
|             return True
 | |
|         else:
 | |
|             return False
 | |
|     vcmd=(topFrame3.register(validation), '%P')
 | |
| 
 | |
|     itemList1 = Frame(topFrame3)
 | |
|     itemList2 = Frame(topFrame3)
 | |
|     itemList3 = Frame(topFrame3)
 | |
|     itemList4 = Frame(topFrame3)
 | |
|     itemList5 = Frame(topFrame3)
 | |
| 
 | |
|     bowFrame = Frame(itemList1)
 | |
|     bowLabel = Label(bowFrame, text='Bow')
 | |
|     bowVar = StringVar(value='0')
 | |
|     bowEntry = Entry(bowFrame, textvariable=bowVar, width=3, validate='all', vcmd=vcmd)
 | |
|     bowFrame.pack()
 | |
|     bowLabel.pack(anchor=W, side=LEFT, padx=(0,53))
 | |
|     bowEntry.pack(anchor=E)
 | |
| 
 | |
|     progbowFrame = Frame(itemList1)
 | |
|     progbowLabel = Label(progbowFrame, text='Prog.Bow')
 | |
|     progbowVar = StringVar(value='2')
 | |
|     progbowEntry = Entry(progbowFrame, textvariable=progbowVar, width=3, validate='all', vcmd=vcmd)
 | |
|     progbowFrame.pack()
 | |
|     progbowLabel.pack(anchor=W, side=LEFT, padx=(0,25))
 | |
|     progbowEntry.pack(anchor=E)
 | |
| 
 | |
|     boomerangFrame = Frame(itemList1)
 | |
|     boomerangLabel = Label(boomerangFrame, text='Boomerang')
 | |
|     boomerangVar = StringVar(value='1')
 | |
|     boomerangEntry = Entry(boomerangFrame, textvariable=boomerangVar, width=3, validate='all', vcmd=vcmd)
 | |
|     boomerangFrame.pack()
 | |
|     boomerangLabel.pack(anchor=W, side=LEFT, padx=(0,14))
 | |
|     boomerangEntry.pack(anchor=E)
 | |
| 
 | |
|     magicboomerangFrame = Frame(itemList1)
 | |
|     magicboomerangLabel = Label(magicboomerangFrame, text='M.Boomerang')
 | |
|     magicboomerangVar = StringVar(value='1')
 | |
|     magicboomerangEntry = Entry(magicboomerangFrame, textvariable=magicboomerangVar, width=3, validate='all', vcmd=vcmd)
 | |
|     magicboomerangFrame.pack()
 | |
|     magicboomerangLabel.pack(anchor=W, side=LEFT)
 | |
|     magicboomerangEntry.pack(anchor=E)
 | |
| 
 | |
|     hookshotFrame = Frame(itemList1)
 | |
|     hookshotLabel = Label(hookshotFrame, text='Hookshot')
 | |
|     hookshotVar = StringVar(value='1')
 | |
|     hookshotEntry = Entry(hookshotFrame, textvariable=hookshotVar, width=3, validate='all', vcmd=vcmd)
 | |
|     hookshotFrame.pack()
 | |
|     hookshotLabel.pack(anchor=W, side=LEFT, padx=(0,24))
 | |
|     hookshotEntry.pack(anchor=E)
 | |
| 
 | |
|     mushroomFrame = Frame(itemList1)
 | |
|     mushroomLabel = Label(mushroomFrame, text='Mushroom')
 | |
|     mushroomVar = StringVar(value='1')
 | |
|     mushroomEntry = Entry(mushroomFrame, textvariable=mushroomVar, width=3, validate='all', vcmd=vcmd)
 | |
|     mushroomFrame.pack()
 | |
|     mushroomLabel.pack(anchor=W, side=LEFT, padx=(0,17))
 | |
|     mushroomEntry.pack(anchor=E)
 | |
| 
 | |
|     magicpowderFrame = Frame(itemList1)
 | |
|     magicpowderLabel = Label(magicpowderFrame, text='Magic Powder')
 | |
|     magicpowderVar = StringVar(value='1')
 | |
|     magicpowderEntry = Entry(magicpowderFrame, textvariable=magicpowderVar, width=3, validate='all', vcmd=vcmd)
 | |
|     magicpowderFrame.pack()
 | |
|     magicpowderLabel.pack(anchor=W, side=LEFT)
 | |
|     magicpowderEntry.pack(anchor=E)
 | |
| 
 | |
|     firerodFrame = Frame(itemList1)
 | |
|     firerodLabel = Label(firerodFrame, text='Fire Rod')
 | |
|     firerodVar = StringVar(value='1')
 | |
|     firerodEntry = Entry(firerodFrame, textvariable=firerodVar, width=3, validate='all', vcmd=vcmd)
 | |
|     firerodFrame.pack()
 | |
|     firerodLabel.pack(anchor=W, side=LEFT, padx=(0,33))
 | |
|     firerodEntry.pack(anchor=E)
 | |
| 
 | |
|     icerodFrame = Frame(itemList1)
 | |
|     icerodLabel = Label(icerodFrame, text='Ice Rod')
 | |
|     icerodVar = StringVar(value='1')
 | |
|     icerodEntry = Entry(icerodFrame, textvariable=icerodVar, width=3, validate='all', vcmd=vcmd)
 | |
|     icerodFrame.pack()
 | |
|     icerodLabel.pack(anchor=W, side=LEFT, padx=(0,37))
 | |
|     icerodEntry.pack(anchor=E)
 | |
| 
 | |
|     bombosFrame = Frame(itemList1)
 | |
|     bombosLabel = Label(bombosFrame, text='Bombos')
 | |
|     bombosVar = StringVar(value='1')
 | |
|     bombosEntry = Entry(bombosFrame, textvariable=bombosVar, width=3, validate='all', vcmd=vcmd)
 | |
|     bombosFrame.pack()
 | |
|     bombosLabel.pack(anchor=W, side=LEFT, padx=(0,32))
 | |
|     bombosEntry.pack(anchor=E)
 | |
| 
 | |
|     etherFrame = Frame(itemList1)
 | |
|     etherLabel = Label(etherFrame, text='Ether')
 | |
|     etherVar = StringVar(value='1')
 | |
|     etherEntry = Entry(etherFrame, textvariable=etherVar, width=3, validate='all', vcmd=vcmd)
 | |
|     etherFrame.pack()
 | |
|     etherLabel.pack(anchor=W, side=LEFT, padx=(0,49))
 | |
|     etherEntry.pack(anchor=E)
 | |
| 
 | |
|     quakeFrame = Frame(itemList1)
 | |
|     quakeLabel = Label(quakeFrame, text='Quake')
 | |
|     quakeVar = StringVar(value='1')
 | |
|     quakeEntry = Entry(quakeFrame, textvariable=quakeVar, width=3, validate='all', vcmd=vcmd)
 | |
|     quakeFrame.pack()
 | |
|     quakeLabel.pack(anchor=W, side=LEFT, padx=(0,42))
 | |
|     quakeEntry.pack(anchor=E)
 | |
| 
 | |
|     lampFrame = Frame(itemList1)
 | |
|     lampLabel = Label(lampFrame, text='Lamp')
 | |
|     lampVar = StringVar(value='1')
 | |
|     lampEntry = Entry(lampFrame, textvariable=lampVar, width=3, validate='all', vcmd=vcmd)
 | |
|     lampFrame.pack()
 | |
|     lampLabel.pack(anchor=W, side=LEFT, padx=(0,46))
 | |
|     lampEntry.pack(anchor=E)
 | |
| 
 | |
|     hammerFrame = Frame(itemList1)
 | |
|     hammerLabel = Label(hammerFrame, text='Hammer')
 | |
|     hammerVar = StringVar(value='1')
 | |
|     hammerEntry = Entry(hammerFrame, textvariable=hammerVar, width=3, validate='all', vcmd=vcmd)
 | |
|     hammerFrame.pack()
 | |
|     hammerLabel.pack(anchor=W, side=LEFT, padx=(0,29))
 | |
|     hammerEntry.pack(anchor=E)
 | |
| 
 | |
|     shovelFrame = Frame(itemList1)
 | |
|     shovelLabel = Label(shovelFrame, text='Shovel')
 | |
|     shovelVar = StringVar(value='1')
 | |
|     shovelEntry = Entry(shovelFrame, textvariable=shovelVar, width=3, validate='all', vcmd=vcmd)
 | |
|     shovelFrame.pack()
 | |
|     shovelLabel.pack(anchor=W, side=LEFT, padx=(0,41))
 | |
|     shovelEntry.pack(anchor=E)
 | |
| 
 | |
|     fluteFrame = Frame(itemList1)
 | |
|     fluteLabel = Label(fluteFrame, text='Flute')
 | |
|     fluteVar = StringVar(value='1')
 | |
|     fluteEntry = Entry(fluteFrame, textvariable=fluteVar, width=3, validate='all', vcmd=vcmd)
 | |
|     fluteFrame.pack()
 | |
|     fluteLabel.pack(anchor=W, side=LEFT, padx=(0,50))
 | |
|     fluteEntry.pack(anchor=E)
 | |
| 
 | |
|     bugnetFrame = Frame(itemList2)
 | |
|     bugnetLabel = Label(bugnetFrame, text='Bug Net')
 | |
|     bugnetVar = StringVar(value='1')
 | |
|     bugnetEntry = Entry(bugnetFrame, textvariable=bugnetVar, width=3, validate='all', vcmd=vcmd)
 | |
|     bugnetFrame.pack()
 | |
|     bugnetLabel.pack(anchor=W, side=LEFT, padx=(0,41))
 | |
|     bugnetEntry.pack(anchor=E)
 | |
| 
 | |
|     bookFrame = Frame(itemList2)
 | |
|     bookLabel = Label(bookFrame, text='Book')
 | |
|     bookVar = StringVar(value='1')
 | |
|     bookEntry = Entry(bookFrame, textvariable=bookVar, width=3, validate='all', vcmd=vcmd)
 | |
|     bookFrame.pack()
 | |
|     bookLabel.pack(anchor=W, side=LEFT, padx=(0,57))
 | |
|     bookEntry.pack(anchor=E)
 | |
| 
 | |
|     bottleFrame = Frame(itemList2)
 | |
|     bottleLabel = Label(bottleFrame, text='Bottle')
 | |
|     bottleVar = StringVar(value='4')
 | |
|     bottleEntry = Entry(bottleFrame, textvariable=bottleVar, width=3, validate='all', vcmd=vcmd)
 | |
|     bottleFrame.pack()
 | |
|     bottleLabel.pack(anchor=W, side=LEFT, padx=(0,53))
 | |
|     bottleEntry.pack(anchor=E)
 | |
| 
 | |
|     somariaFrame = Frame(itemList2)
 | |
|     somariaLabel = Label(somariaFrame, text='C.Somaria')
 | |
|     somariaVar = StringVar(value='1')
 | |
|     somariaEntry = Entry(somariaFrame, textvariable=somariaVar, width=3, validate='all', vcmd=vcmd)
 | |
|     somariaFrame.pack()
 | |
|     somariaLabel.pack(anchor=W, side=LEFT, padx=(0,30))
 | |
|     somariaEntry.pack(anchor=E)
 | |
| 
 | |
|     byrnaFrame = Frame(itemList2)
 | |
|     byrnaLabel = Label(byrnaFrame, text='C.Byrna')
 | |
|     byrnaVar = StringVar(value='1')
 | |
|     byrnaEntry = Entry(byrnaFrame, textvariable=byrnaVar, width=3, validate='all', vcmd=vcmd)
 | |
|     byrnaFrame.pack()
 | |
|     byrnaLabel.pack(anchor=W, side=LEFT, padx=(0,43))
 | |
|     byrnaEntry.pack(anchor=E)
 | |
| 
 | |
|     capeFrame = Frame(itemList2)
 | |
|     capeLabel = Label(capeFrame, text='Magic Cape')
 | |
|     capeVar = StringVar(value='1')
 | |
|     capeEntry = Entry(capeFrame, textvariable=capeVar, width=3, validate='all', vcmd=vcmd)
 | |
|     capeFrame.pack()
 | |
|     capeLabel.pack(anchor=W, side=LEFT, padx=(0,21))
 | |
|     capeEntry.pack(anchor=E)
 | |
| 
 | |
|     mirrorFrame = Frame(itemList2)
 | |
|     mirrorLabel = Label(mirrorFrame, text='Magic Mirror')
 | |
|     mirrorVar = StringVar(value='1')
 | |
|     mirrorEntry = Entry(mirrorFrame, textvariable=mirrorVar, width=3, validate='all', vcmd=vcmd)
 | |
|     mirrorFrame.pack()
 | |
|     mirrorLabel.pack(anchor=W, side=LEFT, padx=(0,15))
 | |
|     mirrorEntry.pack(anchor=E)
 | |
| 
 | |
|     bootsFrame = Frame(itemList2)
 | |
|     bootsLabel = Label(bootsFrame, text='Pegasus Boots')
 | |
|     bootsVar = StringVar(value='1')
 | |
|     bootsEntry = Entry(bootsFrame, textvariable=bootsVar, width=3, validate='all', vcmd=vcmd)
 | |
|     bootsFrame.pack()
 | |
|     bootsLabel.pack(anchor=W, side=LEFT, padx=(0,8))
 | |
|     bootsEntry.pack(anchor=E)
 | |
| 
 | |
|     powergloveFrame = Frame(itemList2)
 | |
|     powergloveLabel = Label(powergloveFrame, text='Power Glove')
 | |
|     powergloveVar = StringVar(value='0')
 | |
|     powergloveEntry = Entry(powergloveFrame, textvariable=powergloveVar, width=3, validate='all', vcmd=vcmd)
 | |
|     powergloveFrame.pack()
 | |
|     powergloveLabel.pack(anchor=W, side=LEFT, padx=(0,18))
 | |
|     powergloveEntry.pack(anchor=E)
 | |
| 
 | |
|     titansmittFrame = Frame(itemList2)
 | |
|     titansmittLabel = Label(titansmittFrame, text='Titan\'s Mitt')
 | |
|     titansmittVar = StringVar(value='0')
 | |
|     titansmittEntry = Entry(titansmittFrame, textvariable=titansmittVar, width=3, validate='all', vcmd=vcmd)
 | |
|     titansmittFrame.pack()
 | |
|     titansmittLabel.pack(anchor=W, side=LEFT, padx=(0,24))
 | |
|     titansmittEntry.pack(anchor=E)
 | |
| 
 | |
|     proggloveFrame = Frame(itemList2)
 | |
|     proggloveLabel = Label(proggloveFrame, text='Prog.Glove')
 | |
|     proggloveVar = StringVar(value='2')
 | |
|     proggloveEntry = Entry(proggloveFrame, textvariable=proggloveVar, width=3, validate='all', vcmd=vcmd)
 | |
|     proggloveFrame.pack()
 | |
|     proggloveLabel.pack(anchor=W, side=LEFT, padx=(0,26))
 | |
|     proggloveEntry.pack(anchor=E)
 | |
| 
 | |
|     flippersFrame = Frame(itemList2)
 | |
|     flippersLabel = Label(flippersFrame, text='Flippers')
 | |
|     flippersVar = StringVar(value='1')
 | |
|     flippersEntry = Entry(flippersFrame, textvariable=flippersVar, width=3, validate='all', vcmd=vcmd)
 | |
|     flippersFrame.pack()
 | |
|     flippersLabel.pack(anchor=W, side=LEFT, padx=(0,43))
 | |
|     flippersEntry.pack(anchor=E)
 | |
| 
 | |
|     pearlFrame = Frame(itemList2)
 | |
|     pearlLabel = Label(pearlFrame, text='Moon Pearl')
 | |
|     pearlVar = StringVar(value='1')
 | |
|     pearlEntry = Entry(pearlFrame, textvariable=pearlVar, width=3, validate='all', vcmd=vcmd)
 | |
|     pearlFrame.pack()
 | |
|     pearlLabel.pack(anchor=W, side=LEFT, padx=(0,23))
 | |
|     pearlEntry.pack(anchor=E)
 | |
| 
 | |
|     heartpieceFrame = Frame(itemList2)
 | |
|     heartpieceLabel = Label(heartpieceFrame, text='Piece of Heart')
 | |
|     heartpieceVar = StringVar(value='24')
 | |
|     heartpieceEntry = Entry(heartpieceFrame, textvariable=heartpieceVar, width=3, validate='all', vcmd=vcmd)
 | |
|     heartpieceFrame.pack()
 | |
|     heartpieceLabel.pack(anchor=W, side=LEFT, padx=(0,10))
 | |
|     heartpieceEntry.pack(anchor=E)
 | |
| 
 | |
|     fullheartFrame = Frame(itemList2)
 | |
|     fullheartLabel = Label(fullheartFrame, text='Heart Container')
 | |
|     fullheartVar = StringVar(value='10')
 | |
|     fullheartEntry = Entry(fullheartFrame, textvariable=fullheartVar, width=3, validate='all', vcmd=vcmd)
 | |
|     fullheartFrame.pack()
 | |
|     fullheartLabel.pack(anchor=W, side=LEFT)
 | |
|     fullheartEntry.pack(anchor=E)
 | |
| 
 | |
|     sancheartFrame = Frame(itemList2)
 | |
|     sancheartLabel = Label(sancheartFrame, text='Sanctuary Heart')
 | |
|     sancheartVar = StringVar(value='1')
 | |
|     sancheartEntry = Entry(sancheartFrame, textvariable=sancheartVar, width=3, validate='all', vcmd=vcmd)
 | |
|     sancheartFrame.pack()
 | |
|     sancheartLabel.pack(anchor=W, side=LEFT)
 | |
|     sancheartEntry.pack(anchor=E)
 | |
| 
 | |
|     sword1Frame = Frame(itemList3)
 | |
|     sword1Label = Label(sword1Frame, text='Sword 1')
 | |
|     sword1Var = StringVar(value='0')
 | |
|     sword1Entry = Entry(sword1Frame, textvariable=sword1Var, width=3, validate='all', vcmd=vcmd)
 | |
|     sword1Frame.pack()
 | |
|     sword1Label.pack(anchor=W, side=LEFT, padx=(0,34))
 | |
|     sword1Entry.pack(anchor=E)
 | |
| 
 | |
|     sword2Frame = Frame(itemList3)
 | |
|     sword2Label = Label(sword2Frame, text='Sword 2')
 | |
|     sword2Var = StringVar(value='0')
 | |
|     sword2Entry = Entry(sword2Frame, textvariable=sword2Var, width=3, validate='all', vcmd=vcmd)
 | |
|     sword2Frame.pack()
 | |
|     sword2Label.pack(anchor=W, side=LEFT, padx=(0,34))
 | |
|     sword2Entry.pack(anchor=E)
 | |
| 
 | |
|     sword3Frame = Frame(itemList3)
 | |
|     sword3Label = Label(sword3Frame, text='Sword 3')
 | |
|     sword3Var = StringVar(value='0')
 | |
|     sword3Entry = Entry(sword3Frame, textvariable=sword3Var, width=3, validate='all', vcmd=vcmd)
 | |
|     sword3Frame.pack()
 | |
|     sword3Label.pack(anchor=W, side=LEFT, padx=(0,34))
 | |
|     sword3Entry.pack(anchor=E)
 | |
| 
 | |
|     sword4Frame = Frame(itemList3)
 | |
|     sword4Label = Label(sword4Frame, text='Sword 4')
 | |
|     sword4Var = StringVar(value='0')
 | |
|     sword4Entry = Entry(sword4Frame, textvariable=sword4Var, width=3, validate='all', vcmd=vcmd)
 | |
|     sword4Frame.pack()
 | |
|     sword4Label.pack(anchor=W, side=LEFT, padx=(0,34))
 | |
|     sword4Entry.pack(anchor=E)
 | |
| 
 | |
|     progswordFrame = Frame(itemList3)
 | |
|     progswordLabel = Label(progswordFrame, text='Prog.Sword')
 | |
|     progswordVar = StringVar(value='4')
 | |
|     progswordEntry = Entry(progswordFrame, textvariable=progswordVar, width=3, validate='all', vcmd=vcmd)
 | |
|     progswordFrame.pack()
 | |
|     progswordLabel.pack(anchor=W, side=LEFT, padx=(0,15))
 | |
|     progswordEntry.pack(anchor=E)
 | |
| 
 | |
|     shield1Frame = Frame(itemList3)
 | |
|     shield1Label = Label(shield1Frame, text='Shield 1')
 | |
|     shield1Var = StringVar(value='0')
 | |
|     shield1Entry = Entry(shield1Frame, textvariable=shield1Var, width=3, validate='all', vcmd=vcmd)
 | |
|     shield1Frame.pack()
 | |
|     shield1Label.pack(anchor=W, side=LEFT, padx=(0,35))
 | |
|     shield1Entry.pack(anchor=E)
 | |
| 
 | |
|     shield2Frame = Frame(itemList3)
 | |
|     shield2Label = Label(shield2Frame, text='Shield 2')
 | |
|     shield2Var = StringVar(value='0')
 | |
|     shield2Entry = Entry(shield2Frame, textvariable=shield2Var, width=3, validate='all', vcmd=vcmd)
 | |
|     shield2Frame.pack()
 | |
|     shield2Label.pack(anchor=W, side=LEFT, padx=(0,35))
 | |
|     shield2Entry.pack(anchor=E)
 | |
| 
 | |
|     shield3Frame = Frame(itemList3)
 | |
|     shield3Label = Label(shield3Frame, text='Shield 3')
 | |
|     shield3Var = StringVar(value='0')
 | |
|     shield3Entry = Entry(shield3Frame, textvariable=shield3Var, width=3, validate='all', vcmd=vcmd)
 | |
|     shield3Frame.pack()
 | |
|     shield3Label.pack(anchor=W, side=LEFT, padx=(0,35))
 | |
|     shield3Entry.pack(anchor=E)
 | |
| 
 | |
|     progshieldFrame = Frame(itemList3)
 | |
|     progshieldLabel = Label(progshieldFrame, text='Prog.Shield')
 | |
|     progshieldVar = StringVar(value='3')
 | |
|     progshieldEntry = Entry(progshieldFrame, textvariable=progshieldVar, width=3, validate='all', vcmd=vcmd)
 | |
|     progshieldFrame.pack()
 | |
|     progshieldLabel.pack(anchor=W, side=LEFT, padx=(0,16))
 | |
|     progshieldEntry.pack(anchor=E)
 | |
| 
 | |
|     bluemailFrame = Frame(itemList3)
 | |
|     bluemailLabel = Label(bluemailFrame, text='Blue Mail')
 | |
|     bluemailVar = StringVar(value='0')
 | |
|     bluemailEntry = Entry(bluemailFrame, textvariable=bluemailVar, width=3, validate='all', vcmd=vcmd)
 | |
|     bluemailFrame.pack()
 | |
|     bluemailLabel.pack(anchor=W, side=LEFT, padx=(0,27))
 | |
|     bluemailEntry.pack(anchor=E)
 | |
| 
 | |
|     redmailFrame = Frame(itemList3)
 | |
|     redmailLabel = Label(redmailFrame, text='Red Mail')
 | |
|     redmailVar = StringVar(value='0')
 | |
|     redmailEntry = Entry(redmailFrame, textvariable=redmailVar, width=3, validate='all', vcmd=vcmd)
 | |
|     redmailFrame.pack()
 | |
|     redmailLabel.pack(anchor=W, side=LEFT, padx=(0,30))
 | |
|     redmailEntry.pack(anchor=E)
 | |
| 
 | |
|     progmailFrame = Frame(itemList3)
 | |
|     progmailLabel = Label(progmailFrame, text='Prog.Mail')
 | |
|     progmailVar = StringVar(value='2')
 | |
|     progmailEntry = Entry(progmailFrame, textvariable=progmailVar, width=3, validate='all', vcmd=vcmd)
 | |
|     progmailFrame.pack()
 | |
|     progmailLabel.pack(anchor=W, side=LEFT, padx=(0,25))
 | |
|     progmailEntry.pack(anchor=E)
 | |
| 
 | |
|     halfmagicFrame = Frame(itemList3)
 | |
|     halfmagicLabel = Label(halfmagicFrame, text='Half Magic')
 | |
|     halfmagicVar = StringVar(value='1')
 | |
|     halfmagicEntry = Entry(halfmagicFrame, textvariable=halfmagicVar, width=3, validate='all', vcmd=vcmd)
 | |
|     halfmagicFrame.pack()
 | |
|     halfmagicLabel.pack(anchor=W, side=LEFT, padx=(0,18))
 | |
|     halfmagicEntry.pack(anchor=E)
 | |
| 
 | |
|     quartermagicFrame = Frame(itemList3)
 | |
|     quartermagicLabel = Label(quartermagicFrame, text='Quarter Magic')
 | |
|     quartermagicVar = StringVar(value='0')
 | |
|     quartermagicEntry = Entry(quartermagicFrame, textvariable=quartermagicVar, width=3, validate='all', vcmd=vcmd)
 | |
|     quartermagicFrame.pack()
 | |
|     quartermagicLabel.pack(anchor=W, side=LEFT)
 | |
|     quartermagicEntry.pack(anchor=E)
 | |
| 
 | |
|     bcap5Frame = Frame(itemList3)
 | |
|     bcap5Label = Label(bcap5Frame, text='Bomb C.+5')
 | |
|     bcap5Var = StringVar(value='0')
 | |
|     bcap5Entry = Entry(bcap5Frame, textvariable=bcap5Var, width=3, validate='all', vcmd=vcmd)
 | |
|     bcap5Frame.pack()
 | |
|     bcap5Label.pack(anchor=W, side=LEFT, padx=(0,16))
 | |
|     bcap5Entry.pack(anchor=E)
 | |
| 
 | |
|     bcap10Frame = Frame(itemList3)
 | |
|     bcap10Label = Label(bcap10Frame, text='Bomb C.+10')
 | |
|     bcap10Var = StringVar(value='0')
 | |
|     bcap10Entry = Entry(bcap10Frame, textvariable=bcap10Var, width=3, validate='all', vcmd=vcmd)
 | |
|     bcap10Frame.pack()
 | |
|     bcap10Label.pack(anchor=W, side=LEFT, padx=(0,10))
 | |
|     bcap10Entry.pack(anchor=E)
 | |
| 
 | |
|     acap5Frame = Frame(itemList4)
 | |
|     acap5Label = Label(acap5Frame, text='Arrow C.+5')
 | |
|     acap5Var = StringVar(value='0')
 | |
|     acap5Entry = Entry(acap5Frame, textvariable=acap5Var, width=3, validate='all', vcmd=vcmd)
 | |
|     acap5Frame.pack()
 | |
|     acap5Label.pack(anchor=W, side=LEFT, padx=(0,7))
 | |
|     acap5Entry.pack(anchor=E)
 | |
| 
 | |
|     acap10Frame = Frame(itemList4)
 | |
|     acap10Label = Label(acap10Frame, text='Arrow C.+10')
 | |
|     acap10Var = StringVar(value='0')
 | |
|     acap10Entry = Entry(acap10Frame, textvariable=acap10Var, width=3, validate='all', vcmd=vcmd)
 | |
|     acap10Frame.pack()
 | |
|     acap10Label.pack(anchor=W, side=LEFT, padx=(0,1))
 | |
|     acap10Entry.pack(anchor=E)
 | |
| 
 | |
|     arrow1Frame = Frame(itemList4)
 | |
|     arrow1Label = Label(arrow1Frame, text='Arrow (1)')
 | |
|     arrow1Var = StringVar(value='1')
 | |
|     arrow1Entry = Entry(arrow1Frame, textvariable=arrow1Var, width=3, validate='all', vcmd=vcmd)
 | |
|     arrow1Frame.pack()
 | |
|     arrow1Label.pack(anchor=W, side=LEFT, padx=(0,18))
 | |
|     arrow1Entry.pack(anchor=E)
 | |
| 
 | |
|     arrow10Frame = Frame(itemList4)
 | |
|     arrow10Label = Label(arrow10Frame, text='Arrows (10)')
 | |
|     arrow10Var = StringVar(value='12')
 | |
|     arrow10Entry = Entry(arrow10Frame, textvariable=arrow10Var, width=3, validate='all', vcmd=vcmd)
 | |
|     arrow10Frame.pack()
 | |
|     arrow10Label.pack(anchor=W, side=LEFT, padx=(0,7))
 | |
|     arrow10Entry.pack(anchor=E)
 | |
| 
 | |
|     bomb1Frame = Frame(itemList4)
 | |
|     bomb1Label = Label(bomb1Frame, text='Bomb (1)')
 | |
|     bomb1Var = StringVar(value='0')
 | |
|     bomb1Entry = Entry(bomb1Frame, textvariable=bomb1Var, width=3, validate='all', vcmd=vcmd)
 | |
|     bomb1Frame.pack()
 | |
|     bomb1Label.pack(anchor=W, side=LEFT, padx=(0,18))
 | |
|     bomb1Entry.pack(anchor=E)
 | |
| 
 | |
|     bomb3Frame = Frame(itemList4)
 | |
|     bomb3Label = Label(bomb3Frame, text='Bombs (3)')
 | |
|     bomb3Var = StringVar(value='16')
 | |
|     bomb3Entry = Entry(bomb3Frame, textvariable=bomb3Var, width=3, validate='all', vcmd=vcmd)
 | |
|     bomb3Frame.pack()
 | |
|     bomb3Label.pack(anchor=W, side=LEFT, padx=(0,13))
 | |
|     bomb3Entry.pack(anchor=E)
 | |
| 
 | |
|     bomb10Frame = Frame(itemList4)
 | |
|     bomb10Label = Label(bomb10Frame, text='Bombs (10)')
 | |
|     bomb10Var = StringVar(value='1')
 | |
|     bomb10Entry = Entry(bomb10Frame, textvariable=bomb10Var, width=3, validate='all', vcmd=vcmd)
 | |
|     bomb10Frame.pack()
 | |
|     bomb10Label.pack(anchor=W, side=LEFT, padx=(0,7))
 | |
|     bomb10Entry.pack(anchor=E)
 | |
| 
 | |
|     rupee1Frame = Frame(itemList4)
 | |
|     rupee1Label = Label(rupee1Frame, text='Rupee (1)')
 | |
|     rupee1Var = StringVar(value='2')
 | |
|     rupee1Entry = Entry(rupee1Frame, textvariable=rupee1Var, width=3, validate='all', vcmd=vcmd)
 | |
|     rupee1Frame.pack()
 | |
|     rupee1Label.pack(anchor=W, side=LEFT, padx=(0,17))
 | |
|     rupee1Entry.pack(anchor=E)
 | |
| 
 | |
|     rupee5Frame = Frame(itemList4)
 | |
|     rupee5Label = Label(rupee5Frame, text='Rupees (5)')
 | |
|     rupee5Var = StringVar(value='4')
 | |
|     rupee5Entry = Entry(rupee5Frame, textvariable=rupee5Var, width=3, validate='all', vcmd=vcmd)
 | |
|     rupee5Frame.pack()
 | |
|     rupee5Label.pack(anchor=W, side=LEFT, padx=(0,12))
 | |
|     rupee5Entry.pack(anchor=E)
 | |
| 
 | |
|     rupee20Frame = Frame(itemList4)
 | |
|     rupee20Label = Label(rupee20Frame, text='Rupees (20)')
 | |
|     rupee20Var = StringVar(value='28')
 | |
|     rupee20Entry = Entry(rupee20Frame, textvariable=rupee20Var, width=3, validate='all', vcmd=vcmd)
 | |
|     rupee20Frame.pack()
 | |
|     rupee20Label.pack(anchor=W, side=LEFT, padx=(0,6))
 | |
|     rupee20Entry.pack(anchor=E)
 | |
| 
 | |
|     rupee50Frame = Frame(itemList4)
 | |
|     rupee50Label = Label(rupee50Frame, text='Rupees (50)')
 | |
|     rupee50Var = StringVar(value='7')
 | |
|     rupee50Entry = Entry(rupee50Frame, textvariable=rupee50Var, width=3, validate='all', vcmd=vcmd)
 | |
|     rupee50Frame.pack()
 | |
|     rupee50Label.pack(anchor=W, side=LEFT, padx=(0,6))
 | |
|     rupee50Entry.pack(anchor=E)
 | |
| 
 | |
|     rupee100Frame = Frame(itemList4)
 | |
|     rupee100Label = Label(rupee100Frame, text='Rupees (100)')
 | |
|     rupee100Var = StringVar(value='1')
 | |
|     rupee100Entry = Entry(rupee100Frame, textvariable=rupee100Var, width=3, validate='all', vcmd=vcmd)
 | |
|     rupee100Frame.pack()
 | |
|     rupee100Label.pack(anchor=W, side=LEFT, padx=(0,0))
 | |
|     rupee100Entry.pack(anchor=E)
 | |
| 
 | |
|     rupee300Frame = Frame(itemList4)
 | |
|     rupee300Label = Label(rupee300Frame, text='Rupees (300)')
 | |
|     rupee300Var = StringVar(value='5')
 | |
|     rupee300Entry = Entry(rupee300Frame, textvariable=rupee300Var, width=3, validate='all', vcmd=vcmd)
 | |
|     rupee300Frame.pack()
 | |
|     rupee300Label.pack(anchor=W, side=LEFT, padx=(0,0))
 | |
|     rupee300Entry.pack(anchor=E)
 | |
| 
 | |
|     blueclockFrame = Frame(itemList4)
 | |
|     blueclockLabel = Label(blueclockFrame, text='Blue Clock')
 | |
|     blueclockVar = StringVar(value='0')
 | |
|     blueclockEntry = Entry(blueclockFrame, textvariable=blueclockVar, width=3, validate='all', vcmd=vcmd)
 | |
|     blueclockFrame.pack()
 | |
|     blueclockLabel.pack(anchor=W, side=LEFT, padx=(0,11))
 | |
|     blueclockEntry.pack(anchor=E)
 | |
| 
 | |
|     greenclockFrame = Frame(itemList4)
 | |
|     greenclockLabel = Label(greenclockFrame, text='Green Clock')
 | |
|     greenclockVar = StringVar(value='0')
 | |
|     greenclockEntry = Entry(greenclockFrame, textvariable=greenclockVar, width=3, validate='all', vcmd=vcmd)
 | |
|     greenclockFrame.pack()
 | |
|     greenclockLabel.pack(anchor=W, side=LEFT, padx=(0,3))
 | |
|     greenclockEntry.pack(anchor=E)
 | |
| 
 | |
|     redclockFrame = Frame(itemList4)
 | |
|     redclockLabel = Label(redclockFrame, text='Red Clock')
 | |
|     redclockVar = StringVar(value='0')
 | |
|     redclockEntry = Entry(redclockFrame, textvariable=redclockVar, width=3, validate='all', vcmd=vcmd)
 | |
|     redclockFrame.pack()
 | |
|     redclockLabel.pack(anchor=W, side=LEFT, padx=(0,14))
 | |
|     redclockEntry.pack(anchor=E)
 | |
| 
 | |
|     silverarrowFrame = Frame(itemList5)
 | |
|     silverarrowLabel = Label(silverarrowFrame, text='Silver Arrow')
 | |
|     silverarrowVar = StringVar(value='0')
 | |
|     silverarrowEntry = Entry(silverarrowFrame, textvariable=silverarrowVar, width=3, validate='all', vcmd=vcmd)
 | |
|     silverarrowFrame.pack()
 | |
|     silverarrowLabel.pack(anchor=W, side=LEFT, padx=(0,64))
 | |
|     silverarrowEntry.pack(anchor=E)
 | |
| 
 | |
|     universalkeyFrame = Frame(itemList5)
 | |
|     universalkeyLabel = Label(universalkeyFrame, text='Universal Key')
 | |
|     universalkeyVar = StringVar(value='0')
 | |
|     universalkeyEntry = Entry(universalkeyFrame, textvariable=universalkeyVar, width=3, validate='all', vcmd=vcmd)
 | |
|     universalkeyFrame.pack()
 | |
|     universalkeyLabel.pack(anchor=W, side=LEFT, padx=(0,57))
 | |
|     universalkeyEntry.pack(anchor=E)
 | |
| 
 | |
|     triforcepieceFrame = Frame(itemList5)
 | |
|     triforcepieceLabel = Label(triforcepieceFrame, text='Triforce Piece')
 | |
|     triforcepieceVar = StringVar(value='30')
 | |
|     triforcepieceEntry = Entry(triforcepieceFrame, textvariable=triforcepieceVar, width=3, validate='all', vcmd=vcmd)
 | |
|     triforcepieceFrame.pack()
 | |
|     triforcepieceLabel.pack(anchor=W, side=LEFT, padx=(0,55))
 | |
|     triforcepieceEntry.pack(anchor=E)
 | |
| 
 | |
|     triforcecountFrame = Frame(itemList5)
 | |
|     triforcecountLabel = Label(triforcecountFrame, text='Triforce Pieces Required')
 | |
|     triforcecountVar = StringVar(value='20')
 | |
|     triforcecountEntry = Entry(triforcecountFrame, textvariable=triforcecountVar, width=3, validate='all', vcmd=vcmd)
 | |
|     triforcecountFrame.pack()
 | |
|     triforcecountLabel.pack(anchor=W, side=LEFT, padx=(0,0))
 | |
|     triforcecountEntry.pack(anchor=E)
 | |
| 
 | |
|     triforceFrame = Frame(itemList5)
 | |
|     triforceLabel = Label(triforceFrame, text='Triforce (win game)')
 | |
|     triforceVar = StringVar(value='0')
 | |
|     triforceEntry = Entry(triforceFrame, textvariable=triforceVar, width=3, validate='all', vcmd=vcmd)
 | |
|     triforceFrame.pack()
 | |
|     triforceLabel.pack(anchor=W, side=LEFT, padx=(0,23))
 | |
|     triforceEntry.pack(anchor=E)
 | |
| 
 | |
|     rupoorFrame = Frame(itemList5)
 | |
|     rupoorLabel = Label(rupoorFrame, text='Rupoor')
 | |
|     rupoorVar = StringVar(value='0')
 | |
|     rupoorEntry = Entry(rupoorFrame, textvariable=rupoorVar, width=3, validate='all', vcmd=vcmd)
 | |
|     rupoorFrame.pack()
 | |
|     rupoorLabel.pack(anchor=W, side=LEFT, padx=(0,87))
 | |
|     rupoorEntry.pack(anchor=E)
 | |
| 
 | |
|     rupoorcostFrame = Frame(itemList5)
 | |
|     rupoorcostLabel = Label(rupoorcostFrame, text='Rupoor Cost')
 | |
|     rupoorcostVar = StringVar(value='10')
 | |
|     rupoorcostEntry = Entry(rupoorcostFrame, textvariable=rupoorcostVar, width=6, validate='all', vcmd=vcmd)
 | |
|     rupoorcostFrame.pack()
 | |
|     rupoorcostLabel.pack(anchor=W, side=LEFT, padx=(0,43))
 | |
|     rupoorcostEntry.pack(anchor=E)
 | |
| 
 | |
|     itemList1.pack(side=LEFT, padx=(0,0))
 | |
|     itemList2.pack(side=LEFT, padx=(0,0))
 | |
|     itemList3.pack(side=LEFT, padx=(0,0))
 | |
|     itemList4.pack(side=LEFT, padx=(0,0))
 | |
|     itemList5.pack(side=LEFT, padx=(0,0))
 | |
|     topFrame3.pack(side=TOP, pady=(17,0))
 | |
| 
 | |
|     if args is not None:
 | |
|         for k,v in vars(args).items():
 | |
|             if type(v) is dict:
 | |
|                 setattr(args, k, v[1]) # only get values for player 1 for now
 | |
|         # load values from commandline args
 | |
|         createSpoilerVar.set(int(args.create_spoiler))
 | |
|         suppressRomVar.set(int(args.suppress_rom))
 | |
|         mapshuffleVar.set(args.mapshuffle)
 | |
|         compassshuffleVar.set(args.compassshuffle)
 | |
|         keyshuffleVar.set(args.keyshuffle)
 | |
|         bigkeyshuffleVar.set(args.bigkeyshuffle)
 | |
|         retroVar.set(args.retro)
 | |
|         quickSwapVar.set(int(args.quickswap))
 | |
|         disableMusicVar.set(int(args.disablemusic))
 | |
|         if args.count:
 | |
|             countVar.set(str(args.count))
 | |
|         if args.seed:
 | |
|             seedVar.set(str(args.seed))
 | |
|         modeVar.set(args.mode)
 | |
|         swordVar.set(args.swords)
 | |
|         difficultyVar.set(args.difficulty)
 | |
|         itemfunctionVar.set(args.item_functionality)
 | |
|         timerVar.set(args.timer)
 | |
|         progressiveVar.set(args.progressive)
 | |
|         accessibilityVar.set(args.accessibility)
 | |
|         goalVar.set(args.goal)
 | |
|         crystalsGTVar.set(args.crystals_gt)
 | |
|         crystalsGanonVar.set(args.crystals_ganon)
 | |
|         algorithmVar.set(args.algorithm)
 | |
|         shuffleVar.set(args.shuffle)
 | |
|         heartbeepVar.set(args.heartbeep)
 | |
|         fastMenuVar.set(args.fastmenu)
 | |
|         logicVar.set(args.logic)
 | |
|         romVar.set(args.rom)
 | |
|         shuffleGanonVar.set(args.shuffleganon)
 | |
|         hintsVar.set(args.hints)
 | |
|         if args.sprite is not None:
 | |
|             set_sprite(Sprite(args.sprite))
 | |
| 
 | |
|     mainWindow.mainloop()
 | |
| 
 | |
| class SpriteSelector(object):
 | |
|     def __init__(self, parent, callback, adjuster=False):
 | |
|         if is_bundled():
 | |
|             self.deploy_icons()
 | |
|         self.parent = parent
 | |
|         self.window = Toplevel(parent)
 | |
|         self.callback = callback
 | |
|         self.adjuster = adjuster
 | |
| 
 | |
|         self.window.wm_title("TAKE ANY ONE YOU WANT")
 | |
|         self.window['padx'] = 5
 | |
|         self.window['pady'] = 5
 | |
|         self.all_sprites = []
 | |
| 
 | |
|         def open_custom_sprite_dir(_evt):
 | |
|             open_file(self.custom_sprite_dir)
 | |
| 
 | |
|         alttpr_frametitle = Label(self.window, text='ALTTPR Sprites')
 | |
| 
 | |
|         custom_frametitle = Frame(self.window)
 | |
|         title_text = Label(custom_frametitle, text="Custom Sprites")
 | |
|         title_link = Label(custom_frametitle, text="(open)", fg="blue", cursor="hand2")
 | |
|         title_text.pack(side=LEFT)
 | |
|         title_link.pack(side=LEFT)
 | |
|         title_link.bind("<Button-1>", open_custom_sprite_dir)
 | |
| 
 | |
|         self.icon_section(alttpr_frametitle, self.alttpr_sprite_dir + '/*', 'ALTTPR sprites not found. Click "Update alttpr sprites" to download them.')
 | |
|         self.icon_section(custom_frametitle, self.custom_sprite_dir + '/*', 'Put sprites in the custom sprites folder (see open link above) to have them appear here.')
 | |
| 
 | |
|         frame = Frame(self.window)
 | |
|         frame.pack(side=BOTTOM, fill=X, pady=5)
 | |
| 
 | |
|         button = Button(frame, text="Browse for file...", command=self.browse_for_sprite)
 | |
|         button.pack(side=RIGHT, padx=(5, 0))
 | |
| 
 | |
|         button = Button(frame, text="Update alttpr sprites", command=self.update_alttpr_sprites)
 | |
|         button.pack(side=RIGHT, padx=(5, 0))
 | |
| 
 | |
|         button = Button(frame, text="Default Link sprite", command=self.use_default_link_sprite)
 | |
|         button.pack(side=LEFT, padx=(0, 5))
 | |
| 
 | |
|         self.randomButtonText = StringVar()
 | |
|         button = Button(frame, textvariable=self.randomButtonText, command=self.use_random_sprite)
 | |
|         button.pack(side=LEFT, padx=(0, 5))
 | |
|         self.randomButtonText.set("Random")
 | |
| 
 | |
|         self.randomOnEventText = StringVar()
 | |
|         self.randomOnHitVar = IntVar()
 | |
|         self.randomOnEnterVar = IntVar()
 | |
|         self.randomOnExitVar = IntVar()
 | |
|         self.randomOnSlashVar = IntVar()
 | |
|         self.randomOnItemVar = IntVar()
 | |
|         self.randomOnBonkVar = IntVar()
 | |
| 
 | |
|         button = Checkbutton(frame, text="Hit", command=self.update_random_button, variable=self.randomOnHitVar)
 | |
|         button.pack(side=LEFT, padx=(0, 5))
 | |
| 
 | |
|         button = Checkbutton(frame, text="Enter", command=self.update_random_button, variable=self.randomOnEnterVar)
 | |
|         button.pack(side=LEFT, padx=(0, 5))
 | |
| 
 | |
|         button = Checkbutton(frame, text="Exit", command=self.update_random_button, variable=self.randomOnExitVar)
 | |
|         button.pack(side=LEFT, padx=(0, 5))
 | |
| 
 | |
|         button = Checkbutton(frame, text="Slash", command=self.update_random_button, variable=self.randomOnSlashVar)
 | |
|         button.pack(side=LEFT, padx=(0, 5))
 | |
| 
 | |
|         button = Checkbutton(frame, text="Item", command=self.update_random_button, variable=self.randomOnItemVar)
 | |
|         button.pack(side=LEFT, padx=(0, 5))
 | |
| 
 | |
|         button = Checkbutton(frame, text="Bonk", command=self.update_random_button, variable=self.randomOnBonkVar)
 | |
|         button.pack(side=LEFT, padx=(0, 5))
 | |
| 
 | |
|         if adjuster:
 | |
|             button = Button(frame, text="Current sprite from rom", command=self.use_default_sprite)
 | |
|             button.pack(side=LEFT, padx=(0, 5))
 | |
| 
 | |
|         set_icon(self.window)
 | |
|         self.window.focus()
 | |
| 
 | |
| 
 | |
|     def icon_section(self, frame_label, path, no_results_label):
 | |
|         frame = LabelFrame(self.window, labelwidget=frame_label, padx=5, pady=5)
 | |
|         frame.pack(side=TOP, fill=X)
 | |
| 
 | |
|         sprites = []
 | |
| 
 | |
|         for file in glob(output_path(path)):
 | |
|             sprites.append(Sprite(file))
 | |
| 
 | |
|         sprites.sort(key=lambda s: str.lower(s.name or "").strip())
 | |
| 
 | |
|         frame.buttons = []
 | |
|         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 else ""))
 | |
|             button.image = image
 | |
|             frame.buttons.append(button)
 | |
| 
 | |
|         if not frame.buttons:
 | |
|             label = Label(frame, text=no_results_label)
 | |
|             label.pack()
 | |
| 
 | |
|         def update_sprites(event):
 | |
|             sprites_per_row = (event.width - 10) // 38
 | |
|             self.grid_fill_sprites(frame, sprites_per_row)
 | |
| 
 | |
|         self.grid_fill_sprites(frame, 32)
 | |
| 
 | |
|         frame.bind("<Configure>", update_sprites)
 | |
| 
 | |
|     def grid_fill_sprites(self, frame, sprites_per_row):
 | |
|         for i, button in enumerate(frame.buttons):
 | |
|             button.grid(row=i // sprites_per_row, column=i % sprites_per_row)
 | |
| 
 | |
|     def update_alttpr_sprites(self):
 | |
|         # need to wrap in try catch. We don't want errors getting the json or downloading the files to break us.
 | |
|         self.window.destroy()
 | |
|         self.parent.update()
 | |
| 
 | |
|         def work(task):
 | |
|             resultmessage = ""
 | |
|             successful = True
 | |
| 
 | |
|             def finished():
 | |
|                 task.close_window()
 | |
|                 if successful:
 | |
|                     messagebox.showinfo("Sprite Updater", resultmessage)
 | |
|                 else:
 | |
|                     messagebox.showerror("Sprite Updater", resultmessage)
 | |
|                 SpriteSelector(self.parent, self.callback, self.adjuster)
 | |
| 
 | |
|             try:
 | |
|                 task.update_status("Downloading alttpr sprites list")
 | |
|                 with urlopen('https://alttpr.com/sprites') as response:
 | |
|                     sprites_arr = json.loads(response.read().decode("utf-8"))
 | |
|             except Exception as e:
 | |
|                 resultmessage = "Error getting list of alttpr sprites. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e)
 | |
|                 successful = False
 | |
|                 task.queue_event(finished)
 | |
|                 return
 | |
| 
 | |
|             try:
 | |
|                 task.update_status("Determining needed sprites")
 | |
|                 current_sprites = [os.path.basename(file) for file in glob(self.alttpr_sprite_dir + '/*')]
 | |
|                 alttpr_sprites = [(sprite['file'], os.path.basename(urlparse(sprite['file']).path)) for sprite in sprites_arr]
 | |
|                 needed_sprites = [(sprite_url, filename) for (sprite_url, filename) in alttpr_sprites if filename not in current_sprites]
 | |
| 
 | |
|                 alttpr_filenames = [filename for (_, filename) in alttpr_sprites]
 | |
|                 obsolete_sprites = [sprite for sprite in current_sprites if sprite not in alttpr_filenames]
 | |
|             except Exception as e:
 | |
|                 resultmessage = "Error Determining which sprites to update. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e)
 | |
|                 successful = False
 | |
|                 task.queue_event(finished)
 | |
|                 return
 | |
| 
 | |
| 
 | |
|             def dl(sprite_url, filename):
 | |
|                 target = os.path.join(self.alttpr_sprite_dir, filename)
 | |
|                 with urlopen(sprite_url) as response, open(target, 'wb') as out:
 | |
|                     shutil.copyfileobj(response, out)
 | |
| 
 | |
|             def rem(sprite):
 | |
|                 os.remove(os.path.join(self.alttpr_sprite_dir, sprite))
 | |
| 
 | |
| 
 | |
|             with ThreadPoolExecutor() as pool:
 | |
|                 dl_tasks = []
 | |
|                 rem_tasks = []
 | |
| 
 | |
|                 for (sprite_url, filename) in needed_sprites:
 | |
|                     dl_tasks.append(pool.submit(dl, sprite_url, filename))
 | |
| 
 | |
|                 for sprite in obsolete_sprites:
 | |
|                     rem_tasks.append(pool.submit(rem, sprite))
 | |
| 
 | |
|                 deleted = 0
 | |
|                 updated = 0
 | |
| 
 | |
|                 for dl_task in as_completed(dl_tasks):
 | |
|                     updated += 1
 | |
|                     task.update_status("Downloading needed sprite %g/%g" % (updated, len(needed_sprites)))
 | |
|                     try:
 | |
|                         dl_task.result()
 | |
|                     except Exception as e:
 | |
|                         logging.exception(e)
 | |
|                         resultmessage = "Error downloading sprite. Not all sprites updated.\n\n%s: %s" % (
 | |
|                         type(e).__name__, e)
 | |
|                         successful = False
 | |
| 
 | |
|                 for rem_task in as_completed(rem_tasks):
 | |
|                     deleted += 1
 | |
|                     task.update_status("Removing obsolete sprite %g/%g" % (deleted, len(obsolete_sprites)))
 | |
|                     try:
 | |
|                         rem_task.result()
 | |
|                     except Exception as e:
 | |
|                         logging.exception(e)
 | |
|                         resultmessage = "Error removing obsolete sprite. Not all sprites updated.\n\n%s: %s" % (
 | |
|                         type(e).__name__, e)
 | |
|                         successful = False
 | |
| 
 | |
|             if successful:
 | |
|                 resultmessage = "alttpr sprites updated successfully"
 | |
| 
 | |
|             task.queue_event(finished)
 | |
| 
 | |
|         BackgroundTaskProgress(self.parent, work, "Updating Sprites")
 | |
| 
 | |
| 
 | |
|     def browse_for_sprite(self):
 | |
|         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:
 | |
|             self.callback(None)
 | |
|         self.window.destroy()
 | |
| 
 | |
| 
 | |
|     def use_default_sprite(self):
 | |
|         self.callback(None)
 | |
|         self.window.destroy()
 | |
| 
 | |
|     def use_default_link_sprite(self):
 | |
|         self.callback(Sprite.default_link_sprite())
 | |
|         self.window.destroy()
 | |
| 
 | |
|     def update_random_button(self):
 | |
|         randomon = "-hit" if self.randomOnHitVar.get() else ""
 | |
|         randomon += "-enter" if self.randomOnEnterVar.get() else ""
 | |
|         randomon += "-exit" if self.randomOnExitVar.get() else ""
 | |
|         randomon += "-slash" if self.randomOnSlashVar.get() else ""
 | |
|         randomon += "-item" if self.randomOnItemVar.get() else ""
 | |
|         randomon += "-bonk" if self.randomOnBonkVar.get() else ""
 | |
|         self.randomOnEventText.set(f"randomon{randomon}" if randomon else None)
 | |
|         self.randomButtonText.set("Random On Event" if randomon else "Random")
 | |
| 
 | |
|     def use_random_sprite(self):
 | |
|         randomon = self.randomOnEventText.get()
 | |
|         self.callback(randomon if randomon else (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()
 | |
| 
 | |
| 
 | |
|     def deploy_icons(self):
 | |
|         if not os.path.exists(self.custom_sprite_dir):
 | |
|             os.makedirs(self.custom_sprite_dir)
 | |
|         if not os.path.exists(self.alttpr_sprite_dir):
 | |
|             shutil.copytree(self.local_alttpr_sprite_dir, self.alttpr_sprite_dir)
 | |
| 
 | |
|     @property
 | |
|     def alttpr_sprite_dir(self):
 | |
|         if is_bundled():
 | |
|             return output_path("sprites", "alttpr")
 | |
|         return self.local_alttpr_sprite_dir
 | |
| 
 | |
|     @property
 | |
|     def local_alttpr_sprite_dir(self):
 | |
|         return local_path("data", "sprites", "alttpr")
 | |
| 
 | |
|     @property
 | |
|     def custom_sprite_dir(self):
 | |
|         if is_bundled():
 | |
|             return output_path("sprites", "custom")
 | |
|         return self.local_custom_sprite_dir
 | |
| 
 | |
|     @property
 | |
|     def local_custom_sprite_dir(self):
 | |
|         return local_path("data", "sprites", "custom")
 | |
| 
 | |
| 
 | |
| def get_image_for_sprite(sprite, gif_only: bool = False):
 | |
|     if not sprite.valid:
 | |
|         return None
 | |
|     height = 24
 | |
|     width = 16
 | |
| 
 | |
|     def draw_sprite_into_gif(add_palette_color, set_pixel_color_index):
 | |
| 
 | |
|         def drawsprite(spr, pal_as_colors, offset):
 | |
|             for y, row in enumerate(spr):
 | |
|                 for x, pal_index in enumerate(row):
 | |
|                     if pal_index:
 | |
|                         color = pal_as_colors[pal_index - 1]
 | |
|                         set_pixel_color_index(x + offset[0], y + offset[1], color)
 | |
| 
 | |
|         add_palette_color(16, (40, 40, 40))
 | |
|         shadow = [
 | |
|             [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 | |
|             [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 | |
|             [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 | |
|             [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 | |
|             [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 | |
|             [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 | |
|         ]
 | |
| 
 | |
|         drawsprite(shadow, [16], (2, 17))
 | |
| 
 | |
|         palettes = sprite.decode_palette()
 | |
|         for i in range(15):
 | |
|             add_palette_color(i + 1, palettes[0][i])
 | |
| 
 | |
|         body = sprite.decode16(0x4C0)
 | |
|         drawsprite(body, list(range(1, 16)), (0, 8))
 | |
|         head = sprite.decode16(0x40)
 | |
|         drawsprite(head, list(range(1, 16)), (0, 0))
 | |
| 
 | |
|     def make_gif(callback):
 | |
|         gif_header = b'GIF89a'
 | |
| 
 | |
|         gif_lsd = bytearray(7)
 | |
|         gif_lsd[0] = width
 | |
|         gif_lsd[2] = height
 | |
|         gif_lsd[4] = 0xF4  # 32 color palette follows.  transparant + 15 for sprite + 1 for shadow=17 which rounds up to 32 as nearest power of 2
 | |
|         gif_lsd[5] = 0  # background color is zero
 | |
|         gif_lsd[6] = 0  # aspect raio not specified
 | |
|         gif_gct = bytearray(3 * 32)
 | |
| 
 | |
|         gif_gce = bytearray(8)
 | |
|         gif_gce[0] = 0x21  # start of extention blocked
 | |
|         gif_gce[1] = 0xF9  # identifies this as the Graphics Control extension
 | |
|         gif_gce[2] = 4  # we are suppling only the 4 four bytes
 | |
|         gif_gce[3] = 0x01  # this gif includes transparency
 | |
|         gif_gce[4] = gif_gce[5] = 0  # animation frrame delay (unused)
 | |
|         gif_gce[6] = 0  # transparent color is index 0
 | |
|         gif_gce[7] = 0  # end of gif_gce
 | |
|         gif_id = bytearray(10)
 | |
|         gif_id[0] = 0x2c
 | |
|         # byte 1,2 are image left. 3,4 are image top both are left as zerosuitsamus
 | |
|         gif_id[5] = width
 | |
|         gif_id[7] = height
 | |
|         gif_id[9] = 0  # no local color table
 | |
| 
 | |
|         gif_img_minimum_code_size = bytes([7])  # we choose 7 bits, so that each pixel is represented by a byte, for conviennce.
 | |
| 
 | |
|         clear = 0x80
 | |
|         stop = 0x81
 | |
| 
 | |
|         unchunked_image_data = bytearray(height * (width + 1) + 1)
 | |
|         # we technically need a Clear code once every 125 bytes, but we do it at the start of every row for simplicity
 | |
|         for row in range(height):
 | |
|             unchunked_image_data[row * (width + 1)] = clear
 | |
|         unchunked_image_data[-1] = stop
 | |
| 
 | |
|         def add_palette_color(index, color):
 | |
|             gif_gct[3 * index] = color[0]
 | |
|             gif_gct[3 * index + 1] = color[1]
 | |
|             gif_gct[3 * index + 2] = color[2]
 | |
| 
 | |
|         def set_pixel_color_index(x, y, color):
 | |
|             unchunked_image_data[y * (width + 1) + x + 1] = color
 | |
| 
 | |
|         callback(add_palette_color, set_pixel_color_index)
 | |
| 
 | |
|         def chunk_image(img):
 | |
|             for i in range(0, len(img), 255):
 | |
|                 chunk = img[i:i + 255]
 | |
|                 yield bytes([len(chunk)])
 | |
|                 yield chunk
 | |
| 
 | |
|         gif_img = b''.join([gif_img_minimum_code_size] + list(chunk_image(unchunked_image_data)) + [b'\x00'])
 | |
| 
 | |
|         gif = b''.join([gif_header, gif_lsd, gif_gct, gif_gce, gif_id, gif_img, b'\x3b'])
 | |
| 
 | |
|         return gif
 | |
| 
 | |
|     gif_data = make_gif(draw_sprite_into_gif)
 | |
|     if gif_only:
 | |
|         return gif_data
 | |
| 
 | |
|     image = PhotoImage(data=gif_data)
 | |
| 
 | |
|     return image.zoom(2)
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     logging.basicConfig(format='%(message)s', level=logging.INFO)
 | |
|     guiMain()
 | 
