1927 lines
		
	
	
		
			82 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1927 lines
		
	
	
		
			82 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
# module is planned to be removed
 | 
						|
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
 | 
						|
import tkinter.font as font
 | 
						|
from urllib.parse import urlparse
 | 
						|
from urllib.request import urlopen
 | 
						|
from concurrent.futures import ThreadPoolExecutor, as_completed
 | 
						|
 | 
						|
import ModuleUpdate
 | 
						|
ModuleUpdate.update()
 | 
						|
 | 
						|
from worlds.alttp.EntranceRandomizer import parse_arguments
 | 
						|
from GuiUtils import ToolTips, set_icon, BackgroundTaskProgress
 | 
						|
from Main import main, get_seed, __version__ as MWVersion
 | 
						|
from worlds.alttp.Rom import Sprite
 | 
						|
from Utils import local_path, output_path, open_file
 | 
						|
 | 
						|
 | 
						|
def guiMain(args=None):
 | 
						|
    mainWindow = Tk()
 | 
						|
    mainWindow.wm_title("Archipelago %s" % MWVersion)
 | 
						|
 | 
						|
    set_icon(mainWindow)
 | 
						|
 | 
						|
    notebook = ttk.Notebook(mainWindow)
 | 
						|
    randomizerWindow = ttk.Frame(notebook)
 | 
						|
    customWindow = ttk.Frame(notebook)
 | 
						|
    notebook.add(randomizerWindow, text='Randomize')
 | 
						|
    notebook.add(customWindow, text='Custom Items')
 | 
						|
    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)
 | 
						|
    romFrame, romVar = get_rom_frame(topFrame)
 | 
						|
 | 
						|
    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)
 | 
						|
    openpyramidFrame = Frame(checkBoxFrame)
 | 
						|
    openpyramidVar = StringVar()
 | 
						|
    openpyramidVar.set('auto')
 | 
						|
    openpyramidOptionMenu = OptionMenu(openpyramidFrame, openpyramidVar, 'auto', 'goal', 'yes', 'no')
 | 
						|
    openpyramidLabel = Label(openpyramidFrame, text='Pre-open Pyramid Hole')
 | 
						|
    openpyramidLabel.pack(side=LEFT)
 | 
						|
    openpyramidOptionMenu.pack(side=LEFT)
 | 
						|
    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)
 | 
						|
 | 
						|
    tileShuffleVar = IntVar()
 | 
						|
    tileShuffleButton = Checkbutton(checkBoxFrame, text="Tile shuffle", variable=tileShuffleVar)
 | 
						|
 | 
						|
    createSpoilerCheckbutton.pack(expand=True, anchor=W)
 | 
						|
    suppressRomCheckbutton.pack(expand=True, anchor=W)
 | 
						|
    openpyramidFrame.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)
 | 
						|
    tileShuffleButton.pack(expand=True, anchor=W)
 | 
						|
 | 
						|
    checkBoxFrame.pack(side=TOP, anchor=W, padx=5, pady=10)
 | 
						|
 | 
						|
    romOptionsFrame, rom_vars, set_sprite = get_rom_options_frame(rightHalfFrame)
 | 
						|
    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', 'bosses', '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)
 | 
						|
 | 
						|
    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', "same simple", "same restricted", "same full",
 | 
						|
                                   "same crossed", "same insanity", "same dungeonsfull", "same 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)
 | 
						|
    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)
 | 
						|
 | 
						|
    bushShuffleVar = IntVar()
 | 
						|
    bushShuffleButton = Checkbutton(enemizerFrame, text="Bush shuffle", variable=bushShuffleVar)
 | 
						|
    bushShuffleButton.grid(row=2, column=1, sticky=W)
 | 
						|
 | 
						|
    killableThievesVar = IntVar()
 | 
						|
    killable_thievesShuffleButton = Checkbutton(enemizerFrame, text="Killable Thieves", variable=killableThievesVar)
 | 
						|
    killable_thievesShuffleButton.grid(row=2, column=2, 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)
 | 
						|
 | 
						|
    shopInventoryShuffleVar = IntVar()
 | 
						|
    shopInventoryShuffleButton = Checkbutton(shopframe, text="New Inventories", variable=shopInventoryShuffleVar)
 | 
						|
    shopInventoryShuffleButton.grid(row=1, column=0, sticky=W)
 | 
						|
 | 
						|
    shopPoolShuffleVar = IntVar()
 | 
						|
    shopPoolShuffleButton = Checkbutton(shopframe, text="Itempool in Shops", variable=shopPoolShuffleVar)
 | 
						|
    shopPoolShuffleButton.grid(row=1, column=1, sticky=W)
 | 
						|
 | 
						|
    shopWitchShuffleVar = IntVar()
 | 
						|
    shopWitchShuffleButton = Checkbutton(shopframe, text="Custom Potion Shop", variable=shopWitchShuffleVar)
 | 
						|
    shopWitchShuffleButton.grid(row=1, column=2, sticky=W)
 | 
						|
 | 
						|
    multiworldframe = LabelFrame(randomizerWindow, text="Multiworld", padx=5, pady=2)
 | 
						|
 | 
						|
    worldLabel = Label(multiworldframe, text='Players per Team')
 | 
						|
    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='Amount of Multiworlds')
 | 
						|
    countVar = StringVar()
 | 
						|
    countSpinbox = Spinbox(multiworldframe, from_=1, to=100, width=5, textvariable=countVar)
 | 
						|
 | 
						|
    balancingVar = IntVar()
 | 
						|
    balancingVar.set(1)  # set default
 | 
						|
    balancingCheckbutton = Checkbutton(multiworldframe, text="Progression Balancing", variable=balancingVar)
 | 
						|
    patchesVar = IntVar()
 | 
						|
    patchesVar.set(1)  # set default
 | 
						|
    patchesCheckbutton = Checkbutton(multiworldframe, text="Create Delta Patches", variable=patchesVar)
 | 
						|
 | 
						|
    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.countdown_start_time = timerCountdownVar.get()
 | 
						|
        guiargs.red_clock_time = timerRedVar.get()
 | 
						|
        guiargs.blue_clock_time = timerBlueVar.get()
 | 
						|
        guiargs.green_clock_time = timerGreenVar.get()
 | 
						|
        guiargs.progression_balancing = 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()
 | 
						|
        if "same " in guiargs.shuffle:
 | 
						|
            guiargs.shuffle = guiargs.shuffle[5:] + "-" + str(seedVar.get() if seedVar.get() else
 | 
						|
                                                              random.randint(0, 2**64))
 | 
						|
        guiargs.heartbeep = rom_vars.heartbeepVar.get()
 | 
						|
        guiargs.heartcolor = rom_vars.heartcolorVar.get()
 | 
						|
        guiargs.fastmenu = rom_vars.fastMenuVar.get()
 | 
						|
        guiargs.create_spoiler = bool(createSpoilerVar.get())
 | 
						|
        guiargs.skip_playthrough = not bool(createSpoilerVar.get())
 | 
						|
        guiargs.open_pyramid = 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(rom_vars.quickSwapVar.get())
 | 
						|
        guiargs.disablemusic = bool(rom_vars.disableMusicVar.get())
 | 
						|
        guiargs.reduceflashing = bool(rom_vars.disableFlashingVar.get())
 | 
						|
        guiargs.ow_palettes = rom_vars.owPalettesVar.get()
 | 
						|
        guiargs.uw_palettes = rom_vars.uwPalettesVar.get()
 | 
						|
        guiargs.hud_palettes = rom_vars.hudPalettesVar.get()
 | 
						|
        guiargs.sword_palettes = rom_vars.swordPalettesVar.get()
 | 
						|
        guiargs.shield_palettes = rom_vars.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"
 | 
						|
        if shopInventoryShuffleVar.get():
 | 
						|
            guiargs.shop_shuffle += "f"
 | 
						|
        if shopWitchShuffleVar.get():
 | 
						|
            guiargs.shop_shuffle += "w"
 | 
						|
        if shopPoolShuffleVar.get():
 | 
						|
            guiargs.shop_shuffle_slots = 30
 | 
						|
        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 = rom_vars.sprite
 | 
						|
        if rom_vars.sprite_pool:
 | 
						|
            guiargs.sprite_pool = rom_vars.sprite_pool
 | 
						|
            messagebox.showinfo(title="Sprite Pool", message=", ".join(guiargs.sprite_pool))
 | 
						|
        # 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 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 Multiworld', command=generateRom)
 | 
						|
 | 
						|
    worldLabel.grid(row=0, column=0, sticky=W)
 | 
						|
    worldSpinbox.grid(row=0, column=1, sticky=W)
 | 
						|
    namesLabel.grid(row=0, column=2, sticky=W)
 | 
						|
    namesEntry.grid(row=0, column=3, sticky=W + E)
 | 
						|
    multiworldframe.grid_columnconfigure(3, weight=1)  # stretch name field
 | 
						|
    seedLabel.grid(row=0, column=4, sticky=W)
 | 
						|
    seedEntry.grid(row=0, column=5, sticky=W)
 | 
						|
    countLabel.grid(row=1, column=0, sticky=W)
 | 
						|
    countSpinbox.grid(row=1, column=1, sticky=W)
 | 
						|
    balancingCheckbutton.grid(row=1, column=2, sticky=W, columnspan=2)
 | 
						|
    patchesCheckbutton.grid(row=1, column=4, sticky=W, columnspan=2)
 | 
						|
 | 
						|
    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)
 | 
						|
 | 
						|
    # Custom Controls
 | 
						|
 | 
						|
    topFrame3 = Frame(customWindow)
 | 
						|
 | 
						|
    def validation(P):
 | 
						|
        if str.isdigit(P) or P == "":
 | 
						|
            return True
 | 
						|
        else:
 | 
						|
            return False
 | 
						|
    vcmd=(topFrame3.register(validation), '%P')
 | 
						|
 | 
						|
    timerOptionsFrame = LabelFrame(topFrame3, text="Timer options")
 | 
						|
    for i in range(3):
 | 
						|
        timerOptionsFrame.columnconfigure(i, weight=1)
 | 
						|
        timerOptionsFrame.rowconfigure(i, weight=1)
 | 
						|
 | 
						|
    timerModeFrame = Frame(timerOptionsFrame)
 | 
						|
    timerModeFrame.grid(row=0, column=0, columnspan=3, sticky=E, padx=3)
 | 
						|
    timerVar = StringVar()
 | 
						|
    timerVar.set('none')
 | 
						|
    timerModeMenu = OptionMenu(timerModeFrame, timerVar, 'none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown')
 | 
						|
    timerLabel = Label(timerModeFrame, text='Timer setting')
 | 
						|
    timerLabel.pack(side=LEFT)
 | 
						|
    timerModeMenu.pack(side=LEFT)
 | 
						|
 | 
						|
    timerCountdownFrame = Frame(timerOptionsFrame)
 | 
						|
    timerCountdownFrame.grid(row=1, column=0, columnspan=3, sticky=E, padx=3)
 | 
						|
    timerCountdownLabel = Label(timerCountdownFrame, text='Countdown starting time')
 | 
						|
    timerCountdownLabel.pack(side=LEFT)
 | 
						|
    timerCountdownVar = IntVar(value=10)
 | 
						|
    timerCountdownSpinbox = Spinbox(timerCountdownFrame, from_=0, to=480, width=3, textvariable=timerCountdownVar)
 | 
						|
    timerCountdownSpinbox.pack(side=LEFT)
 | 
						|
 | 
						|
    timerRedFrame = Frame(timerOptionsFrame)
 | 
						|
    timerRedFrame.grid(row=2, column=0, sticky=E, padx=3)
 | 
						|
    timerRedLabel = Label(timerRedFrame, text='Clock adjustments: Red')
 | 
						|
    timerRedLabel.pack(side=LEFT)
 | 
						|
    timerRedVar = IntVar(value=-2)
 | 
						|
    timerRedSpinbox = Spinbox(timerRedFrame, from_=-60, to=60, width=3, textvariable=timerRedVar)
 | 
						|
    timerRedSpinbox.pack(side=LEFT)
 | 
						|
 | 
						|
    timerBlueFrame = Frame(timerOptionsFrame)
 | 
						|
    timerBlueFrame.grid(row=2, column=1, sticky=E, padx=3)
 | 
						|
    timerBlueLabel = Label(timerBlueFrame, text='Blue')
 | 
						|
    timerBlueLabel.pack(side=LEFT)
 | 
						|
    timerBlueVar = IntVar(value=2)
 | 
						|
    timerBlueSpinbox = Spinbox(timerBlueFrame, from_=-60, to=60, width=3, textvariable=timerBlueVar)
 | 
						|
    timerBlueSpinbox.pack(side=LEFT)
 | 
						|
 | 
						|
    timerGreenFrame = Frame(timerOptionsFrame)
 | 
						|
    timerGreenFrame.grid(row=2, column=2, sticky=E, padx=3)
 | 
						|
    timerGreenLabel = Label(timerGreenFrame, text='Green')
 | 
						|
    timerGreenLabel.pack(side=LEFT)
 | 
						|
    timerGreenVar = IntVar(value=4)
 | 
						|
    timerGreenSpinbox = Spinbox(timerGreenFrame, from_=-60, to=60, width=3, textvariable=timerGreenVar)
 | 
						|
    timerGreenSpinbox.pack(side=LEFT)
 | 
						|
 | 
						|
    timerOptionsFrame.pack(expand=True, fill=BOTH, padx=3)
 | 
						|
 | 
						|
 | 
						|
    itemList1 = Frame(topFrame3)
 | 
						|
    itemList2 = Frame(topFrame3)
 | 
						|
    itemList3 = Frame(topFrame3)
 | 
						|
    itemList4 = Frame(topFrame3)
 | 
						|
    itemList5 = Frame(topFrame3)
 | 
						|
 | 
						|
    customVar = IntVar()
 | 
						|
    customCheckbutton = Checkbutton(topFrame3, text="Use custom item pool", variable=customVar)
 | 
						|
    customCheckbutton.pack(expand=True, anchor=W)
 | 
						|
 | 
						|
    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))
 | 
						|
        mapshuffleVar.set(args.mapshuffle)
 | 
						|
        compassshuffleVar.set(args.compassshuffle)
 | 
						|
        keyshuffleVar.set(args.keyshuffle)
 | 
						|
        bigkeyshuffleVar.set(args.bigkeyshuffle)
 | 
						|
        retroVar.set(args.retro)
 | 
						|
        rom_vars.quickSwapVar.set(int(args.quickswap))
 | 
						|
        rom_vars.disableMusicVar.set(int(args.disablemusic))
 | 
						|
        rom_vars.disableFlashingVar.set(int(args.reduceflashing))
 | 
						|
        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)
 | 
						|
        timerCountdownVar.set(args.countdown_start_time)
 | 
						|
        timerRedVar.set(args.red_clock_time)
 | 
						|
        timerBlueVar.set(args.blue_clock_time)
 | 
						|
        timerGreenVar.set(args.green_clock_time)
 | 
						|
        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)
 | 
						|
        rom_vars.heartbeepVar.set(args.heartbeep)
 | 
						|
        rom_vars.fastMenuVar.set(args.fastmenu)
 | 
						|
        logicVar.set(args.logic)
 | 
						|
        rom_vars.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()
 | 
						|
 | 
						|
def get_rom_frame(parent=None):
 | 
						|
    romFrame = Frame(parent)
 | 
						|
    baseRomLabel = Label(romFrame, text='LttP Base Rom: ')
 | 
						|
    romVar = StringVar(value="Zelda no Densetsu - Kamigami no Triforce (Japan).sfc")
 | 
						|
    romEntry = Entry(romFrame, 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(romFrame, text='Select Rom', command=RomSelect)
 | 
						|
 | 
						|
    baseRomLabel.pack(side=LEFT)
 | 
						|
    romEntry.pack(side=LEFT, expand=True, fill=X)
 | 
						|
    romSelectButton.pack(side=LEFT)
 | 
						|
    romFrame.pack(side=TOP, expand=True, fill=X)
 | 
						|
 | 
						|
    return romFrame, romVar
 | 
						|
 | 
						|
 | 
						|
def get_rom_options_frame(parent=None):
 | 
						|
    romOptionsFrame = LabelFrame(parent, text="Rom options")
 | 
						|
    romOptionsFrame.columnconfigure(0, weight=1)
 | 
						|
    romOptionsFrame.columnconfigure(1, weight=1)
 | 
						|
    for i in range(5):
 | 
						|
        romOptionsFrame.rowconfigure(i, weight=1)
 | 
						|
    vars = Namespace()
 | 
						|
 | 
						|
    vars.disableMusicVar = IntVar()
 | 
						|
    disableMusicCheckbutton = Checkbutton(romOptionsFrame, text="Disable music", variable=vars.disableMusicVar)
 | 
						|
    disableMusicCheckbutton.grid(row=0, column=0, sticky=E)
 | 
						|
 | 
						|
    vars.disableFlashingVar = IntVar(value=1)
 | 
						|
    disableFlashingCheckbutton = Checkbutton(romOptionsFrame, text="Disable flashing (anti-epilepsy)", variable=vars.disableFlashingVar)
 | 
						|
    disableFlashingCheckbutton.grid(row=6, column=0, sticky=E)
 | 
						|
 | 
						|
    spriteDialogFrame = Frame(romOptionsFrame)
 | 
						|
    spriteDialogFrame.grid(row=0, column=1)
 | 
						|
    baseSpriteLabel = Label(spriteDialogFrame, text='Sprite:')
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    vars.spriteNameVar = StringVar()
 | 
						|
    vars.sprite = None
 | 
						|
    def set_sprite(sprite_param):
 | 
						|
        nonlocal vars
 | 
						|
        if isinstance(sprite_param, str):
 | 
						|
            vars.sprite = sprite_param
 | 
						|
            vars.spriteNameVar.set(sprite_param)
 | 
						|
        elif sprite_param is None or not sprite_param.valid:
 | 
						|
            vars.sprite = None
 | 
						|
            vars.spriteNameVar.set('(unchanged)')
 | 
						|
        else:
 | 
						|
            vars.sprite = sprite_param
 | 
						|
            vars.spriteNameVar.set(vars.sprite.name)
 | 
						|
 | 
						|
    set_sprite(None)
 | 
						|
    vars.spriteNameVar.set('(unchanged)')
 | 
						|
    spriteEntry = Label(spriteDialogFrame, textvariable=vars.spriteNameVar)
 | 
						|
 | 
						|
    def SpriteSelect():
 | 
						|
        nonlocal vars
 | 
						|
        SpriteSelector(parent, set_sprite, spritePool=vars.sprite_pool)
 | 
						|
 | 
						|
    spriteSelectButton = Button(spriteDialogFrame, text='...', command=SpriteSelect)
 | 
						|
 | 
						|
    baseSpriteLabel.pack(side=LEFT)
 | 
						|
    spriteEntry.pack(side=LEFT)
 | 
						|
    spriteSelectButton.pack(side=LEFT)
 | 
						|
 | 
						|
    vars.quickSwapVar = IntVar(value=1)
 | 
						|
    quickSwapCheckbutton = Checkbutton(romOptionsFrame, text="L/R Quickswapping", variable=vars.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)
 | 
						|
    vars.fastMenuVar = StringVar()
 | 
						|
    vars.fastMenuVar.set('normal')
 | 
						|
    fastMenuOptionMenu = OptionMenu(fastMenuFrame, vars.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)
 | 
						|
    vars.heartcolorVar = StringVar()
 | 
						|
    vars.heartcolorVar.set('red')
 | 
						|
    heartcolorOptionMenu = OptionMenu(heartcolorFrame, vars.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)
 | 
						|
    vars.heartbeepVar = StringVar()
 | 
						|
    vars.heartbeepVar.set('normal')
 | 
						|
    heartbeepOptionMenu = OptionMenu(heartbeepFrame, vars.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)
 | 
						|
    vars.owPalettesVar = StringVar()
 | 
						|
    vars.owPalettesVar.set('default')
 | 
						|
    owPalettesOptionMenu = OptionMenu(owPalettesFrame, vars.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)
 | 
						|
    vars.uwPalettesVar = StringVar()
 | 
						|
    vars.uwPalettesVar.set('default')
 | 
						|
    uwPalettesOptionMenu = OptionMenu(uwPalettesFrame, vars.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)
 | 
						|
    vars.hudPalettesVar = StringVar()
 | 
						|
    vars.hudPalettesVar.set('default')
 | 
						|
    hudPalettesOptionMenu = OptionMenu(hudPalettesFrame, vars.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)
 | 
						|
    vars.swordPalettesVar = StringVar()
 | 
						|
    vars.swordPalettesVar.set('default')
 | 
						|
    swordPalettesOptionMenu = OptionMenu(swordPalettesFrame, vars.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)
 | 
						|
    vars.shieldPalettesVar = StringVar()
 | 
						|
    vars.shieldPalettesVar.set('default')
 | 
						|
    shieldPalettesOptionMenu = OptionMenu(shieldPalettesFrame, vars.shieldPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
 | 
						|
    shieldPalettesOptionMenu.pack(side=LEFT)
 | 
						|
 | 
						|
    spritePoolFrame = Frame(romOptionsFrame)
 | 
						|
    spritePoolFrame.grid(row=5, column=1)
 | 
						|
    baseSpritePoolLabel = Label(spritePoolFrame, text='Sprite Pool:')
 | 
						|
 | 
						|
    vars.spritePoolCountVar = StringVar()
 | 
						|
    vars.sprite_pool = []
 | 
						|
    def set_sprite_pool(sprite_param):
 | 
						|
        nonlocal vars
 | 
						|
        operation = "add"
 | 
						|
        if isinstance(sprite_param, tuple):
 | 
						|
            operation, sprite_param = sprite_param
 | 
						|
        if isinstance(sprite_param, Sprite) and sprite_param.valid:
 | 
						|
            sprite_param = sprite_param.name
 | 
						|
        if isinstance(sprite_param, str):
 | 
						|
            if operation == "add":
 | 
						|
                vars.sprite_pool.append(sprite_param)
 | 
						|
            elif operation == "remove":
 | 
						|
                vars.sprite_pool.remove(sprite_param)
 | 
						|
            elif operation == "clear":
 | 
						|
                vars.sprite_pool.clear()
 | 
						|
        vars.spritePoolCountVar.set(str(len(vars.sprite_pool)))
 | 
						|
 | 
						|
    set_sprite_pool(None)
 | 
						|
    vars.spritePoolCountVar.set('0')
 | 
						|
    spritePoolEntry = Label(spritePoolFrame, textvariable=vars.spritePoolCountVar)
 | 
						|
 | 
						|
    def SpritePoolSelect():
 | 
						|
        nonlocal vars
 | 
						|
        SpriteSelector(parent, set_sprite_pool, randomOnEvent=False, spritePool=vars.sprite_pool)
 | 
						|
 | 
						|
    def SpritePoolClear():
 | 
						|
        nonlocal vars
 | 
						|
        vars.sprite_pool.clear()
 | 
						|
        vars.spritePoolCountVar.set('0')
 | 
						|
 | 
						|
    spritePoolSelectButton = Button(spritePoolFrame, text='...', command=SpritePoolSelect)
 | 
						|
    spritePoolClearButton = Button(spritePoolFrame, text='Clear', command=SpritePoolClear)
 | 
						|
 | 
						|
    baseSpritePoolLabel.pack(side=LEFT)
 | 
						|
    spritePoolEntry.pack(side=LEFT)
 | 
						|
    spritePoolSelectButton.pack(side=LEFT)
 | 
						|
    spritePoolClearButton.pack(side=LEFT)
 | 
						|
 | 
						|
    return romOptionsFrame, vars, set_sprite
 | 
						|
 | 
						|
 | 
						|
class SpriteSelector():
 | 
						|
    def __init__(self, parent, callback, adjuster=False, randomOnEvent=True, spritePool=None):
 | 
						|
        self.deploy_icons()
 | 
						|
        self.parent = parent
 | 
						|
        self.window = Toplevel(parent)
 | 
						|
        self.callback = callback
 | 
						|
        self.adjuster = adjuster
 | 
						|
        self.randomOnEvent = randomOnEvent
 | 
						|
        self.spritePoolButtons = None
 | 
						|
 | 
						|
        self.window.wm_title("TAKE ANY ONE YOU WANT")
 | 
						|
        self.window['padx'] = 5
 | 
						|
        self.window['pady'] = 5
 | 
						|
        self.spritesPerRow = 32
 | 
						|
        self.all_sprites = []
 | 
						|
        self.sprite_pool = spritePool
 | 
						|
 | 
						|
        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.')
 | 
						|
        if not randomOnEvent:
 | 
						|
            self.sprite_pool_section(spritePool)
 | 
						|
 | 
						|
        frame = Frame(self.window)
 | 
						|
        frame.pack(side=BOTTOM, fill=X, pady=5)
 | 
						|
 | 
						|
        if self.randomOnEvent:
 | 
						|
            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()
 | 
						|
        self.randomOnRandomVar = IntVar()
 | 
						|
 | 
						|
        if self.randomOnEvent:
 | 
						|
            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))
 | 
						|
 | 
						|
            button = Checkbutton(frame, text="Random", command=self.update_random_button, variable=self.randomOnRandomVar)
 | 
						|
            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 remove_from_sprite_pool(self, button, spritename):
 | 
						|
        self.callback(("remove", spritename))
 | 
						|
        self.spritePoolButtons.buttons.remove(button)
 | 
						|
        button.destroy()
 | 
						|
 | 
						|
    def add_to_sprite_pool(self, spritename):
 | 
						|
        if isinstance(spritename, str):
 | 
						|
            if spritename == "random":
 | 
						|
                button = Button(self.spritePoolButtons, text="?")
 | 
						|
                button['font'] = font.Font(size=19)
 | 
						|
                button.configure(command=lambda spr="random": self.remove_from_sprite_pool(button, spr))
 | 
						|
                ToolTips.register(button, "Random")
 | 
						|
                self.spritePoolButtons.buttons.append(button)
 | 
						|
            else:
 | 
						|
                spritename = Sprite.get_sprite_from_name(spritename)
 | 
						|
        if isinstance(spritename, Sprite) and spritename.valid:
 | 
						|
            image = get_image_for_sprite(spritename)
 | 
						|
            if image is None:
 | 
						|
                return
 | 
						|
            button = Button(self.spritePoolButtons, image=image)
 | 
						|
            button.configure(command=lambda spr=spritename: self.remove_from_sprite_pool(button, spr.name))
 | 
						|
            ToolTips.register(button, spritename.name +
 | 
						|
                              f"\nBy: {spritename.author_name if spritename.author_name else ''}")
 | 
						|
            button.image = image
 | 
						|
 | 
						|
            self.spritePoolButtons.buttons.append(button)
 | 
						|
        self.grid_fill_sprites(self.spritePoolButtons)
 | 
						|
 | 
						|
    def sprite_pool_section(self, spritePool):
 | 
						|
        def clear_sprite_pool(_evt):
 | 
						|
            self.callback(("clear", "Clear"))
 | 
						|
            for button in self.spritePoolButtons.buttons:
 | 
						|
                button.destroy()
 | 
						|
            self.spritePoolButtons.buttons.clear()
 | 
						|
 | 
						|
        frametitle = Frame(self.window)
 | 
						|
        title_text = Label(frametitle, text="Sprite Pool")
 | 
						|
        title_link = Label(frametitle, text="(clear)", fg="blue", cursor="hand2")
 | 
						|
        title_text.pack(side=LEFT)
 | 
						|
        title_link.pack(side=LEFT)
 | 
						|
        title_link.bind("<Button-1>", clear_sprite_pool)
 | 
						|
 | 
						|
        self.spritePoolButtons = LabelFrame(self.window, labelwidget=frametitle, padx=5, pady=5)
 | 
						|
        self.spritePoolButtons.pack(side=TOP, fill=X)
 | 
						|
        self.spritePoolButtons.buttons = []
 | 
						|
 | 
						|
        def update_sprites(event):
 | 
						|
            self.spritesPerRow = (event.width - 10) // 38
 | 
						|
            self.grid_fill_sprites(self.spritePoolButtons)
 | 
						|
 | 
						|
        self.grid_fill_sprites(self.spritePoolButtons)
 | 
						|
        self.spritePoolButtons.bind("<Configure>", update_sprites)
 | 
						|
 | 
						|
        if spritePool:
 | 
						|
            for sprite in spritePool:
 | 
						|
                self.add_to_sprite_pool(sprite)
 | 
						|
 | 
						|
    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 os.listdir(path):
 | 
						|
            sprites.append((file, Sprite(os.path.join(path, file))))
 | 
						|
 | 
						|
        sprites.sort(key=lambda s: str.lower(s[1].name or "").strip())
 | 
						|
 | 
						|
        frame.buttons = []
 | 
						|
        for file, 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 "") +
 | 
						|
                              f"\nFrom: {file}")
 | 
						|
            button.image = image
 | 
						|
            frame.buttons.append(button)
 | 
						|
 | 
						|
        if not frame.buttons:
 | 
						|
            label = Label(frame, text=no_results_label)
 | 
						|
            label.pack()
 | 
						|
 | 
						|
        def update_sprites(event):
 | 
						|
            self.spritesPerRow = (event.width - 10) // 38
 | 
						|
            self.grid_fill_sprites(frame)
 | 
						|
 | 
						|
        self.grid_fill_sprites(frame)
 | 
						|
 | 
						|
        frame.bind("<Configure>", update_sprites)
 | 
						|
 | 
						|
    def grid_fill_sprites(self, frame):
 | 
						|
        for i, button in enumerate(frame.buttons):
 | 
						|
            button.grid(row=i // self.spritesPerRow, column=i % self.spritesPerRow)
 | 
						|
 | 
						|
    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 on_finish(successful, resultmessage):
 | 
						|
            if successful:
 | 
						|
                messagebox.showinfo("Sprite Updater", resultmessage)
 | 
						|
            else:
 | 
						|
                logging.error(resultmessage)
 | 
						|
                messagebox.showerror("Sprite Updater", resultmessage)
 | 
						|
            SpriteSelector(self.parent, self.callback, self.adjuster)
 | 
						|
 | 
						|
        BackgroundTaskProgress(self.parent, update_sprites, "Updating Sprites", on_finish)
 | 
						|
 | 
						|
 | 
						|
    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):
 | 
						|
        if self.randomOnEvent:
 | 
						|
            self.callback(Sprite.default_link_sprite())
 | 
						|
            self.window.destroy()
 | 
						|
        else:
 | 
						|
            self.callback("link")
 | 
						|
            self.add_to_sprite_pool("link")
 | 
						|
 | 
						|
    def update_random_button(self):
 | 
						|
        if self.randomOnRandomVar.get():
 | 
						|
            randomon = "random"
 | 
						|
        else:
 | 
						|
            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):
 | 
						|
        if not self.randomOnEvent:
 | 
						|
            self.callback("random")
 | 
						|
            self.add_to_sprite_pool("random")
 | 
						|
            return
 | 
						|
        elif self.randomOnEventText.get():
 | 
						|
            self.callback(self.randomOnEventText.get())
 | 
						|
        elif self.sprite_pool:
 | 
						|
            self.callback(random.choice(self.sprite_pool))
 | 
						|
        elif self.all_sprites:
 | 
						|
            self.callback(random.choice(self.all_sprites))
 | 
						|
        else:
 | 
						|
            self.callback(None)
 | 
						|
        self.window.destroy()
 | 
						|
 | 
						|
    def select_sprite(self, spritename):
 | 
						|
        self.callback(spritename)
 | 
						|
        if self.randomOnEvent:
 | 
						|
            self.window.destroy()
 | 
						|
        else:
 | 
						|
            self.add_to_sprite_pool(spritename)
 | 
						|
 | 
						|
    def deploy_icons(self):
 | 
						|
        if not os.path.exists(self.custom_sprite_dir):
 | 
						|
            os.makedirs(self.custom_sprite_dir)
 | 
						|
 | 
						|
    @property
 | 
						|
    def alttpr_sprite_dir(self):
 | 
						|
        return local_path("data", "sprites", "alttpr")
 | 
						|
 | 
						|
    @property
 | 
						|
    def custom_sprite_dir(self):
 | 
						|
        return local_path("data", "sprites", "custom")
 | 
						|
 | 
						|
 | 
						|
def update_sprites(task, on_finish=None):
 | 
						|
    resultmessage = ""
 | 
						|
    successful = True
 | 
						|
    sprite_dir = local_path("data", "sprites", "alttpr")
 | 
						|
    os.makedirs(sprite_dir, exist_ok=True)
 | 
						|
 | 
						|
    def finished():
 | 
						|
        task.close_window()
 | 
						|
        if on_finish:
 | 
						|
            on_finish(successful, resultmessage)
 | 
						|
 | 
						|
    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(sprite_dir + '/*')]
 | 
						|
        alttpr_sprites = [(sprite['file'], os.path.basename(urlparse(sprite['file']).path))
 | 
						|
                          for sprite in sprites_arr if sprite["author"] != "Nintendo"]
 | 
						|
        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(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(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)
 | 
						|
 | 
						|
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__':
 | 
						|
    import sys
 | 
						|
    if "update_sprites" in sys.argv:
 | 
						|
        import threading
 | 
						|
        done = threading.Event()
 | 
						|
        top = Tk()
 | 
						|
        top.withdraw()
 | 
						|
        BackgroundTaskProgress(top, update_sprites, "Updating Sprites", lambda succesful, resultmessage: done.set())
 | 
						|
        while not done.isSet():
 | 
						|
            top.update()
 | 
						|
        print("Done updating sprites")
 | 
						|
    else:
 | 
						|
        logging.basicConfig(level=logging.INFO)
 | 
						|
        guiMain()
 |