The rest of the helpful hint system

This should now work fairly completely. I've added the IR's junk hint text, updated the base ROM to v30, added a checkbox to the GUI/option to the command line to control the hint system, and fixed a bug in the previous upload that listed Skull Woods final erroneously in two arrays. I also now shuffle the Silver Arrow locations before hinting at the first one (so if multiple Silver Arrows are in a seed, all of them are equally likely to be the one Ganon hints at) and now call out "Castle Tower" in hints as a unique location and not as "Hyrule Castle" (what was I thinking on that?).
This commit is contained in:
AmazingAmpharos 2019-01-23 03:04:42 -06:00 committed by GitHub
parent b2defa664d
commit 91bee4f1b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 117 additions and 135 deletions

View File

@ -7,7 +7,7 @@ from Utils import int16_as_bytes
class World(object): 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, retro, custom, customitemarray, boss_shuffle): def __init__(self, shuffle, logic, mode, difficulty, timer, progressive, goal, algorithm, place_dungeon_items, check_beatable_only, shuffle_ganon, quickswap, fastmenu, disable_music, keysanity, retro, custom, customitemarray, boss_shuffle, hints):
self.shuffle = shuffle self.shuffle = shuffle
self.logic = logic self.logic = logic
self.mode = mode self.mode = mode
@ -65,6 +65,7 @@ class World(object):
self.difficulty_requirements = None self.difficulty_requirements = None
self.fix_fake_world = True self.fix_fake_world = True
self.boss_shuffle = boss_shuffle self.boss_shuffle = boss_shuffle
self.hints = hints
self.dynamic_regions = [] self.dynamic_regions = []
self.dynamic_locations = [] self.dynamic_locations = []
self.spoiler = Spoiler(self) self.spoiler = Spoiler(self)

View File

@ -182,6 +182,9 @@ def start():
ensure all locations are reachable. This only has an effect ensure all locations are reachable. This only has an effect
on the restrictive algorithm currently. on the restrictive algorithm currently.
''', action='store_true') ''', action='store_true')
parser.add_argument('--hints', help='''\
Make telepathic tiles and storytellers give helpful hints.
''', action='store_true')
# included for backwards compatibility # included for backwards compatibility
parser.add_argument('--shuffleganon', help=argparse.SUPPRESS, action='store_true', default=True) parser.add_argument('--shuffleganon', help=argparse.SUPPRESS, action='store_true', default=True)
parser.add_argument('--no-shuffleganon', help='''\ parser.add_argument('--no-shuffleganon', help='''\

6
Gui.py
View File

@ -73,6 +73,9 @@ def guiMain(args=None):
shuffleGanonVar = IntVar() shuffleGanonVar = IntVar()
shuffleGanonVar.set(1) #set default shuffleGanonVar.set(1) #set default
shuffleGanonCheckbutton = Checkbutton(checkBoxFrame, text="Include Ganon's Tower and Pyramid Hole in shuffle pool", variable=shuffleGanonVar) shuffleGanonCheckbutton = Checkbutton(checkBoxFrame, text="Include Ganon's Tower and Pyramid Hole in shuffle pool", variable=shuffleGanonVar)
hintsVar = IntVar()
hintsVar.set(1) #set default
hintsCheckbutton = Checkbutton(checkBoxFrame, text="Include Helpful Hints", variable=hintsVar)
customVar = IntVar() customVar = IntVar()
customCheckbutton = Checkbutton(checkBoxFrame, text="Use custom item pool", variable=customVar) customCheckbutton = Checkbutton(checkBoxFrame, text="Use custom item pool", variable=customVar)
@ -85,6 +88,7 @@ def guiMain(args=None):
beatableOnlyCheckbutton.pack(expand=True, anchor=W) beatableOnlyCheckbutton.pack(expand=True, anchor=W)
disableMusicCheckbutton.pack(expand=True, anchor=W) disableMusicCheckbutton.pack(expand=True, anchor=W)
shuffleGanonCheckbutton.pack(expand=True, anchor=W) shuffleGanonCheckbutton.pack(expand=True, anchor=W)
hintsCheckbutton.pack(expand=True, anchor=W)
customCheckbutton.pack(expand=True, anchor=W) customCheckbutton.pack(expand=True, anchor=W)
fileDialogFrame = Frame(rightHalfFrame) fileDialogFrame = Frame(rightHalfFrame)
@ -271,6 +275,7 @@ def guiMain(args=None):
guiargs.quickswap = bool(quickSwapVar.get()) guiargs.quickswap = bool(quickSwapVar.get())
guiargs.disablemusic = bool(disableMusicVar.get()) guiargs.disablemusic = bool(disableMusicVar.get())
guiargs.shuffleganon = bool(shuffleGanonVar.get()) guiargs.shuffleganon = bool(shuffleGanonVar.get())
guiargs.hints = bool(hintsVar.get())
guiargs.custom = bool(customVar.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()), 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(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()),
@ -1013,6 +1018,7 @@ def guiMain(args=None):
logicVar.set(args.logic) logicVar.set(args.logic)
romVar.set(args.rom) romVar.set(args.rom)
shuffleGanonVar.set(args.shuffleganon) shuffleGanonVar.set(args.shuffleganon)
hintsVar.set(args.hints)
if args.sprite is not None: if args.sprite is not None:
set_sprite(Sprite(args.sprite)) set_sprite(Sprite(args.sprite))

View File

@ -40,7 +40,7 @@ def main(args, seed=None):
start = time.clock() start = time.clock()
# initialize the world # 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, args.retro, args.custom, args.customitemarray, args.shufflebosses) 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.retro, args.custom, args.customitemarray, args.shufflebosses, args.hints)
logger = logging.getLogger('') logger = logging.getLogger('')
if seed is None: if seed is None:
random.seed(None) random.seed(None)
@ -112,7 +112,7 @@ def main(args, seed=None):
else: else:
sprite = None sprite = None
outfilebase = 'ER_%s_%s-%s-%s%s_%s-%s%s%s%s_%s' % (world.logic, world.difficulty, world.mode, world.goal, "" if world.timer in ['none', 'display'] else "-" + world.timer, world.shuffle, world.algorithm, "-keysanity" if world.keysanity else "", "-retro" if world.retro else "", "-prog_" + world.progressive if world.progressive in ['off', 'random'] else "", world.seed) outfilebase = 'ER_%s_%s-%s-%s%s_%s-%s%s%s%s%s_%s' % (world.logic, world.difficulty, world.mode, world.goal, "" if world.timer in ['none', 'display'] else "-" + world.timer, world.shuffle, world.algorithm, "-keysanity" if world.keysanity else "", "-retro" if world.retro else "", "-prog_" + world.progressive if world.progressive in ['off', 'random'] else "", "-nohints" if not world.hints else "", world.seed)
if not args.suppress_rom: if not args.suppress_rom:
if args.jsonout: if args.jsonout:
@ -140,7 +140,7 @@ def gt_filler(world):
def copy_world(world): def copy_world(world):
# ToDo: Not good yet # 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, world.retro, world.custom, world.customitemarray, world.boss_shuffle) 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.retro, world.custom, world.customitemarray, world.boss_shuffle, world.hints)
ret.required_medallions = list(world.required_medallions) ret.required_medallions = list(world.required_medallions)
ret.swamp_patch_required = world.swamp_patch_required ret.swamp_patch_required = world.swamp_patch_required
ret.ganon_at_pyramid = world.ganon_at_pyramid ret.ganon_at_pyramid = world.ganon_at_pyramid

View File

@ -468,8 +468,8 @@ location_table = {'Mushroom': (0x180013, False, 'in the woods'),
'Sewers - Secret Room - Middle': (0xEB60, False, 'in the sewers'), 'Sewers - Secret Room - Middle': (0xEB60, False, 'in the sewers'),
'Sewers - Secret Room - Right': (0xEB63, False, 'in the sewers'), 'Sewers - Secret Room - Right': (0xEB63, False, 'in the sewers'),
'Sanctuary': (0xEA79, False, 'in Sanctuary'), 'Sanctuary': (0xEA79, False, 'in Sanctuary'),
'Castle Tower - Room 03': (0xEAB5, False, 'in Hyrule Castle'), 'Castle Tower - Room 03': (0xEAB5, False, 'in Castle Tower'),
'Castle Tower - Dark Maze': (0xEAB2, False, 'in Hyrule Castle'), 'Castle Tower - Dark Maze': (0xEAB2, False, 'in Castle Tower'),
'Old Man': (0xF69FA, False, 'with the old man'), 'Old Man': (0xF69FA, False, 'with the old man'),
'Spectacle Rock Cave': (0x180002, False, 'alone in a cave'), 'Spectacle Rock Cave': (0x180002, False, 'alone in a cave'),
'Paradox Cave Lower - Far Left': (0xEB2A, False, 'in paradox cave'), 'Paradox Cave Lower - Far Left': (0xEB2A, False, 'in paradox cave'),

7
Rom.py
View File

@ -16,7 +16,7 @@ from Items import ItemFactory
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '354bad0d01b6284c89f05c9b414d48c1' RANDOMIZERBASEHASH = 'cb560220b7b1b8202e92381aee19cd36'
class JsonRom(object): class JsonRom(object):
@ -1016,6 +1016,7 @@ def write_strings(rom, world):
tt.removeUnwantedText() tt.removeUnwantedText()
# For hints, first we write hints about entrances, some from the inconvenient list others from all reasonable entrances. # For hints, first we write hints about entrances, some from the inconvenient list others from all reasonable entrances.
if world.hints:
entrances_to_hint = {} entrances_to_hint = {}
entrances_to_hint.update(InconvenientEntrances) entrances_to_hint.update(InconvenientEntrances)
if world.shuffle_ganon: if world.shuffle_ganon:
@ -1098,6 +1099,7 @@ def write_strings(rom, world):
# We still need the older hints of course. Those are done here. # We still need the older hints of course. Those are done here.
silverarrows = world.find_items('Silver Arrows') silverarrows = world.find_items('Silver Arrows')
random.shuffle(silverarrows)
silverarrow_hint = (' %s?' % silverarrows[0].hint_text.replace('Ganon\'s', 'my')) if silverarrows else '?\nI think not!' silverarrow_hint = (' %s?' % silverarrows[0].hint_text.replace('Ganon\'s', 'my')) if silverarrows else '?\nI think not!'
tt['ganon_phase_3'] = 'Did you find the silver arrows%s' % silverarrow_hint tt['ganon_phase_3'] = 'Did you find the silver arrows%s' % silverarrow_hint
@ -1178,7 +1180,7 @@ def write_strings(rom, world):
InconvenientEntrances = {'Turtle Rock': 'Turtle Rock Main', InconvenientEntrances = {'Turtle Rock': 'Turtle Rock Main',
'Misery Mire': 'Misery Mire', 'Misery Mire': 'Misery Mire',
'Ice Palace': 'Ice Palace', 'Ice Palace': 'Ice Palace',
'Skull Woods Final Section': 'Skull Woods Final', 'Skull Woods Final Section': 'The back of Skull Woods',
'Death Mountain Return Cave (West)': 'The upper DM entrance', 'Death Mountain Return Cave (West)': 'The upper DM entrance',
'Mimic Cave': 'Mimic Ledge', 'Mimic Cave': 'Mimic Ledge',
'Dark World Hammer Peg Cave': 'The rows of pegs', 'Dark World Hammer Peg Cave': 'The rows of pegs',
@ -1194,7 +1196,6 @@ OtherEntrances = {'Eastern Palace': 'Eastern Palace',
'Thieves Town': 'Thieves\' Town', 'Thieves Town': 'Thieves\' Town',
'Bumper Cave (Bottom)': 'The lower Bumper Cave', 'Bumper Cave (Bottom)': 'The lower Bumper Cave',
'Swamp Palace': 'Swamp Palace', 'Swamp Palace': 'Swamp Palace',
'Skull Woods Final Section': 'The back of Skull Woods',
'Dark Death Mountain Ledge (West)': 'The East dark DM connector ledge', 'Dark Death Mountain Ledge (West)': 'The East dark DM connector ledge',
'Dark Death Mountain Ledge (East)': 'The East dark DM connector ledge', 'Dark Death Mountain Ledge (East)': 'The East dark DM connector ledge',
'Superbunny Cave (Top)': 'The summit of dark DM cave', 'Superbunny Cave (Top)': 'The summit of dark DM cave',

73
Text.py
View File

@ -225,57 +225,28 @@ TavernMan_texts = [
] ]
junk_texts = [ junk_texts = [
"What do you\ncall a blind\ndinosaur?\na doyouthink-\nhesaurus.", "Its a secret\nto everybody.\n >",
"A blind man\nwalks into\na bar.\nAnd a table.\nAnd a chair.", "Dodongo\ndislikes\nsmoke. >",
"What do ducks\nlike to eat?\n\nQuackers!", "> Digdogger\nhates certain\nkind of sound.",
"How do you\nset up a party\nin space?\n\nYou planet!", "I bet youd\nlike to have\nmore bombs. >",
"I'm glad I\nknow sign\nlanguage.\nIt's pretty\nhandy.", ">Secret power\nis said to be\nin the arrow.",
"What did Zelda\nsay to Link at\na secure door?\n\nTRIFORCE!", "Aim at the\neyes of Gohma.\n >",
"I am on a\nseafood diet.\n\nEvery time\nI see food,\nI eat it.", "Grumble,\ngrumble…\n >",
"I've decided\nto sell my\nvacuum.\nIt was just\ngathering\ndust.", "10th enemy\nhas the bomb.\n >",
"What's the best\ntime to go to\nthe dentist?\n\nTooth-hurtie!", "Go to the\nnext room.\n >",
"Why can't a\nbike stand on\nits own?\n\nIt's two-tired!", ">Thanks, @\nYoure the\nhero of Hyrule",
"If you haven't\nfound Quake\nyet…\nit's not your\nfault.", "Theres always\nmoney in the\nBanana Stand>",
"Why is Peter\nPan always\nflying?\nBecause he\nNeverlands!", " \nJust walk away\n >",
"I once told a\njoke to Armos.\n\nBut he\nremained\nstone-faced!", "everybody is\nlooking for\nsomething >",
"Lanmola was\nlate to our\ndinner party.\nHe just came\nfor the desert", "Candy Is Dandy\nBut liquor\nIs quicker. >",
"Moldorm is\nsuch a\nprankster.\nAnd I fall for\nit every time!", "Spring Ball\nare behind\nRidley >",
"Helmasaur is\nthrowing a\nparty.\nI hope it's\na masquerade!", "The gnome asks\nyou to guess\nhis name. >",
"I'd like to\nknow Arrghus\nbetter.\nBut he won't\ncome out of\nhis shell!", "I heard beans\non toast is a\ngreat meal. >",
"Mothula didn't\nhave much fun\nat the party.\nHe's immune to\nspiked punch!", "> Sweetcorn\non pizza is a\ngreat choice.",
"Don't set me\nup with that\nchick from\nSteve's Town.\n\n\nI'm not\ninterested in\na Blind date!", "> race roms\ndont have\nspoiler logs",
"Kholdstare is\nafraid to go\nto the circus.\nHungry kids\nthought he was\ncotton candy!", "I bet a nice\ncup of tea\nwould help! >",
"I asked who\nVitreous' best\nfriends are.\nHe said,\n'Me, Myself,\nand Eye!'", "I bet you\nexpected help,\ndidn't you? >",
"Trinexx can be\na hothead or\nhe can be an\nice guy. In\nthe end, he's\na solid\nindividual!", "Learn to make\nplogues, easy\nand yummy! >"
"Bari thought I\nhad moved out\nof town.\nHe was shocked\nto see me!",
"I can only get\nWeetabix\naround here.\nI have to go\nto Steve's\nTown for Count\nChocula!",
"Don't argue\nwith a frozen\nDeadrock.\nHe'll never\nchange his\nposition!",
"I offered a\ndrink to a\nself-loathing\nGhini.\nHe said he\ndidn't like\nspirits!",
"I was supposed\nto meet Gibdo\nfor lunch.\nBut he got\nwrapped up in\nsomething!",
"Goriya sure\nhas changed\nin this game.\nI hope he\ncomes back\naround!",
"Hinox actually\nwants to be a\nlawyer.\nToo bad he\nbombed the\nBar exam!",
"I'm surprised\nMoblin's tusks\nare so gross.\nHe always has\nhis Trident\nwith him!",
"Don't tell\nStalfos I'm\nhere.\nHe has a bone\nto pick with\nme!",
"I got\nWallmaster to\nhelp me move\nfurniture.\nHe was really\nhandy!",
"Wizzrobe was\njust here.\nHe always\nvanishes right\nbefore we get\nthe check!",
"I shouldn't\nhave picked up\nZora's tab.\nThat guy\ndrinks like\na fish!",
"I was sharing\na drink with\nPoe.\nFor no reason,\nhe left in a\nheartbeat!",
"Don't trust\nhorsemen on\nDeath Mountain.\nThey're Lynel\nthe time!",
"Today's\nspecial is\nbattered bat.\nGot slapped\nfor offering a\nlady a Keese!",
"Don't walk\nunder\npropellered\npineapples.\nYou may end up\nwearing\na pee hat!",
"My girlfriend\nburrowed under\nthe sand.\nSo I decided\nto Leever!",
"Geldman wants\nto be a\nBroadway star.\nHe's always\npracticing\nJazz Hands!",
"Octoballoon\nmust be mad\nat me.\nHe blows up\nat the sight\nof me!",
"Toppo is a\ntotal pothead.\n\nHe hates it\nwhen you take\naway his grass",
"I lost my\nshield by\nthat house.\nWhy did they\nput up a\nPikit fence?!",
"Know that fox\nin Steve's\nTown?\nHe'll Pikku\npockets if you\naren't careful",
"Dash through\nDark World\nbushes.\nYou'll see\nGanon is tryin\nto Stal you!",
"Eyegore!\n\nYou gore!\nWe all gore\nthose jerks\nwith arrows!",
"I like my\nwhiskey neat.\n\nSome prefer it\nOctoroks!",
"I consoled\nFreezor over a\ncup of coffee.\nHis problems\njust seemed to\nmelt away!",
"Magic droplets\nof water don't\nshut up.\nThey just\nKyameron!",
"I bought hot\nwings for\nSluggula.\nThey gave him\nexplosive\ndiarrhea!",
"Hardhat Beetle\nwon't\nLet It Be?\nTell it to Get\nBack or give\nit a Ticket to\nRide down\na hole!",
] ]
KingsReturn_texts = [ KingsReturn_texts = [

File diff suppressed because one or more lines are too long