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 9560fa8a..2d325e90 100644 Binary files a/data/base2current.bps and b/data/base2current.bps differ 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`