1 Commits

Author SHA1 Message Date
7bab5b0434 Merge commit '3cb1e' 2026-05-04 00:41:59 -05:00
8 changed files with 33 additions and 89 deletions

View File

@@ -164,7 +164,6 @@ class World(object):
set_player_attr('bigkeyshuffle', 'none')
set_player_attr('prizeshuffle', 'none')
set_player_attr('showloot', 'never')
set_player_attr('loothud', 'never')
set_player_attr('showmap', 'map')
set_player_attr('restrict_boss_items', 'none')
set_player_attr('bombbag', False)
@@ -203,7 +202,6 @@ class World(object):
set_player_attr('damage_challenge', 'normal')
set_player_attr('shuffle_damage_table', 'vanilla')
set_player_attr('crystal_book', False)
set_player_attr('extra_keys', 0)
set_player_attr('collection_rate', False)
set_player_attr('colorizepots', True)
set_player_attr('pot_pool', {})
@@ -1980,7 +1978,6 @@ class Dungeon(object):
self.prize = None
self.big_key = big_key
self.small_keys = small_keys
self.extra_small_keys = 0
self.dungeon_items = dungeon_items
self.bosses = dict()
self.player = player
@@ -3157,7 +3154,6 @@ class Spoiler(object):
'bigkeyshuffle': self.world.bigkeyshuffle,
'prizeshuffle': self.world.prizeshuffle,
'showloot': self.world.showloot,
'loothud': self.world.loothud,
'showmap': self.world.showmap,
'boss_shuffle': self.world.boss_shuffle,
'enemy_shuffle': self.world.enemy_shuffle,
@@ -3178,7 +3174,6 @@ class Spoiler(object):
'damage_challenge': self.world.damage_challenge,
'shuffle_damage_table': self.world.shuffle_damage_table,
'crystal_book': self.world.crystal_book,
'extra_keys': self.world.extra_keys,
'triforcegoal': self.world.treasure_hunt_count,
'triforcepool': self.world.treasure_hunt_total,
'race': self.world.settings.world_rep['meta']['race'],
@@ -3186,8 +3181,6 @@ class Spoiler(object):
'code': {p: Settings.make_code(self.world, p) for p in range(1, self.world.players + 1)},
'seed': self.world.seed
}
if self.hashes:
self.metadata['hash'] = {p: self.hashes[p, 0] for p in range(1, self.world.players + 1)} # TODO: make this work for multiple teams
for p in range(1, self.world.players + 1):
from ItemList import set_default_triforce
@@ -3434,7 +3427,6 @@ class Spoiler(object):
outfile.write('Big Key Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['bigkeyshuffle'][player])
outfile.write('Prize Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['prizeshuffle'][player])
outfile.write('Show Value of Checks:'.ljust(line_width) + '%s\n' % self.metadata['showloot'][player])
outfile.write('Show Value of Checks on HUD:'.ljust(line_width) + '%s\n' % self.metadata['loothud'][player])
outfile.write('Show Map:'.ljust(line_width) + '%s\n' % self.metadata['showmap'][player])
outfile.write('Key Logic Algorithm:'.ljust(line_width) + '%s\n' % self.metadata['key_logic'][player])
outfile.write('\n')
@@ -3461,7 +3453,6 @@ class Spoiler(object):
outfile.write('Damage Challenge:'.ljust(line_width) + '%s\n' % self.metadata['damage_challenge'][player])
outfile.write('Damage Table Randomization:'.ljust(line_width) + '%s\n' % self.metadata['shuffle_damage_table'][player])
outfile.write('Crystal Book:'.ljust(line_width) + '%s\n' % yn(self.metadata['crystal_book'][player]))
outfile.write('Extra Keys:'.ljust(line_width) + '%d%%\n' % self.metadata['extra_keys'][player])
outfile.write('Hints:'.ljust(line_width) + '%s\n' % yn(self.metadata['hints'][player]))
outfile.write('Race:'.ljust(line_width) + '%s\n' % yn(self.world.settings.world_rep['meta']['race']))

53
CLI.py
View File

@@ -153,32 +153,31 @@ def parse_cli(argv, no_defaults=False):
'crystals_ganon', 'crystals_gt', 'bosses_ganon',
'bosshunt_include_agas', 'ganon_item', 'openpyramid',
'mapshuffle', 'compassshuffle', 'keyshuffle',
'bigkeyshuffle', 'prizeshuffle', 'showloot', 'loothud',
'showmap', 'startinventory', 'usestartinventory',
'bombbag', 'shuffleganon', 'overworld_map',
'restrict_boss_items', 'triforce_max_difference',
'triforce_pool_min', 'triforce_pool_max',
'triforce_goal_min', 'triforce_goal_max',
'triforce_min_difference', 'triforce_goal',
'triforce_pool', 'shufflelinks', 'shuffletavern',
'skullwoods', 'linked_drops', 'pseudoboots',
'mirrorscroll', 'dark_rooms', 'damage_challenge',
'shuffle_damage_table', 'crystal_book', 'extra_keys',
'retro', 'accessibility', 'hints', 'beemizer',
'experimental', 'dungeon_counters', 'shufflebosses',
'shuffleenemies', 'enemy_health', 'enemy_damage',
'shufflepots', 'ow_palettes', 'uw_palettes', 'sprite',
'triforce_gfx', 'disablemusic', 'quickswap', 'fastmenu',
'heartcolor', 'heartbeep', 'remote_items', 'shopsanity',
'dropshuffle', 'pottery', 'keydropshuffle',
'mixed_travel', 'standardize_palettes', 'code',
'reduce_flashing', 'shuffle_sfx',
'shuffle_sfxinstruments', 'shuffle_songinstruments',
'msu_resume', 'collection_rate', 'colorizepots',
'decoupledoors', 'door_type_mode', 'bonk_drops',
'trap_door_mode', 'key_logic_algorithm',
'door_self_loops', 'any_enemy_logic', 'aga_randomness',
'money_balance']:
'bigkeyshuffle', 'prizeshuffle', 'showloot', 'showmap',
'startinventory', 'usestartinventory', 'bombbag',
'shuffleganon', 'overworld_map', 'restrict_boss_items',
'triforce_max_difference', 'triforce_pool_min',
'triforce_pool_max', 'triforce_goal_min',
'triforce_goal_max', 'triforce_min_difference',
'triforce_goal', 'triforce_pool', 'shufflelinks',
'shuffletavern', 'skullwoods', 'linked_drops',
'pseudoboots', 'mirrorscroll', 'dark_rooms',
'damage_challenge', 'shuffle_damage_table',
'crystal_book', 'retro', 'accessibility', 'hints',
'beemizer', 'experimental', 'dungeon_counters',
'shufflebosses', 'shuffleenemies', 'enemy_health',
'enemy_damage', 'shufflepots', 'ow_palettes',
'uw_palettes', 'sprite', 'triforce_gfx', 'disablemusic',
'quickswap', 'fastmenu', 'heartcolor', 'heartbeep',
'remote_items', 'shopsanity', 'dropshuffle', 'pottery',
'keydropshuffle', 'mixed_travel',
'standardize_palettes', 'code', 'reduce_flashing',
'shuffle_sfx', 'shuffle_sfxinstruments',
'shuffle_songinstruments', 'msu_resume',
'collection_rate', 'colorizepots', 'decoupledoors',
'door_type_mode', 'bonk_drops', 'trap_door_mode',
'key_logic_algorithm', 'door_self_loops',
'any_enemy_logic', 'aga_randomness', 'money_balance']:
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
if player == 1:
setattr(ret, name, {1: value})
@@ -255,7 +254,6 @@ def parse_settings():
"damage_challenge": "normal",
"shuffle_damage_table": "vanilla",
"crystal_book": False,
"extra_keys": 0,
"shuffleenemies": "none",
"shufflebosses": "none",
@@ -275,7 +273,6 @@ def parse_settings():
"bigkeyshuffle": "none",
"prizeshuffle": "none",
"showloot": "never",
"loothud": "never",
"showmap": "map",
"keysanity": False,
"door_shuffle": "vanilla",

View File

@@ -3,7 +3,6 @@ import time
from collections import defaultdict, deque
from enum import Flag, unique
from itertools import chain
from math import ceil
from typing import DefaultDict, Dict, List
import RaceRandom as random
@@ -1600,11 +1599,7 @@ def assign_cross_keys(dungeon_builders, world, player):
if actual_chest_keys == 0:
dungeon.small_keys = []
else:
extra_keys = ceil(actual_chest_keys * world.extra_keys[player] / 100)
logger.debug(f'Adding {extra_keys} extra small keys to {name}')
dungeon.extra_small_keys = extra_keys
created_keys = actual_chest_keys + extra_keys
dungeon.small_keys = [ItemFactory(dungeon_keys[name], player)] * created_keys
dungeon.small_keys = [ItemFactory(dungeon_keys[name], player)] * actual_chest_keys
logger.info(f'{world.fish.translate("cli", "cli", "keydoor.shuffle.time.crossed")}: {time.process_time()-start}')
@@ -2176,10 +2171,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, all_
if actual_chest_keys == 0:
dungeon.small_keys = []
else:
extra_keys = ceil(actual_chest_keys * world.extra_keys[player] / 100)
dungeon.extra_small_keys = extra_keys
created_keys = actual_chest_keys + extra_keys
dungeon.small_keys = [ItemFactory(dungeon_keys[dungeon_name], player) for _ in range(created_keys)]
dungeon.small_keys = [ItemFactory(dungeon_keys[dungeon_name], player) for _ in range(actual_chest_keys)]
for name, small_list in small_map.items():
used_doors.update(flatten_pair_list(small_list))

View File

@@ -516,7 +516,6 @@ def init_world(args, fish):
world.bigkeyshuffle = args.bigkeyshuffle.copy()
world.prizeshuffle = args.prizeshuffle.copy()
world.showloot = args.showloot.copy()
world.loothud = args.loothud.copy()
world.showmap = args.showmap.copy()
world.bombbag = args.bombbag.copy()
world.flute_mode = args.flute_mode.copy()
@@ -565,7 +564,6 @@ def init_world(args, fish):
world.damage_challenge = args.damage_challenge.copy()
world.shuffle_damage_table = args.shuffle_damage_table.copy()
world.crystal_book = args.crystal_book.copy()
world.extra_keys = {player: int(args.extra_keys[player]) for player in range(1, world.players + 1)}
world.overworld_map = args.overworld_map.copy()
world.take_any = args.take_any.copy()
world.restrict_boss_items = args.restrict_boss_items.copy()
@@ -838,7 +836,6 @@ def copy_world(world):
ret.bigkeyshuffle = world.bigkeyshuffle.copy()
ret.prizeshuffle = world.prizeshuffle.copy()
ret.showloot = world.showloot.copy()
ret.loothud = world.loothud.copy()
ret.showmap = world.showmap.copy()
ret.bombbag = world.bombbag.copy()
ret.flute_mode = world.flute_mode.copy()
@@ -871,7 +868,6 @@ def copy_world(world):
ret.damage_challenge = world.damage_challenge.copy()
ret.shuffle_damage_table = world.shuffle_damage_table.copy()
ret.crystal_book = world.crystal_book.copy()
ret.extra_keys = world.extra_keys.copy()
ret.overworld_map = world.overworld_map.copy()
ret.take_any = world.take_any.copy()
ret.boss_shuffle = world.boss_shuffle.copy()
@@ -1072,7 +1068,6 @@ def copy_world_premature(world, player, create_flute_exits=True):
ret.bigkeyshuffle = world.bigkeyshuffle.copy()
ret.prizeshuffle = world.prizeshuffle.copy()
ret.showloot = world.showloot.copy()
ret.loothud = world.loothud.copy()
ret.showmap = world.showmap.copy()
ret.bombbag = world.bombbag.copy()
ret.flute_mode = world.flute_mode.copy()
@@ -1105,7 +1100,6 @@ def copy_world_premature(world, player, create_flute_exits=True):
ret.damage_challenge = world.damage_challenge.copy()
ret.shuffle_damage_table = world.shuffle_damage_table.copy()
ret.crystal_book = world.crystal_book.copy()
ret.extra_keys = world.extra_keys.copy()
ret.overworld_map = world.overworld_map.copy()
ret.take_any = world.take_any.copy()
ret.boss_shuffle = world.boss_shuffle.copy()

30
Rom.py
View File

@@ -85,7 +85,7 @@ from Utils import int16_as_bytes, int32_as_bytes, local_path, snes_to_pc
from Versions import DRVersion, GKVersion, ORVersion
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = 'beae4c06c4841030709639215e2b03c3'
RANDOMIZERBASEHASH = '8945e9fdcefc02eb3ff3ad2a8892a180'
class JsonRom(object):
@@ -818,13 +818,11 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
rom.write_byte(0x138002, 2)
for name, layout in world.key_layout[player].items():
offset = compass_data[name][4]//2
dungeon = world.get_dungeon(name, player)
if world.keyshuffle[player] == 'universal':
rom.write_byte(0x187010+offset, layout.max_chests + layout.max_drops)
else:
rom.write_byte(0x13f020+offset, layout.max_chests + layout.max_drops + dungeon.extra_small_keys) # not currently used
rom.write_byte(0x187010+offset, layout.max_chests + dungeon.extra_small_keys)
rom.write_byte(0x187000+offset, dungeon.extra_small_keys)
rom.write_byte(0x13f020+offset, layout.max_chests + layout.max_drops) # not currently used
rom.write_byte(0x187010+offset, layout.max_chests)
builder = world.dungeon_layouts[player][name]
bk_status = 1 if builder.bk_required else 0
bk_status = 2 if builder.bk_provided else bk_status
@@ -1503,22 +1501,9 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
loot_source |= 0x04
rom.write_byte(0x1CFF10, loot_source)
if world.loothud[player] == 'never':
rom.write_byte(0x1CFF12, 0x00)
elif world.showloot[player] == 'presence':
rom.write_byte(0x1CFF12, 0x01)
rom.write_bytes(0x1CFF0E, [0x01, 0x01])
elif world.showloot[player] == 'value':
rom.write_byte(0x1CFF12, 0x01)
rom.write_bytes(0x1CFF0E, [0xFF, 0xFF])
elif world.showloot[player] == 'dungeon_value':
rom.write_byte(0x1CFF12, 0x01)
rom.write_bytes(0x1CFF0E, [0xFF, 0x01])
if world.showloot[player] == 'never':
rom.write_bytes(0x1CFF08, [0x00, 0x00, 0x00, 0x00])
rom.write_byte(0x1CFF11, 0x00)
rom.write_byte(0x1CFF12, 0x00) # turn off hud icon too just to be safe
elif world.showloot[player] == 'presence':
rom.write_bytes(0x1CFF08, [0x01, 0x00, 0x00, 0x00])
rom.write_byte(0x1CFF11, 0x00)
@@ -3541,10 +3526,7 @@ Prizes = ['Green Pendant',
]
hash_alphabet = [
"Bow", "Boomerang", "Hookshot", "Bomb", "Mushroom", "Powder",
"Ice Rod", "Green Pendant", "Bombos", "Ether", "Quake", "Lamp",
"Hammer", "Shovel", "Ocarina", "Bug Net", "Book", "Bottle",
"Green Potion", "Somaria", "Cape", "Mirror", "Boots", "Gloves",
"Flippers", "Pearl", "Shield", "Green Tunic", "Heart", "Map",
"Compass", "Key",
"Bow", "Boomerang", "Hookshot", "Bomb", "Mushroom", "Powder", "Rod", "Pendant", "Bombos", "Ether", "Quake",
"Lamp", "Hammer", "Shovel", "Ocarina", "Bug Net", "Book", "Bottle", "Potion", "Cane", "Cape", "Mirror", "Boots",
"Gloves", "Flippers", "Pearl", "Shield", "Tunic", "Heart", "Map", "Compass", "Key"
]

Binary file not shown.

View File

@@ -486,14 +486,6 @@
"always"
]
},
"loothud": {
"choices": [
"never",
"presence",
"value",
"dungeon_value"
]
},
"showmap": {
"choices": [
"visited",
@@ -673,9 +665,6 @@
"action": "store_true",
"type": "bool"
},
"extra_keys": {
"type": "int"
},
"calc_playthrough": {
"action": "store_false",
"type": "bool"

View File

@@ -425,7 +425,6 @@
"AlwaysInLogic: Dark rooms are always considered to be in logic, even if the player cannot see"
],
"crystal_book": [ " Book can be used indoors to flip the state of colored pegs (default: %(default)s)"],
"extra_keys": [ " Percentage of extra small keys to create for each dungeon when door shuffle is enabled (default: %(default)s)"],
"bombbag": ["Start with 0 bomb capacity. Two capacity upgrades (+10) are added to the pool (default: %(default)s)" ],
"any_enemy_logic": [
"How to handle potential traversal between dungeon in Crossed door shuffle",