diff --git a/BaseClasses.py b/BaseClasses.py index 9da00855..71760838 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -6,7 +6,7 @@ from collections import OrderedDict class World(object): - def __init__(self, shuffle, logic, mode, difficulty, timer, progressive, goal, algorithm, place_dungeon_items, check_beatable_only, shuffle_ganon, quickswap, fastmenu, disable_music, keysanity): + def __init__(self, shuffle, logic, mode, difficulty, timer, progressive, goal, algorithm, place_dungeon_items, check_beatable_only, shuffle_ganon, quickswap, fastmenu, disable_music, keysanity, custom, customitemarray): self.shuffle = shuffle self.logic = logic self.mode = mode @@ -37,6 +37,7 @@ class World(object): self.treasure_hunt_count = 0 self.treasure_hunt_icon = 'Triforce Piece' self.clock_mode = 'off' + self.rupoor_cost = 10 self.aga_randomness = True self.lock_aga_door_in_escape = False self.fix_trock_doors = self.shuffle != 'vanilla' @@ -52,6 +53,8 @@ class World(object): self.fastmenu = fastmenu self.disable_music = disable_music self.keysanity = keysanity + self.custom = custom + self.customitemarray = customitemarray self.can_take_damage = True self.difficulty_requirements = None self.spoiler = Spoiler(self) diff --git a/EntranceRandomizer.py b/EntranceRandomizer.py index 818913c0..91b3a633 100755 --- a/EntranceRandomizer.py +++ b/EntranceRandomizer.py @@ -163,6 +163,8 @@ def start(): Keys (and other dungeon items) are no longer restricted to their dungeons, but can be anywhere ''', action='store_true') + parser.add_argument('--custom', default=False, help='Not supported.') + parser.add_argument('--customitemarray', default=False, help='Not supported.') parser.add_argument('--nodungeonitems', help='''\ Remove Maps and Compasses from Itempool, replacing them by empty slots. diff --git a/Gui.py b/Gui.py index 5f1e1c0d..c04ba514 100755 --- a/Gui.py +++ b/Gui.py @@ -25,8 +25,10 @@ def guiMain(args=None): notebook = ttk.Notebook(mainWindow) randomizerWindow = ttk.Frame(notebook) adjustWindow = ttk.Frame(notebook) + customWindow = ttk.Frame(notebook) notebook.add(randomizerWindow, text='Randomize') notebook.add(adjustWindow, text='Adjust') + notebook.add(customWindow, text='Custom') notebook.pack() # Shared Controls @@ -68,6 +70,8 @@ def guiMain(args=None): disableMusicCheckbutton = Checkbutton(checkBoxFrame, text="Disable game music", variable=disableMusicVar) shuffleGanonVar = IntVar() shuffleGanonCheckbutton = Checkbutton(checkBoxFrame, text="Include Ganon's Tower and Pyramid Hole in shuffle pool", variable=shuffleGanonVar) + customVar = IntVar() + customCheckbutton = Checkbutton(checkBoxFrame, text="Use custom item pool", variable=customVar) createSpoilerCheckbutton.pack(expand=True, anchor=W) suppressRomCheckbutton.pack(expand=True, anchor=W) @@ -77,6 +81,7 @@ def guiMain(args=None): beatableOnlyCheckbutton.pack(expand=True, anchor=W) disableMusicCheckbutton.pack(expand=True, anchor=W) shuffleGanonCheckbutton.pack(expand=True, anchor=W) + customCheckbutton.pack(expand=True, anchor=W) fileDialogFrame = Frame(rightHalfFrame) @@ -252,6 +257,16 @@ def guiMain(args=None): guiargs.quickswap = bool(quickSwapVar.get()) guiargs.disablemusic = bool(disableMusicVar.get()) guiargs.shuffleganon = bool(shuffleGanonVar.get()) + guiargs.custom = bool(customVar.get()) + 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(triforcepieceVar.get()), int(triforcecountVar.get()), + int(triforceVar.get()), int(rupoorcostVar.get())] guiargs.rom = romVar.get() guiargs.jsonout = None guiargs.sprite = sprite @@ -372,6 +387,574 @@ def guiMain(args=None): topFrame2.pack(side=TOP, pady=30) bottomFrame2.pack(side=BOTTOM, pady=(180, 0)) + # Custom Controls + + topFrame3 = Frame(customWindow) + + def validation(P): + if str.isdigit(P) or P == "": + return True + else: + return False + vcmd=(topFrame3.register(validation), '%P') + + itemList1 = Frame(topFrame3) + itemList2 = Frame(topFrame3) + itemList3 = Frame(topFrame3) + itemList4 = Frame(topFrame3) + itemList5 = Frame(topFrame3) + + bowFrame = Frame(itemList1) + bowLabel = Label(bowFrame, text='Bow') + bowVar = StringVar(value='1') + 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) + + silverarrowFrame = Frame(itemList1) + silverarrowLabel = Label(silverarrowFrame, text='Silver Arrow') + silverarrowVar = StringVar(value='1') + silverarrowEntry = Entry(silverarrowFrame, textvariable=silverarrowVar, width=3, validate='all', vcmd=vcmd) + silverarrowFrame.pack() + silverarrowLabel.pack(anchor=W, side=LEFT, padx=(0,13)) + silverarrowEntry.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='6') + 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='1') + 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='6') + 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='1') + 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='5') + 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='10') + 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) + + 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) + + rupoorFrame = Frame(itemList4) + 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,28)) + rupoorEntry.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) + + triforcepieceFrame = Frame(itemList5) + triforcepieceLabel = Label(triforcepieceFrame, text='Triforce Piece') + triforcepieceVar = StringVar(value='0') + 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='0') + 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) + + 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) + if args is not None: # load values from commandline args createSpoilerVar.set(int(args.create_spoiler)) diff --git a/ItemList.py b/ItemList.py index d2847613..6709fd10 100644 --- a/ItemList.py +++ b/ItemList.py @@ -213,7 +213,11 @@ def generate_itempool(world): world.get_location('Agahnim 2').event = True # set up item pool - (pool, placed_items, clock_mode, treasure_hunt_count, treasure_hunt_icon) = get_pool_core(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode) + if world.custom: + (pool, placed_items, clock_mode, treasure_hunt_count, treasure_hunt_icon) = make_custom_item_pool(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode, world.customitemarray) + world.rupoor_cost = min(world.customitemarray[67], 9999) + else: + (pool, placed_items, clock_mode, treasure_hunt_count, treasure_hunt_icon) = get_pool_core(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode) world.itempool = ItemFactory(pool) for (location, item) in placed_items: world.push_item(location, ItemFactory(item), False) @@ -230,10 +234,10 @@ def generate_itempool(world): # logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) - # We mark one random heart container as an advancement item (or 4 heart peices in expert mode) - if world.difficulty in ['easy', 'normal', 'hard']: + # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) + if world.difficulty in ['easy', 'normal', 'hard'] and not (world.custom and world.customitemarray[30] == 0): [item for item in world.itempool if item.name == 'Boss Heart Container'][0].advancement = True - elif world.difficulty in ['expert']: + elif world.difficulty in ['expert'] and not (world.custom and world.customitemarray[29] < 4): adv_heart_pieces = [item for item in world.itempool if item.name == 'Piece of Heart'][0:4] for hp in adv_heart_pieces: hp.advancement = True @@ -253,7 +257,6 @@ def generate_itempool(world): fill_restrictive(world, world.get_all_state(keys=True), crystal_locations, crystals) - def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode): pool = [] placed_items = [] @@ -351,6 +354,144 @@ def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode): placed_items.append(('Master Sword Pedestal', 'Triforce')) return (pool, placed_items, clock_mode, treasure_hunt_count, treasure_hunt_icon) +def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, customitemarray): + pool = [] + placed_items = [] + clock_mode = None + treasure_hunt_count = None + treasure_hunt_icon = None + + # Correct for insanely oversized item counts and take initial steps to handle undersized pools. + for x in range(0, 64): + if customitemarray[x] > total_items_to_place: + customitemarray[x] = total_items_to_place + if customitemarray[66] > total_items_to_place: + customitemarray[66] = total_items_to_place + itemtotal = 0 + for x in range(0, 64): + itemtotal = itemtotal + customitemarray[x] + itemtotal = itemtotal + customitemarray[66] + + pool.extend(['Bow'] * customitemarray[0]) + pool.extend(['Silver Arrows']* customitemarray[1]) + pool.extend(['Blue Boomerang'] * customitemarray[2]) + pool.extend(['Red Boomerang'] * customitemarray[3]) + pool.extend(['Hookshot'] * customitemarray[4]) + pool.extend(['Mushroom'] * customitemarray[5]) + pool.extend(['Magic Powder'] * customitemarray[6]) + pool.extend(['Fire Rod'] * customitemarray[7]) + pool.extend(['Ice Rod'] * customitemarray[8]) + pool.extend(['Bombos'] * customitemarray[9]) + pool.extend(['Ether'] * customitemarray[10]) + pool.extend(['Quake'] * customitemarray[11]) + pool.extend(['Lamp'] * customitemarray[12]) + pool.extend(['Hammer'] * customitemarray[13]) + pool.extend(['Shovel'] * customitemarray[14]) + pool.extend(['Ocarina'] * customitemarray[15]) + pool.extend(['Bug Catching Net'] * customitemarray[16]) + pool.extend(['Book of Mudora'] * customitemarray[17]) + pool.extend(['Cane of Somaria'] * customitemarray[19]) + pool.extend(['Cane of Byrna'] * customitemarray[20]) + pool.extend(['Cape'] * customitemarray[21]) + pool.extend(['Pegasus Boots'] * customitemarray[23]) + pool.extend(['Power Glove'] * customitemarray[24]) + pool.extend(['Titans Mitts'] * customitemarray[25]) + pool.extend(['Progressive Glove'] * customitemarray[26]) + pool.extend(['Flippers'] * customitemarray[27]) + pool.extend(['Piece of Heart'] * customitemarray[29]) + pool.extend(['Boss Heart Container'] * customitemarray[30]) + pool.extend(['Sanctuary Heart Container'] * customitemarray[31]) + pool.extend(['Master Sword'] * customitemarray[33]) + pool.extend(['Tempered Sword'] * customitemarray[34]) + pool.extend(['Golden Sword'] * customitemarray[35]) + pool.extend(['Blue Shield'] * customitemarray[37]) + pool.extend(['Red Shield'] * customitemarray[38]) + pool.extend(['Mirror Shield'] * customitemarray[39]) + pool.extend(['Progressive Shield'] * customitemarray[40]) + pool.extend(['Blue Mail'] * customitemarray[41]) + pool.extend(['Red Mail'] * customitemarray[42]) + pool.extend(['Progressive Armor'] * customitemarray[43]) + pool.extend(['Magic Upgrade (1/2)'] * customitemarray[44]) + pool.extend(['Magic Upgrade (1/4)'] * customitemarray[45]) + pool.extend(['Bomb Upgrade (+5)'] * customitemarray[46]) + pool.extend(['Bomb Upgrade (+10)'] * customitemarray[47]) + pool.extend(['Arrow Upgrade (+5)'] * customitemarray[48]) + pool.extend(['Arrow Upgrade (+10)'] * customitemarray[49]) + pool.extend(['Single Arrow'] * customitemarray[50]) + pool.extend(['Arrows (10)'] * customitemarray[51]) + pool.extend(['Single Bomb'] * customitemarray[52]) + pool.extend(['Bombs (3)'] * customitemarray[53]) + pool.extend(['Rupee (1)'] * customitemarray[54]) + pool.extend(['Rupees (5)'] * customitemarray[55]) + pool.extend(['Rupees (20)'] * customitemarray[56]) + pool.extend(['Rupees (50)'] * customitemarray[57]) + pool.extend(['Rupees (100)'] * customitemarray[58]) + pool.extend(['Rupees (300)'] * customitemarray[59]) + pool.extend(['Rupoor'] * customitemarray[60]) + pool.extend(['Blue Clock'] * customitemarray[61]) + pool.extend(['Green Clock'] * customitemarray[62]) + pool.extend(['Red Clock'] * customitemarray[63]) + pool.extend(['Triforce Piece'] * customitemarray[64]) + pool.extend(['Triforce'] * customitemarray[66]) + + diff = difficulties[difficulty] + + # expert+ difficulties produce the same contents for + # all bottles, since only one bottle is available + if diff.same_bottle: + thisbottle = random.choice(diff.bottles) + for _ in range(customitemarray[18]): + if not diff.same_bottle: + thisbottle = random.choice(diff.bottles) + pool.append(thisbottle) + + if customitemarray[64] > 0 or customitemarray[65] > 0: + treasure_hunt_count = max(min(customitemarray[65], 99), 1) #To display, count must be between 1 and 99. + treasure_hunt_icon = 'Triforce Piece' + # Ensure game is always possible to complete here, force sufficient pieces if the player is unwilling. + if (customitemarray[64] < treasure_hunt_count) and (goal == 'triforcehunt') and (customitemarray[66] == 0): + extrapieces = treasure_hunt_count - customitemarray[64] + pool.extend(['Triforce Piece'] * extrapieces) + itemtotal = itemtotal + extrapieces + + if timer in ['display', 'timed', 'timed-countdown']: + clock_mode = 'countdown' if timer == 'timed-countdown' else 'stopwatch' + elif timer == 'timed-ohko': + clock_mode = 'countdown-ohko' + elif timer == 'ohko': + clock_mode = 'ohko' + + if goal == 'pedestal': + placed_items.append(('Master Sword Pedestal', 'Triforce')) + itemtotal = itemtotal + 1 + + if mode == 'standard': + if progressive == 'off': + placed_items.append(('Link\'s Uncle', 'Fighter Sword')) + pool.extend(['Fighter Sword'] * max((customitemarray[32] - 1), 0)) + pool.extend(['Progressive Sword'] * customitemarray[36]) + else: + placed_items.append(('Link\'s Uncle', 'Progressive Sword')) + pool.extend(['Fighter Sword'] * customitemarray[32]) + pool.extend(['Progressive Sword'] * max((customitemarray[36] - 1), 0)) + else: + pool.extend(['Fighter Sword'] * customitemarray[32]) + pool.extend(['Progressive Sword'] * customitemarray[36]) + + if shuffle == 'insanity': + placed_items.append(('Link\'s House', 'Magic Mirror')) + placed_items.append(('Sanctuary', 'Moon Pearl')) + pool.extend(['Magic Mirror'] * max((customitemarray[22] -1 ), 0)) + pool.extend(['Moon Pearl'] * max((customitemarray[28] - 1), 0)) + else: + pool.extend(['Magic Mirror'] * customitemarray[22]) + pool.extend(['Moon Pearl'] * customitemarray[28]) + + if itemtotal < total_items_to_place: + pool.extend(['Nothing'] * (total_items_to_place - itemtotal)) + + return (pool, placed_items, clock_mode, treasure_hunt_count, treasure_hunt_icon) + # A quick test to ensure all combinations generate the correct amount of items. def test(): for difficulty in ['easy', 'normal', 'hard', 'expert', 'insane']: diff --git a/Main.py b/Main.py index 44597dc8..70dedead 100644 --- a/Main.py +++ b/Main.py @@ -39,7 +39,7 @@ def main(args, seed=None): start = time.clock() # initialize the world - world = World(args.shuffle, args.logic, args.mode, args.difficulty, args.timer, args.progressive, args.goal, args.algorithm, not args.nodungeonitems, args.beatableonly, args.shuffleganon, args.quickswap, args.fastmenu, args.disablemusic, args.keysanity) + world = World(args.shuffle, args.logic, args.mode, args.difficulty, args.timer, args.progressive, args.goal, args.algorithm, not args.nodungeonitems, args.beatableonly, args.shuffleganon, args.quickswap, args.fastmenu, args.disablemusic, args.keysanity, args.custom, args.customitemarray) logger = logging.getLogger('') if seed is None: random.seed(None) @@ -133,7 +133,7 @@ def main(args, seed=None): def copy_world(world): # ToDo: Not good yet - ret = World(world.shuffle, world.logic, world.mode, world.difficulty, world.timer, world.progressive, world.goal, world.algorithm, world.place_dungeon_items, world.check_beatable_only, world.shuffle_ganon, world.quickswap, world.fastmenu, world.disable_music, world.keysanity) + ret = World(world.shuffle, world.logic, world.mode, world.difficulty, world.timer, world.progressive, world.goal, world.algorithm, world.place_dungeon_items, world.check_beatable_only, world.shuffle_ganon, world.quickswap, world.fastmenu, world.disable_music, world.keysanity, world.custom, world.customitemarray) ret.required_medallions = list(world.required_medallions) ret.swamp_patch_required = world.swamp_patch_required ret.ganon_at_pyramid = world.ganon_at_pyramid diff --git a/Rom.py b/Rom.py index 31a6af3a..ac20671a 100644 --- a/Rom.py +++ b/Rom.py @@ -370,7 +370,7 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None): rom.write_byte(0x34FD6, 0x80) overflow_replacement = GREEN_TWENTY_RUPEES # Rupoor negative value - rom.write_int16_to_rom(0x180036, 10) + rom.write_int16_to_rom(0x180036, world.rupoor_cost) #Make Blue Shield more expensive rom.write_bytes(0xF73D2, [0xFC, 0xFF]) rom.write_bytes(0xF73DA, [0x04, 0x00])