Skip to content

Commit

Permalink
Merge 'Add option to give Boss Keys when collecting Key Rings' (OoTRa…
Browse files Browse the repository at this point in the history
  • Loading branch information
cjohnson57 committed Jan 7, 2023
2 parents 8b3256e + 2bd4ca3 commit 41ebdb8
Show file tree
Hide file tree
Showing 20 changed files with 14,209 additions and 14,067 deletions.
634 changes: 318 additions & 316 deletions ASM/build/asm_symbols.txt

Large diffs are not rendered by default.

Binary file modified ASM/build/bundle.o
Binary file not shown.
243 changes: 122 additions & 121 deletions ASM/build/c_symbols.txt

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions ASM/c/item_effects.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,12 @@ void give_small_key(z64_file_t *save, int16_t dungeon_id, int16_t arg2) {
save->scene_flags[dungeon_id].unk_00_ = (flag & 0x0000ffff) | ((total_keys + 1) << 0x10);
}

uint8_t KEYRING_BOSSKEY_CONDITION = 0;
void give_small_key_ring(z64_file_t *save, int16_t dungeon_id, int16_t arg2) {
int8_t current_keys = save->dungeon_keys[dungeon_id] > 0 ? save->dungeon_keys[dungeon_id] : 0;
save->dungeon_keys[dungeon_id] = current_keys + key_counts[dungeon_id][CFG_DUNGEON_IS_MQ[dungeon_id]];
if (KEYRING_BOSSKEY_CONDITION && dungeon_id > 2 && dungeon_id < 8)
save->dungeon_items[dungeon_id].boss_key = 1;
uint32_t flag = save->scene_flags[dungeon_id].unk_00_;
int8_t total_keys = flag >> 0x10;
save->scene_flags[dungeon_id].unk_00_ = (flag & 0x0000ffff) | ((total_keys + key_counts[dungeon_id][CFG_DUNGEON_IS_MQ[dungeon_id]]) << 0x10);
Expand Down
15 changes: 10 additions & 5 deletions ItemPool.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,8 @@ def get_pool_core(world):
pending_junk_pool.append(f"Small Key ({dungeon})")
if world.settings.shuffle_bosskeys in ['any_dungeon', 'overworld', 'keysanity', 'regional']:
for dungeon in ['Forest Temple', 'Fire Temple', 'Water Temple', 'Shadow Temple', 'Spirit Temple']:
pending_junk_pool.append(f"Boss Key ({dungeon})")
if not world.settings.keyring_give_bk or dungeon not in world.settings.key_rings or world.settings.shuffle_smallkeys not in ['any_dungeon', 'overworld', 'keysanity', 'regional']:
pending_junk_pool.append(f"Boss Key ({dungeon})")
if world.settings.shuffle_ganon_bosskey in ['any_dungeon', 'overworld', 'keysanity', 'regional']:
pending_junk_pool.append('Boss Key (Ganons Castle)')
if world.settings.shuffle_song_items == 'any':
Expand Down Expand Up @@ -572,10 +573,14 @@ def get_pool_core(world):

# Boss Key
if location.vanilla_item == dungeon.item_name("Boss Key"):
shuffle_setting = world.settings.shuffle_bosskeys if dungeon.name != 'Ganons Castle' else world.settings.shuffle_ganon_bosskey
dungeon_collection = dungeon.boss_key
if shuffle_setting == 'vanilla':
shuffle_item = False
if world.settings.shuffle_smallkeys in ['any_dungeon', 'overworld', 'keysanity', 'regional'] and dungeon.name in world.settings.key_rings and world.settings.keyring_give_bk and dungeon.name in ['Forest Temple', 'Fire Temple', 'Water Temple', 'Shadow Temple', 'Spirit Temple']:
item = get_junk_item()[0]
shuffle_item = True
else:
shuffle_setting = world.settings.shuffle_bosskeys if dungeon.name != 'Ganons Castle' else world.settings.shuffle_ganon_bosskey
dungeon_collection = dungeon.boss_key
if shuffle_setting == 'vanilla':
shuffle_item = False
# Map or Compass
elif location.vanilla_item in [dungeon.item_name("Map"), dungeon.item_name("Compass")]:
shuffle_setting = world.settings.shuffle_mapcompass
Expand Down
5 changes: 5 additions & 0 deletions Patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,11 @@ def set_entrance_updates(entrances):
rom.write_byte(symbol, 0)
rom.write_int16(count_symbol, 0)

# Set Boss Key collection in Key Ring.
symbol = rom.sym('KEYRING_BOSSKEY_CONDITION')
if world.settings.keyring_give_bk:
rom.write_byte(symbol, 1)

# Set up LACS conditions.
symbol = rom.sym('LACS_CONDITION')
count_symbol = rom.sym('LACS_CONDITION_COUNT')
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ issue. You should always Hard Reset to avoid this issue entirely.
### Dev

#### New Features
* **Settings**
* New setting `Key Rings give Boss Keys` makes it so when picking up a key ring for a certain dungeon, you will also get the boss key for that dungeon, if applicable.
* **Hints**
* New `Important Checks` hint type which hints at how many major items are in a given region.

Expand Down
9 changes: 9 additions & 0 deletions SaveContext.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,15 @@ def give_item(self, world, item, count=1):
'total_keys.gc': 3 if world.dungeon_mq[dungeon] else 2,
},
}[dungeon]
if world.settings.keyring_give_bk:
bk_names = {
"Forest Temple": 'dungeon_items.forest.boss_key',
"Fire Temple": 'dungeon_items.fire.boss_key',
"Water Temple": 'dungeon_items.water.boss_key',
"Spirit Temple": 'dungeon_items.spirit.boss_key',
"Shadow Temple": 'dungeon_items.shadow.boss_key'
}
save_writes[dungeon][bk_names[dungeon]] = True
else:
save_writes = SaveContext.save_writes_table[item]
for address, value in save_writes.items():
Expand Down
17 changes: 16 additions & 1 deletion SettingsList.py
Original file line number Diff line number Diff line change
Expand Up @@ -3033,7 +3033,7 @@ def __init__(self, name, gui_text, min, max, default, step=1,
''',
shared = True,
disable={
'off': {'settings' : ['key_rings']},
'off': {'settings' : ['key_rings', 'keyring_give_bk']},
'all': {'settings' : ['key_rings']},
'random': {'settings' : ['key_rings']},
},
Expand Down Expand Up @@ -3062,6 +3062,21 @@ def __init__(self, name, gui_text, min, max, default, step=1,
''',
shared = True,
),
Checkbutton(
name = 'keyring_give_bk',
gui_text = 'Key Rings give Boss Keys',
gui_tooltip = '''\
Boss Keys will be included in the Key Ring for the specific dungeon.
''',
default = False,
shared = True,
gui_params = {
"hide_when_disabled": True,
},
disable={
True: {'settings' : ['shuffle_bosskeys']},
},
),
Combobox(
name = 'shuffle_mapcompass',
gui_text = 'Maps & Compasses',
Expand Down
8 changes: 8 additions & 0 deletions State.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ def guarantee_hint(self):
# Be careful using this function. It will not collect any
# items that may be locked behind the item, only the item itself.
def collect(self, item):
if 'Small Key Ring' in item.name and self.world.settings.keyring_give_bk:
dungeon_name = item.name[:-1].split(' (', 1)[1]
if dungeon_name in ['Forest Temple', 'Fire Temple', 'Water Temple', 'Shadow Temple', 'Spirit Temple']:
self.prog_items[f'Boss Key ({dungeon_name})'] = True
if item.alias:
self.prog_items[item.alias[0]] += item.alias[1]
if item.advancement:
Expand All @@ -153,6 +157,10 @@ def collect(self, item):
# Be careful using this function. It will not uncollect any
# items that may be locked behind the item, only the item itself.
def remove(self, item):
if 'Small Key Ring' in item.name and self.world.settings.keyring_give_bk:
dungeon_name = item.name[:-1].split(' (', 1)[1]
if dungeon_name in ['Forest Temple', 'Fire Temple', 'Water Temple', 'Shadow Temple', 'Spirit Temple']:
self.prog_items[f'Boss Key ({dungeon_name})'] = False
if item.alias and self.prog_items[item.alias[0]] > 0:
self.prog_items[item.alias[0]] -= item.alias[1]
if self.prog_items[item.alias[0]] <= 0:
Expand Down
20 changes: 20 additions & 0 deletions Unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,26 @@ def test_weird_egg_in_pool(self):

def test_key_rings(self):
# Checking dungeon keys using forest temple
# Testing Boss Keys, should not be any Forest BK
# All other Boss Keys should exist, Fire Temple for example
distribution_file, spoiler = generate_with_plandomizer("plando-keyrings-bosskey-forest-anywhere-minimal")
self.assertNotIn('Boss Key (Forest Temple)', spoiler['locations'].values())
self.assertEqual(get_actual_pool(spoiler)['Boss Key (Fire Temple)'], 1)
distribution_file, spoiler = generate_with_plandomizer("plando-keyrings-bosskey-forest-anywhere-balanced")
self.assertNotIn('Boss Key (Forest Temple)', spoiler['locations'].values())
self.assertEqual(get_actual_pool(spoiler)['Boss Key (Fire Temple)'], 1)
# Shuffle Keys set to Vanilla, Boss Keys should exist
distribution_file, spoiler = generate_with_plandomizer("plando-keyrings-bosskey-forest-vanilla-plentiful")
self.assertEqual(get_actual_pool(spoiler)['Boss Key (Forest Temple)'], 1)

# No key rings: Make sure boss key in plentiful
distribution_file, spoiler = generate_with_plandomizer("plando-keyrings-bosskey-none-anywhere-plentiful")
self.assertEqual(get_actual_pool(spoiler)['Boss Key (Forest Temple)'], 1)

# No key rings: Make sure boss key in ludicrous
distribution_file, spoiler = generate_with_plandomizer("plando-keyrings-bosskey-none-anywhere-ludicrous")
self.assertEqual(get_actual_pool(spoiler)['Boss Key (Forest Temple)'], 1)

# Minimal and balanced pools: Should be one key ring
distribution_file, spoiler = generate_with_plandomizer("plando-keyrings-forest-anywhere-minimal")
self.assertNotIn('Small Key (Forest Temple)', spoiler['locations'].values())
Expand Down
Loading

0 comments on commit 41ebdb8

Please sign in to comment.