From 600865b6590b6c4214691619890ebf89ba520ade Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 8 Nov 2025 10:37:16 -0600 Subject: [PATCH] Some fixes for Custom Goals - Changed spoiler meta output to include goaltext - Fixed GT Cutscene crash - Allow multiple %d to resolve in goaltext --- BaseClasses.py | 22 ++++++++++++++-------- Main.py | 14 +++++++------- Rom.py | 15 ++++++++++----- data/base2current.bps | Bin 137148 -> 137199 bytes docs/Customizer.md | 2 +- 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index f41301eb..3abcbdd4 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -3274,16 +3274,20 @@ class Spoiler(object): custom = self.metadata['custom_goals'][player] if custom['gtentry'] and 'requirements' in custom['gtentry']: outfile.write('GT Entry Requirement:'.ljust(line_width) + 'custom\n') + outfile.write(' %s\n' % custom['gtentry']['goaltext']) else: outfile.write('GT Entry Requirement:'.ljust(line_width) + '%s crystals\n' % str(self.world.crystals_gt_orig[player])) if custom['ganongoal'] and 'requirements' in custom['ganongoal']: outfile.write('Ganon Requirement:'.ljust(line_width) + 'custom\n') + outfile.write(' %s\n' % custom['ganongoal']['goaltext']) else: outfile.write('Ganon Requirement:'.ljust(line_width) + '%s crystals\n' % str(self.world.crystals_ganon_orig[player])) if custom['pedgoal'] and 'requirements' in custom['pedgoal']: outfile.write('Pedestal Requirement:'.ljust(line_width) + 'custom\n') + outfile.write(' %s\n' % custom['pedgoal']['goaltext']) if custom['murahgoal'] and 'requirements' in custom['murahgoal']: outfile.write('Murahdahla Requirement:'.ljust(line_width) + 'custom\n') + outfile.write(' %s\n' % custom['murahgoal']['goaltext']) outfile.write('Swords:'.ljust(line_width) + '%s\n' % self.metadata['weapons'][player]) outfile.write('\n') outfile.write('Accessibility:'.ljust(line_width) + '%s\n' % self.metadata['accessibility'][player]) @@ -3396,20 +3400,22 @@ class Spoiler(object): player_name = '' if self.world.players == 1 else str(' (Player ' + str(player) + ')') goal = self.world.custom_goals[player]['gtentry'] if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: - outfile.write(str('GT Entry Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) + pass + # outfile.write(str('GT Entry Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) elif self.world.crystals_gt_orig[player] == 'random': outfile.write(str('Crystals Required for GT' + player_name + ':').ljust(line_width) + '%s\n' % (str(self.metadata['gt_crystals'][player]))) goal = self.world.custom_goals[player]['ganongoal'] if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: - outfile.write(str('Ganon Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) + pass + # outfile.write(str('Ganon Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) elif self.world.crystals_ganon_orig[player] == 'random': outfile.write(str('Crystals Required for Ganon' + player_name + ':').ljust(line_width) + '%s\n' % (str(self.metadata['ganon_crystals'][player]))) - goal = self.world.custom_goals[player]['pedgoal'] - if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: - outfile.write(str('Pedestal Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) - goal = self.world.custom_goals[player]['murahgoal'] - if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: - outfile.write(str('Murahdahla Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) + # goal = self.world.custom_goals[player]['pedgoal'] + # if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: + # outfile.write(str('Pedestal Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) + # goal = self.world.custom_goals[player]['murahgoal'] + # if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: + # outfile.write(str('Murahdahla Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) outfile.write('\n\nPrizes:\n\n') for dungeon, prize in self.prizes.items(): outfile.write(str(dungeon + ':').ljust(line_width) + '%s\n' % prize) diff --git a/Main.py b/Main.py index ee5a2d63..a8d2265f 100644 --- a/Main.py +++ b/Main.py @@ -645,23 +645,23 @@ def resolve_random_settings(world, args): else: raise Exception(f'Invalid {list(r.keys())[0]} requirement target for {goal_type}') if req['condition'] & 0x7F == req_table['Pendants']: - goal['logic']['pendants'] = req['target'] or 3 + goal['logic']['pendants'] = req['target'] = req.get('target', 3) elif req['condition'] & 0x7F == req_table['Crystals']: - goal['logic']['crystals'] = req['target'] or 7 + goal['logic']['crystals'] = req['target'] = req.get('target', 7) elif req['condition'] & 0x7F == req_table['PendantBosses']: - goal['logic']['pendant_bosses'] = req['target'] or 3 + goal['logic']['pendant_bosses'] = req['target'] = req.get('target', 3) elif req['condition'] & 0x7F == req_table['CrystalBosses']: - goal['logic']['crystal_bosses'] = req['target'] or 7 + goal['logic']['crystal_bosses'] = req['target'] = req.get('target', 7) elif req['condition'] & 0x7F == req_table['PrizeBosses']: - goal['logic']['bosses'] = req['target'] or 10 + goal['logic']['bosses'] = req['target'] = req.get('target', 10) elif req['condition'] & 0x7F == req_table['Aga1']: goal['logic']['aga1'] = True elif req['condition'] & 0x7F == req_table['Aga2']: goal['logic']['aga2'] = True elif req['condition'] & 0x7F == req_table['TriforcePieces']: - goal['logic']['goal_items'] = req['target'] or None + goal['logic']['goal_items'] = req['target'] = req.get('target', None) elif req['condition'] & 0x7F == req_table['CollectionRate']: - goal['logic']['collection'] = req['target'] or None + goal['logic']['collection'] = req['target'] = req.get('target', None) goal['requirements'].append(req) except KeyError: raise KeyError(f'Invalid {goal_type} requirement: {r}') diff --git a/Rom.py b/Rom.py index a04a4aab..8e69b142 100644 --- a/Rom.py +++ b/Rom.py @@ -43,7 +43,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'a1c8a1c9b4a626f25a240d5b35b17ffe' +RANDOMIZERBASEHASH = '39c6d90d9aa4711fe3c95d85b1a9b16e' class JsonRom(object): @@ -1270,8 +1270,11 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None): goal_bytes += [req['target']] else: goal_bytes += int16_as_bytes(req['target']) - elif 'target' in req: - if req['condition'] & 0x7F < 0x08: + elif req['condition'] & 0x80 == 0: + if req['condition'] & 0x7F == 0x06 or req['condition'] & 0x7F == 0x07: + # agahnims have no target value + pass + elif req['condition'] & 0x7F < 0x08: goal_bytes += [req['target']] else: goal_bytes += int16_as_bytes(req['target']) @@ -2588,8 +2591,10 @@ def write_strings(rom, world, player, team): def get_custom_goal_text(type): goal_text = world.custom_goals[player][type]['goaltext'] - if '%d' in goal_text: - return goal_text % world.custom_goals[player][type]['requirements'][0]['target'] + placeholder_count = goal_text.count('%d') + if placeholder_count > 0: + targets = [req['target'] for req in world.custom_goals[player][type]['requirements'] if 'target' in req][:placeholder_count] + return goal_text % tuple(targets) return goal_text if world.custom_goals[player]['gtentry'] and 'goaltext' in world.custom_goals[player]['gtentry']: diff --git a/data/base2current.bps b/data/base2current.bps index 9560fa8a184ce289aed573bdfbe895330229f819..2d325e9098601881c2aac9356f06c1ebc87e3f39 100644 GIT binary patch delta 6597 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 diff --git a/docs/Customizer.md b/docs/Customizer.md index 6c7063e0..b1c85f19 100644 --- a/docs/Customizer.md +++ b/docs/Customizer.md @@ -76,7 +76,7 @@ This must be defined by player. Each player number should be listed with the app * `gtentry` (Ganon's Tower entrance) * `ganongoal` (Ganon vulnerability) -* `pedpull` (Master Sword Pedestal activation) +* `pedgoal` (Master Sword Pedestal activation) * `murahgoal` (Murahdahla requirement, if given requirements, Murahdahla appears always and acts as an alternative way to beat the game) These four custom goals use the following identical structure to define them. These goals have four primary subsections: `cutscene_gfx`, `goaltext`, `requirements`, and `logic`