New goals and rom update
This commit is contained in:
@@ -155,7 +155,9 @@ class World(object):
|
|||||||
def finish_init(self):
|
def finish_init(self):
|
||||||
for player in range(1, self.players + 1):
|
for player in range(1, self.players + 1):
|
||||||
if self.mode[player] == 'retro':
|
if self.mode[player] == 'retro':
|
||||||
self.mode[player] == 'open'
|
self.mode[player] = 'open'
|
||||||
|
if self.goal[player] == 'completionist':
|
||||||
|
self.accessibility[player] = 'locations'
|
||||||
|
|
||||||
def get_name_string_for_object(self, obj):
|
def get_name_string_for_object(self, obj):
|
||||||
return obj.name if self.players == 1 else f'{obj.name} ({self.get_player_names(obj.player)})'
|
return obj.name if self.players == 1 else f'{obj.name} ({self.get_player_names(obj.player)})'
|
||||||
@@ -1035,6 +1037,10 @@ class CollectionState(object):
|
|||||||
def item_count(self, item, player):
|
def item_count(self, item, player):
|
||||||
return self.prog_items[item, player]
|
return self.prog_items[item, player]
|
||||||
|
|
||||||
|
def everything(self, player):
|
||||||
|
return (len([x for x in self.locations_checked if x.player == player])
|
||||||
|
>= len(self.world.get_filled_locations(player)))
|
||||||
|
|
||||||
def has_crystals(self, count, player):
|
def has_crystals(self, count, player):
|
||||||
crystals = ['Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7']
|
crystals = ['Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7']
|
||||||
return len([crystal for crystal in crystals if self.has(crystal, player)]) >= count
|
return len([crystal for crystal in crystals if self.has(crystal, player)]) >= count
|
||||||
@@ -2587,7 +2593,7 @@ class Spoiler(object):
|
|||||||
outfile.write('Mode: %s\n' % self.metadata['mode'][player])
|
outfile.write('Mode: %s\n' % self.metadata['mode'][player])
|
||||||
outfile.write('Swords: %s\n' % self.metadata['weapons'][player])
|
outfile.write('Swords: %s\n' % self.metadata['weapons'][player])
|
||||||
outfile.write('Goal: %s\n' % self.metadata['goal'][player])
|
outfile.write('Goal: %s\n' % self.metadata['goal'][player])
|
||||||
if self.metadata['goal'][player] in ['triforcehunt', 'trinity']:
|
if self.metadata['goal'][player] in ['triforcehunt', 'trinity', 'ganonhunt']:
|
||||||
outfile.write('Triforce Pieces Required: %s\n' % self.metadata['triforcegoal'][player])
|
outfile.write('Triforce Pieces Required: %s\n' % self.metadata['triforcegoal'][player])
|
||||||
outfile.write('Triforce Pieces Total: %s\n' % self.metadata['triforcepool'][player])
|
outfile.write('Triforce Pieces Total: %s\n' % self.metadata['triforcepool'][player])
|
||||||
outfile.write('Crystals required for GT: %s\n' % (str(self.world.crystals_gt_orig[player])))
|
outfile.write('Crystals required for GT: %s\n' % (str(self.world.crystals_gt_orig[player])))
|
||||||
@@ -2867,7 +2873,8 @@ world_mode = {"open": 0, "standard": 1, "inverted": 2}
|
|||||||
sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3}
|
sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3}
|
||||||
|
|
||||||
# byte 2: GGGD DFFH (goal, diff, item_func, hints)
|
# byte 2: GGGD DFFH (goal, diff, item_func, hints)
|
||||||
goal_mode = {'ganon': 0, 'pedestal': 1, 'dungeons': 2, 'triforcehunt': 3, 'crystals': 4, 'trinity': 5}
|
goal_mode = {'ganon': 0, 'pedestal': 1, 'dungeons': 2, 'triforcehunt': 3, 'crystals': 4, 'trinity': 5,
|
||||||
|
'ganonhunt': 6, 'completionist': 7}
|
||||||
diff_mode = {"normal": 0, "hard": 1, "expert": 2}
|
diff_mode = {"normal": 0, "hard": 1, "expert": 2}
|
||||||
func_mode = {"normal": 0, "hard": 1, "expert": 2}
|
func_mode = {"normal": 0, "hard": 1, "expert": 2}
|
||||||
|
|
||||||
|
|||||||
2
Fill.py
2
Fill.py
@@ -400,7 +400,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
|||||||
else:
|
else:
|
||||||
max_trash = gt_count
|
max_trash = gt_count
|
||||||
scaled_trash = math.floor(max_trash * scale_factor)
|
scaled_trash = math.floor(max_trash * scale_factor)
|
||||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
if world.goal[player] in ['triforcehunt', 'trinity', 'ganonhunt']:
|
||||||
gftower_trash_count = random.randint(scaled_trash, max_trash)
|
gftower_trash_count = random.randint(scaled_trash, max_trash)
|
||||||
else:
|
else:
|
||||||
gftower_trash_count = random.randint(0, scaled_trash)
|
gftower_trash_count = random.randint(0, scaled_trash)
|
||||||
|
|||||||
28
ItemList.py
28
ItemList.py
@@ -181,8 +181,12 @@ def get_custom_array_key(item):
|
|||||||
|
|
||||||
|
|
||||||
def generate_itempool(world, player):
|
def generate_itempool(world, player):
|
||||||
if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'trinity', 'crystals']
|
if (world.difficulty[player] not in ['normal', 'hard', 'expert']
|
||||||
or world.mode[player] not in ['open', 'standard', 'inverted'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']):
|
or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'trinity', 'crystals',
|
||||||
|
'ganonhunt', 'completionist']
|
||||||
|
or world.mode[player] not in ['open', 'standard', 'inverted']
|
||||||
|
or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown']
|
||||||
|
or world.progressive not in ['on', 'off', 'random']):
|
||||||
raise NotImplementedError('Not supported yet')
|
raise NotImplementedError('Not supported yet')
|
||||||
|
|
||||||
if world.timer in ['ohko', 'timed-ohko']:
|
if world.timer in ['ohko', 'timed-ohko']:
|
||||||
@@ -344,7 +348,7 @@ def generate_itempool(world, player):
|
|||||||
world.clock_mode = clock_mode
|
world.clock_mode = clock_mode
|
||||||
|
|
||||||
goal = world.goal[player]
|
goal = world.goal[player]
|
||||||
if goal in ['triforcehunt', 'trinity']:
|
if goal in ['triforcehunt', 'trinity', 'ganonhunt']:
|
||||||
g, t = set_default_triforce(goal, world.treasure_hunt_count[player], world.treasure_hunt_total[player])
|
g, t = set_default_triforce(goal, world.treasure_hunt_count[player], world.treasure_hunt_total[player])
|
||||||
world.treasure_hunt_count[player], world.treasure_hunt_total[player] = g, t
|
world.treasure_hunt_count[player], world.treasure_hunt_total[player] = g, t
|
||||||
world.treasure_hunt_icon[player] = 'Triforce Piece'
|
world.treasure_hunt_icon[player] = 'Triforce Piece'
|
||||||
@@ -817,15 +821,15 @@ def add_pot_contents(world, player):
|
|||||||
world.itempool.append(ItemFactory(item, player))
|
world.itempool.append(ItemFactory(item, player))
|
||||||
|
|
||||||
|
|
||||||
def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, bombbag,
|
def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords,
|
||||||
door_shuffle, logic, flute_activated):
|
bombbag, door_shuffle, logic, flute_activated):
|
||||||
pool = []
|
pool = []
|
||||||
placed_items = {}
|
placed_items = {}
|
||||||
precollected_items = []
|
precollected_items = []
|
||||||
clock_mode = None
|
clock_mode = None
|
||||||
if goal in ['triforcehunt', 'trinity']:
|
if goal in ['triforcehunt', 'trinity', 'ganonhunt']:
|
||||||
if treasure_hunt_total == 0:
|
if treasure_hunt_total == 0:
|
||||||
treasure_hunt_total = 30 if goal == 'triforcehunt' else 10
|
treasure_hunt_total = 30 if goal in ['triforcehunt', 'ganonhunt'] else 10
|
||||||
# triforce pieces max out
|
# triforce pieces max out
|
||||||
triforcepool = ['Triforce Piece'] * min(treasure_hunt_total, max_goal)
|
triforcepool = ['Triforce Piece'] * min(treasure_hunt_total, max_goal)
|
||||||
|
|
||||||
@@ -928,7 +932,7 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt
|
|||||||
elif timer == 'timed-ohko':
|
elif timer == 'timed-ohko':
|
||||||
pool.extend(diff.timedohko)
|
pool.extend(diff.timedohko)
|
||||||
clock_mode = 'countdown-ohko'
|
clock_mode = 'countdown-ohko'
|
||||||
if goal in ['triforcehunt', 'trinity']:
|
if goal in ['triforcehunt', 'trinity', 'ganonhunt']:
|
||||||
pool.extend(triforcepool)
|
pool.extend(triforcepool)
|
||||||
|
|
||||||
for extra in diff.extras:
|
for extra in diff.extras:
|
||||||
@@ -987,7 +991,7 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer
|
|||||||
customitemarray["triforce"] = total_items_to_place
|
customitemarray["triforce"] = total_items_to_place
|
||||||
|
|
||||||
# Triforce Pieces
|
# Triforce Pieces
|
||||||
if goal in ['triforcehunt', 'trinity']:
|
if goal in ['triforcehunt', 'trinity', 'ganonhunt']:
|
||||||
g, t = set_default_triforce(goal, customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"])
|
g, t = set_default_triforce(goal, customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"])
|
||||||
customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"] = g, t
|
customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"] = g, t
|
||||||
|
|
||||||
@@ -1025,8 +1029,8 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer
|
|||||||
treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], max_goal), 1)
|
treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], max_goal), 1)
|
||||||
treasure_hunt_icon = 'Triforce Piece'
|
treasure_hunt_icon = 'Triforce Piece'
|
||||||
# Ensure game is always possible to complete here, force sufficient pieces if the player is unwilling.
|
# Ensure game is always possible to complete here, force sufficient pieces if the player is unwilling.
|
||||||
if ((customitemarray["triforcepieces"] < treasure_hunt_count) and (goal in ['triforcehunt', 'trinity'])
|
if ((customitemarray["triforcepieces"] < treasure_hunt_count)
|
||||||
and (customitemarray["triforce"] == 0)):
|
and (goal in ['triforcehunt', 'trinity', 'ganonhunt']) and (customitemarray["triforce"] == 0)):
|
||||||
extrapieces = treasure_hunt_count - customitemarray["triforcepieces"]
|
extrapieces = treasure_hunt_count - customitemarray["triforcepieces"]
|
||||||
pool.extend(['Triforce Piece'] * extrapieces)
|
pool.extend(['Triforce Piece'] * extrapieces)
|
||||||
itemtotal = itemtotal + extrapieces
|
itemtotal = itemtotal + extrapieces
|
||||||
@@ -1214,7 +1218,7 @@ def get_player_dungeon_item_pool(world, player):
|
|||||||
# location pool doesn't support larger values at this time
|
# location pool doesn't support larger values at this time
|
||||||
def set_default_triforce(goal, custom_goal, custom_total):
|
def set_default_triforce(goal, custom_goal, custom_total):
|
||||||
triforce_goal, triforce_total = 0, 0
|
triforce_goal, triforce_total = 0, 0
|
||||||
if goal == 'triforcehunt':
|
if goal in ['triforcehunt', 'ganonhunt']:
|
||||||
triforce_goal, triforce_total = 20, 30
|
triforce_goal, triforce_total = 20, 30
|
||||||
elif goal == 'trinity':
|
elif goal == 'trinity':
|
||||||
triforce_goal, triforce_total = 8, 10
|
triforce_goal, triforce_total = 8, 10
|
||||||
|
|||||||
2
Main.py
2
Main.py
@@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new
|
|||||||
from source.tools.BPS import create_bps_from_data
|
from source.tools.BPS import create_bps_from_data
|
||||||
from source.classes.CustomSettings import CustomSettings
|
from source.classes.CustomSettings import CustomSettings
|
||||||
|
|
||||||
__version__ = '1.2.0.0-u'
|
__version__ = '1.2.0.1-u'
|
||||||
|
|
||||||
from source.classes.BabelFish import BabelFish
|
from source.classes.BabelFish import BabelFish
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,15 @@ This is similar to insanity mode in ER where door entrances and exits are not pa
|
|||||||
|
|
||||||
Please see [Customizer documentation](docs/Customizer.md) on how to create custom seeds.
|
Please see [Customizer documentation](docs/Customizer.md) on how to create custom seeds.
|
||||||
|
|
||||||
|
## New Goals
|
||||||
|
|
||||||
|
### Triforce Hunt + Ganon
|
||||||
|
Collect the requisite triforce pieces, then defeat Ganon. (Aga2 not required). Use `ganonhunt` on CLI
|
||||||
|
|
||||||
|
### Completionist
|
||||||
|
All dungeons not enough for you? You have to obtain every item in the game too. This option turns on the collection rate counter and forces accessibility to be 100% locations. Finish by defeating Ganon.
|
||||||
|
|
||||||
|
|
||||||
## Standard Generation Change
|
## Standard Generation Change
|
||||||
|
|
||||||
Hyrule Castle in standard mode is generated a little differently now. The throne room is guaranteed to be in Hyrule Castle and the Sanctuary is guaranteed to be beyond that. Additionally, the Mirror Scroll will bring you back to Zelda's Cell or the Throne Room depending on what save point you last obtained, this is to make it consistent with where you end up if you die. If you are lucky enough to find the Mirror, it behaves differently and brings you the last entrance used - giving you more options for exploration in Hyrule Castle.
|
Hyrule Castle in standard mode is generated a little differently now. The throne room is guaranteed to be in Hyrule Castle and the Sanctuary is guaranteed to be beyond that. Additionally, the Mirror Scroll will bring you back to Zelda's Cell or the Throne Room depending on what save point you last obtained, this is to make it consistent with where you end up if you die. If you are lucky enough to find the Mirror, it behaves differently and brings you the last entrance used - giving you more options for exploration in Hyrule Castle.
|
||||||
@@ -100,10 +109,10 @@ These are now independent of retro mode and have three options: None, Random, an
|
|||||||
|
|
||||||
# Bug Fixes and Notes
|
# Bug Fixes and Notes
|
||||||
|
|
||||||
None yet
|
* 1.2.0.1-u
|
||||||
|
* Fixed the issue when defeating Agahnim and standing in the doorway can cause door state to linger.
|
||||||
|
|
||||||
# Known Issues
|
# Known Issues
|
||||||
|
|
||||||
* Standing in the doorway when defeating Aga 1 and being teleported to the Dark World will not clear door state. It may cause issues requiring a Save & Quit to fix.
|
|
||||||
* Decoupled doors can lead to situations where you aren't logically supposed to go back through a door without a big key or small key, but you can if you press the correct direction back through the door first. There are some transitions where you may get stuck without a bomb. These problems are planned to be fixed.
|
* Decoupled doors can lead to situations where you aren't logically supposed to go back through a door without a big key or small key, but you can if you press the correct direction back through the door first. There are some transitions where you may get stuck without a bomb. These problems are planned to be fixed.
|
||||||
* Logic getting to Skull X room may be wrong if a trap door, big key door, or bombable wall. A bomb jump to get to those pot may be required if you don't have boots to bonk across.
|
* Logic getting to Skull X room may be wrong if a trap door, big key door, or bombable wall is shuffled there. A bomb jump to get to those pot may be required if you don't have boots to bonk across.
|
||||||
15
Rom.py
15
Rom.py
@@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = 'b6fcbc0d61faffa178135545f18fadbd'
|
RANDOMIZERBASEHASH = 'fb7f9a0d501ba9ecd0a31066f9a0a973'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -730,7 +730,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' else DROptions.Town_Portal
|
dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' else DROptions.Town_Portal
|
||||||
if world.doorShuffle[player] not in ['vanilla', 'basic']:
|
if world.doorShuffle[player] not in ['vanilla', 'basic']:
|
||||||
dr_flags |= DROptions.Map_Info
|
dr_flags |= DROptions.Map_Info
|
||||||
if world.collection_rate[player] and world.goal[player] not in ['triforcehunt', 'trinity']:
|
if ((world.collection_rate[player] or world.goal[player] == 'completionist')
|
||||||
|
and world.goal[player] not in ['triforcehunt', 'trinity', 'ganonhunt']):
|
||||||
dr_flags |= DROptions.Debug
|
dr_flags |= DROptions.Debug
|
||||||
if world.doorShuffle[player] not in ['vanilla', 'basic'] and world.logic[player] != 'nologic'\
|
if world.doorShuffle[player] not in ['vanilla', 'basic'] and world.logic[player] != 'nologic'\
|
||||||
and world.mixed_travel[player] == 'prevent':
|
and world.mixed_travel[player] == 'prevent':
|
||||||
@@ -1275,7 +1276,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
|
|
||||||
# set up goals for treasure hunt
|
# set up goals for treasure hunt
|
||||||
rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon[player] == 'Triforce Piece' else [0x0D, 0x28])
|
rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon[player] == 'Triforce Piece' else [0x0D, 0x28])
|
||||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
if world.goal[player] in ['triforcehunt', 'trinity', 'ganonhunt']:
|
||||||
rom.write_bytes(0x180167, int16_as_bytes(world.treasure_hunt_count[player]))
|
rom.write_bytes(0x180167, int16_as_bytes(world.treasure_hunt_count[player]))
|
||||||
rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled)
|
rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled)
|
||||||
|
|
||||||
@@ -1340,6 +1341,10 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat
|
rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat
|
||||||
elif world.goal[player] in ['crystals', 'trinity']:
|
elif world.goal[player] in ['crystals', 'trinity']:
|
||||||
rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals
|
rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals
|
||||||
|
elif world.goal[player] in ['ganonhunt']:
|
||||||
|
rom.write_byte(0x18003E, 0x05) # make ganon invincible until all triforce pieces collected
|
||||||
|
elif world.goal[player] in ['completionist']:
|
||||||
|
rom.write_byte(0x18003E, 0x09) # make ganon invincible until everything is collected
|
||||||
else:
|
else:
|
||||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||||
|
|
||||||
@@ -2362,6 +2367,10 @@ def write_strings(rom, world, player, team):
|
|||||||
trinity_crystal_text = ('%d crystal to beat Ganon.' if world.crystals_needed_for_ganon[player] == 1 else '%d crystals to beat Ganon.') % world.crystals_needed_for_ganon[player]
|
trinity_crystal_text = ('%d crystal to beat Ganon.' if world.crystals_needed_for_ganon[player] == 1 else '%d crystals to beat Ganon.') % world.crystals_needed_for_ganon[player]
|
||||||
tt['sign_ganon'] = 'Three ways to victory! %s Get to it!' % trinity_crystal_text
|
tt['sign_ganon'] = 'Three ways to victory! %s Get to it!' % trinity_crystal_text
|
||||||
tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % int(world.treasure_hunt_count[player])
|
tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % int(world.treasure_hunt_count[player])
|
||||||
|
elif world.goal[player] == 'ganonhunt':
|
||||||
|
tt['sign_ganon'] = 'Go find the Triforce pieces to beat Ganon'
|
||||||
|
elif world.goal[player] == 'completionist':
|
||||||
|
tt['sign_ganon'] = 'Ganon only respects those who have done everything'
|
||||||
tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)]
|
tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)]
|
||||||
tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!'
|
tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!'
|
||||||
tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!'
|
tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!'
|
||||||
|
|||||||
4
Rules.py
4
Rules.py
@@ -60,6 +60,10 @@ def set_rules(world, player):
|
|||||||
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
||||||
elif world.goal[player] in ['triforcehunt', 'trinity']:
|
elif world.goal[player] in ['triforcehunt', 'trinity']:
|
||||||
add_rule(world.get_location('Murahdahla', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player]))
|
add_rule(world.get_location('Murahdahla', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player]))
|
||||||
|
elif world.goal[player] == 'ganonhunt':
|
||||||
|
add_rule(world.get_location('Ganon', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player]))
|
||||||
|
elif world.goal[player] == 'completionist':
|
||||||
|
add_rule(world.get_location('Ganon', player), lambda state: state.everything(player))
|
||||||
|
|
||||||
if world.mode[player] != 'inverted':
|
if world.mode[player] != 'inverted':
|
||||||
set_big_bomb_rules(world, player)
|
set_big_bomb_rules(world, player)
|
||||||
|
|||||||
Binary file not shown.
@@ -82,6 +82,8 @@
|
|||||||
pedestal: 2
|
pedestal: 2
|
||||||
triforce-hunt: 2
|
triforce-hunt: 2
|
||||||
trinity: 2
|
trinity: 2
|
||||||
|
ganonhunt: 2
|
||||||
|
completionist: 1
|
||||||
triforce_goal_min: 10
|
triforce_goal_min: 10
|
||||||
triforce_goal_max: 30
|
triforce_goal_max: 30
|
||||||
triforce_pool_min: 20
|
triforce_pool_min: 20
|
||||||
|
|||||||
@@ -67,7 +67,9 @@
|
|||||||
"dungeons",
|
"dungeons",
|
||||||
"triforcehunt",
|
"triforcehunt",
|
||||||
"trinity",
|
"trinity",
|
||||||
"crystals"
|
"crystals",
|
||||||
|
"ganonhunt",
|
||||||
|
"completionist"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"difficulty": {
|
"difficulty": {
|
||||||
|
|||||||
@@ -107,7 +107,10 @@
|
|||||||
"Triforce Hunt: Places 30 Triforce Pieces in the world, collect",
|
"Triforce Hunt: Places 30 Triforce Pieces in the world, collect",
|
||||||
" 20 of them to beat the game.",
|
" 20 of them to beat the game.",
|
||||||
"Trinity: Can beat the game by defeating Ganon, pulling",
|
"Trinity: Can beat the game by defeating Ganon, pulling",
|
||||||
" Pedestal, or delivering Triforce Pieces."
|
" Pedestal, or delivering Triforce Pieces.",
|
||||||
|
"Ganon Hunt: Places 30 Triforce Pieces in the world, collect",
|
||||||
|
" 20 of them then defeat Ganon.",
|
||||||
|
"Completionist: Find everything then defeat Ganon."
|
||||||
],
|
],
|
||||||
"difficulty": [
|
"difficulty": [
|
||||||
"Select game difficulty. Affects available itempool. (default: %(default)s)",
|
"Select game difficulty. Affects available itempool. (default: %(default)s)",
|
||||||
|
|||||||
@@ -248,6 +248,8 @@
|
|||||||
"randomizer.item.goal.triforcehunt": "Triforce Hunt",
|
"randomizer.item.goal.triforcehunt": "Triforce Hunt",
|
||||||
"randomizer.item.goal.trinity": "Trinity",
|
"randomizer.item.goal.trinity": "Trinity",
|
||||||
"randomizer.item.goal.crystals": "Crystals",
|
"randomizer.item.goal.crystals": "Crystals",
|
||||||
|
"randomizer.item.goal.ganonhunt": "Triforce Hunt + Ganon",
|
||||||
|
"randomizer.item.goal.completionist": "Completionist",
|
||||||
|
|
||||||
"randomizer.item.crystals_gt": "Crystals to open GT",
|
"randomizer.item.crystals_gt": "Crystals to open GT",
|
||||||
"randomizer.item.crystals_gt.0": "0",
|
"randomizer.item.crystals_gt.0": "0",
|
||||||
|
|||||||
@@ -36,7 +36,9 @@
|
|||||||
"dungeons",
|
"dungeons",
|
||||||
"triforcehunt",
|
"triforcehunt",
|
||||||
"trinity",
|
"trinity",
|
||||||
"crystals"
|
"crystals",
|
||||||
|
"ganonhunt",
|
||||||
|
"completionist"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"crystals_gt": {
|
"crystals_gt": {
|
||||||
|
|||||||
@@ -113,7 +113,9 @@ def roll_settings(weights):
|
|||||||
'dungeons': 'dungeons',
|
'dungeons': 'dungeons',
|
||||||
'pedestal': 'pedestal',
|
'pedestal': 'pedestal',
|
||||||
'triforce-hunt': 'triforcehunt',
|
'triforce-hunt': 'triforcehunt',
|
||||||
'trinity': 'trinity'
|
'trinity': 'trinity',
|
||||||
|
'ganonhunt': 'ganonhunt',
|
||||||
|
'completionist': 'completionist'
|
||||||
}[goal]
|
}[goal]
|
||||||
ret.openpyramid = goal in ['fast_ganon', 'trinity'] if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
ret.openpyramid = goal in ['fast_ganon', 'trinity'] if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user