Some fixes for Custom Goals
- Changed spoiler meta output to include goaltext - Fixed GT Cutscene crash - Allow multiple %d to resolve in goaltext
This commit is contained in:
@@ -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)
|
||||
|
||||
14
Main.py
14
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}')
|
||||
|
||||
15
Rom.py
15
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']:
|
||||
|
||||
Binary file not shown.
@@ -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`
|
||||
|
||||
Reference in New Issue
Block a user