Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion worlds/tww/Macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,11 @@ def can_reach_wind_temple_tall_basement_room(state: CollectionState, player: int


def can_access_dungeon_entrance_on_dragon_roost_island(state: CollectionState, player: int) -> bool:
return True
return state._tww_open_drc(player) or (
can_move_boulders(state, player)
or can_fly_with_deku_leaf_outdoors(state, player)
or state.has("Empty Bottle", player, 1)
)


def can_access_forest_haven(state: CollectionState, player: int) -> bool:
Expand Down
12 changes: 12 additions & 0 deletions worlds/tww/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,14 @@ class EnableTunerLogic(Toggle):
display_name = "Enable Tuner Logic"


class OpenDRC(Toggle):
"""
If enabled, the boulder in front of the DRC entrance will be removed and the location will be accessible with no items
"""

display_name = "Open DRC Entrance"


class RandomizeDungeonEntrances(Toggle):
"""
Shuffles around which dungeon entrances take you into which dungeons.
Expand Down Expand Up @@ -727,6 +735,7 @@ class TWWOptions(PerGameCommonOptions):
hero_mode: HeroMode
logic_obscurity: LogicObscurity
logic_precision: LogicPrecision
open_drc: OpenDRC
enable_tuner_logic: EnableTunerLogic
randomize_dungeon_entrances: RandomizeDungeonEntrances
randomize_secret_cave_entrances: RandomizeSecretCavesEntrances
Expand Down Expand Up @@ -791,6 +800,7 @@ def get_slot_data_dict(self) -> dict[str, Any]:
"logic_obscurity",
"logic_precision",
"enable_tuner_logic",
"open_drc",
"randomize_dungeon_entrances",
"randomize_secret_cave_entrances",
"randomize_miniboss_entrances",
Expand Down Expand Up @@ -847,6 +857,7 @@ def get_output_dict(self) -> dict[str, Any]:
"hero_mode",
"logic_obscurity",
"logic_precision",
"open_drc",
"randomize_dungeon_entrances",
"randomize_secret_cave_entrances",
"randomize_miniboss_entrances",
Expand Down Expand Up @@ -916,6 +927,7 @@ def get_output_dict(self) -> dict[str, Any]:
RandomizeSecretCaveInnerEntrances,
RandomizeFairyFountainEntrances,
MixEntrances,
OpenDRC,
],
),
OptionGroup(
Expand Down
3 changes: 3 additions & 0 deletions worlds/tww/Rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def _tww_precise_3(self, player: int) -> bool:

def _tww_tuner_logic_enabled(self, player: int) -> bool:
return self.multiworld.worlds[player].logic_tuner_logic_enabled

def _tww_open_drc(self, player: int) -> bool:
return self.multiworld.worlds[player].logic_open_drc


def set_rules(world: "TWWWorld") -> None: # noqa: F405
Expand Down
16 changes: 13 additions & 3 deletions worlds/tww/TWWClient.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import os.path
import time
import traceback
from typing import TYPE_CHECKING, Any, Optional
Expand Down Expand Up @@ -29,6 +30,15 @@
CONNECTION_INITIAL_STATUS = "Dolphin connection has not been initiated."


def load_custom_symbols(filename: str) -> dict[str, int]:
"""Loads asm offsets from a custom_symbols.txt file generated by the Wind Waker Randomizer program"""
with open(filename) as stream:
symbols = Utils.parse_yaml(stream)
return symbols["sys/main.dol"]


CUSTOM_SYMBOLS = load_custom_symbols(os.path.join(os.path.dirname(__file__), "custom_symbols.txt"))

# This address is used to check/set the player's health for DeathLink.
CURR_HEALTH_ADDR = 0x803C4C0A

Expand Down Expand Up @@ -60,17 +70,17 @@

# This address contains the byte used to give the player an item.
# 0xFF represents no item. The byte is read and cleared every frame.
GIVE_ITEM_BYTE_ADDR = 0x803FE868
GIVE_ITEM_BYTE_ADDR = CUSTOM_SYMBOLS["give_archipelago_item_byte"]

# This is the address that holds the player's slot name.
# This way, the player does not have to manually authenticate their slot name.
SLOT_NAME_ADDR = 0x803FE880
SLOT_NAME_ADDR = CUSTOM_SYMBOLS["archipelago_slot_name"]

# This address is the start of an array that we use to inform us of which charts lead where.
# The array is of length 49, and each element is two bytes. The index represents the chart's original destination, and
# the value represents the new destination.
# The chart name is inferrable from the chart's original destination.
CHARTS_MAPPING_ADDR = 0x803FE8C0
CHARTS_MAPPING_ADDR = CUSTOM_SYMBOLS["archipelago_charts_mapping"]

# This address contains the most recent spawn ID from which the player spawned.
MOST_RECENT_SPAWN_ID_ADDR = 0x803C9D44
Expand Down
1 change: 1 addition & 0 deletions worlds/tww/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ def generate_early(self) -> None:
self.logic_precise_2 = self.logic_precise_3 or options.logic_precision == "hard"
self.logic_precise_1 = self.logic_precise_2 or options.logic_precision == "normal"
self.logic_tuner_logic_enabled = bool(options.enable_tuner_logic.value)
self.logic_open_drc = bool(options.open_drc)

# Determine any item classification overrides based on user options.
self._determine_item_classification_overrides()
Expand Down
200 changes: 200 additions & 0 deletions worlds/tww/custom_symbols.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
sys/main.dol:
hurricane_spin_item_resource_arc_name: 0x803FCFA8
ballad_of_gales_warp_table: 0x803FCFB0
ballad_of_gales_warp_float_bank: 0x803FCFF8
custom_DynamicNameTable: 0x803FD050
custom_l_objectName: 0x803FD084
custom_l_objectName_end: 0x803FD09C
custom_DMC: 0x803FD09C
init_save_with_tweaks: 0x803FD87C
init_starting_gear: 0x803FDC34
num_triforce_shards_to_start_with: 0x803FDC7C
should_start_with_heros_clothes: 0x803FDC7D
sword_mode: 0x803FDC7E
skip_rematch_bosses: 0x803FDC7F
starting_gear: 0x803FDC80
starting_quarter_hearts: 0x803FDCD8
starting_magic: 0x803FDCDA
captured_prologue_pigs_bitfield: 0x803FDCDB
option_targeting_mode: 0x803FDCDC
open_drc: 0x803FDCDD
convert_progressive_item_id: 0x803FDCE0
progressive_sword_item_func: 0x803FDF70
progressive_shield_item_func: 0x803FDFD8
progressive_bow_func: 0x803FE020
progressive_wallet_item_func: 0x803FE078
progressive_bomb_bag_item_func: 0x803FE0B0
progressive_quiver_item_func: 0x803FE0F0
progressive_picto_box_item_func: 0x803FE130
magic_meter_item_func: 0x803FE178
magic_meter_upgrade_item_func: 0x803FE198
normal_magic_meter_item_func: 0x803FE1B8
hurricane_spin_item_func: 0x803FE1D0
custom_createItem: 0x803FE1FC
generic_on_dungeon_bit: 0x803FE248
generic_small_key_item_get_func: 0x803FE2A4
drc_small_key_item_get_func: 0x803FE33C
fw_small_key_item_get_func: 0x803FE360
totg_small_key_item_get_func: 0x803FE384
et_small_key_item_get_func: 0x803FE3A8
wt_small_key_item_get_func: 0x803FE3CC
drc_big_key_item_get_func: 0x803FE3F0
fw_big_key_item_get_func: 0x803FE418
totg_big_key_item_get_func: 0x803FE440
et_big_key_item_get_func: 0x803FE468
wt_big_key_item_get_func: 0x803FE490
drc_dungeon_map_item_get_func: 0x803FE4B8
fw_dungeon_map_item_get_func: 0x803FE4E0
totg_dungeon_map_item_get_func: 0x803FE508
ff_dungeon_map_item_get_func: 0x803FE530
et_dungeon_map_item_get_func: 0x803FE558
wt_dungeon_map_item_get_func: 0x803FE580
drc_compass_item_get_func: 0x803FE5A8
fw_compass_item_get_func: 0x803FE5D0
totg_compass_item_get_func: 0x803FE5F8
ff_compass_item_get_func: 0x803FE620
et_compass_item_get_func: 0x803FE648
wt_compass_item_get_func: 0x803FE670
dragon_tingle_statue_item_get_func: 0x803FE698
forbidden_tingle_statue_item_get_func: 0x803FE6C4
goddess_tingle_statue_item_get_func: 0x803FE6F0
earth_tingle_statue_item_get_func: 0x803FE71C
wind_tingle_statue_item_get_func: 0x803FE748
check_tingle_statue_owned: 0x803FE774
custom_isTbox_for_unloaded_stage_save_info: 0x803FE7FC
give_archipelago_item: 0x803FE82C
give_archipelago_item_byte: 0x803FE87C
modify_triforce_count: 0x803FE880
archipelago_slot_name: 0x803FE894
archipelago_charts_mapping: 0x803FE8D4
hookshot_sight_failsafe_check: 0x803FE938
deluxe_picto_box_item_func_fix_equipped_picto_box: 0x803FE950
stop_sub_bgm_when_unloading_stage: 0x803FE984
zero_out_arrow_on_hit_callback: 0x803FE99C
check_can_defend: 0x803FE9AC
check_ganondorf_in_phase_3: 0x803FE9DC
check_play_special_item_get_music: 0x803FE9F8
multiply_damage_amount: 0x803FEA60
damage_multiplier: 0x803FEA84
invert_camera_horizontal_axis: 0x803FEA88
convert_progressive_item_id_for_createDemoItem: 0x803FEA94
convert_progressive_item_id_for_daItem_create: 0x803FEAC0
convert_progressive_item_id_for_dProcGetItem_init_1: 0x803FEAEC
convert_progressive_item_id_for_dProcGetItem_init_2: 0x803FEB14
check_open_map_select: 0x803FEB3C
set_starting_health: 0x803FEB9C
get_current_health_for_file_select_screen: 0x803FEBB8
get_max_health_for_file_select_screen: 0x803FEBE0
fully_refill_magic_meter_and_cap_health_on_load_save: 0x803FEC04
turn_while_swinging: 0x803FEC34
check_animate_rainbow_rupee_color: 0x803FEC94
rainbow_rupee_keyframe: 0x803FECD4
check_run_new_text_commands: 0x803FECE4
exec_curr_num_keys_text_command: 0x803FED24
set_warp_confirm_dialog_message_id_for_custom_warps: 0x803FEE04
check_player_in_casual_clothes: 0x803FEE1C
read_custom_DynamicNameTable_loop: 0x803FEE58
read_custom_l_objectName_loop_for_dStage_searchName: 0x803FEE84
read_custom_l_objectName_loop_for_dStage_getName: 0x803FEEAC
get_num_owned_tingle_statues: 0x803FEED8
ladder_up_check_unequip_held_item: 0x803FEF4C
ladder_down_check_unequip_held_item: 0x803FEF64
gameover_continue_reset_life: 0x803FEF7C
give_pearl_and_raise_totg_if_necessary: 0x803FEF98
remove_low_health_anim_at_full_health: 0x803FF02C
give_temporary_sword_during_ganondorf_fight_in_swordless: 0x803FF050
give_temporary_sword_in_orcas_house_in_swordless: 0x803FF06C
remove_temporary_sword_when_loading_stage_in_swordless: 0x803FF0B4
test_room_stage_name: 0x8022D034
test_room_starting_items_list: 0x8022D03C
test_room_spawn_id: 0x800531E3
test_room_room_index: 0x800531E7
test_room_override_layer_num: 0x800531EB
files/rels/d_a_demo_item.rel:
check_give_item: 0x1344
files/rels/d_a_npc_bs1.rel:
set_shop_item_in_bait_bag_slot_sold_out: 0x61F0
check_shop_item_in_bait_bag_slot_sold_out: 0x6220
custom_getSelectItemNo_progressive: 0x624C
files/rels/d_a_st.rel:
stalfos_kill_lower_body_when_upper_body_light_arrowed: 0xA778
stalfos_set_death_switch: 0xA7C0
files/rels/d_a_pt.rel:
miniblin_set_death_switch_when_light_arrowed: 0x60BC
files/rels/d_a_pw.rel:
poe_fix_light_arrows_bug: 0x7FB4
files/rels/d_a_mt.rel:
magtail_respawn_when_head_light_arrowed: 0xA04C
files/rels/d_a_fganon.rel:
phantom_ganon_check_link_within_y_diff: 0xB020
check_ganons_tower_chest_opened: 0xB03C
files/rels/d_a_bdk.rel:
initialize_helmaroc_king_landing_timer: 0xEA88
check_helmaroc_king_landing_timeout: 0xEA98
files/rels/d_a_boko.rel:
check_phantom_ganons_sword_should_disappear: 0x4B88
phantom_ganon_maze_stage_name: 0x4BC4
files/rels/d_a_rd.rel:
redead_check_disable_spawn_switch: 0x61E4
redead_set_death_switch: 0x6224
files/rels/d_a_ph.rel:
peahat_check_disable_spawn_switch: 0x7F70
peahat_set_death_switch: 0x7FB8
peahat_check_enable_spawn_switch: 0x7FE4
peahat_check_enable_spawn_switch_for_draw: 0x803C
files/rels/d_a_mo2.rel:
moblin_set_death_switch: 0xE2D4
files/rels/d_a_tn.rel:
darknut_set_death_switch: 0xEA24
files/rels/d_a_nzg.rel:
rat_hole_all_rats_dead: 0xE00
files/rels/d_a_obj_ftree.rel:
create_item_for_withered_trees_without_setting_speeds: 0x535C
withered_tree_item_try_give_momentum: 0x5384
withered_tree_item_speeds: 0x53F8
files/rels/d_a_npc_people.rel:
create_item_and_set_event_bit_for_townsperson: 0xCF18
files/rels/d_a_npc_photo.rel:
lenzo_set_deluxe_picto_box_event_bit: 0x5EC8
files/rels/d_a_npc_rsh1.rel:
zunari_give_item_and_set_magic_armor_event_bit: 0x5D18
zunari_magic_armor_slot_item_id: 0x5D70
files/rels/d_a_npc_sv.rel:
salvage_corp_give_item_and_set_event_bit: 0x3580
files/rels/d_a_npc_kp1.rel:
maggie_give_item_and_set_event_bit: 0x338C
files/rels/d_a_npc_bm1.rel:
rito_cafe_postman_start_event_and_set_event_bit: 0xAFD0
files/rels/d_a_npc_ds1.rel:
doc_bandam_check_new_potion_and_give_free_item: 0x60F8
doc_bandam_green_potion_slot_item_id: 0x6154
doc_bandam_blue_potion_slot_item_id: 0x6155
files/rels/d_a_tsubo.rel:
create_pot_item: 0x9964
files/rels/d_a_obj_homen.rel:
create_stone_head_item: 0x36DC
files/rels/d_a_ship.rel:
set_wind_dir_to_ship_dir: 0xE3A8
slow_down_ship_when_stopping: 0xE3F0
ship_stopping_deceleration: 0xE420
slow_down_ship_when_idle: 0xE428
ship_idle_deceleration: 0xE458
files/rels/d_a_npc_md.rel:
reset_medli_position: 0x15D78
medli_possible_et_spawn_positions: 0x15E50
files/rels/d_a_npc_cb1.rel:
reset_makar_position: 0xB214
makar_possible_wt_spawn_positions: 0xB2EC
files/rels/d_a_warpdm20.rel:
check_hyrule_warp_unlocked: 0x1EBC
files/rels/d_a_npc_os.rel:
set_inactive_servant_when_player_leaves_room: 0x8AB4
files/rels/d_a_obj_hsehi1.rel:
set_item_obtained_from_totg_tablet_event_bit: 0x29D0
files/rels/d_a_shop_item.rel:
convert_progressive_item_id_for_shop_item: 0x1174
files/rels/d_a_obj_warpt.rel:
set_prm_color_for_warp_pot_particles: 0x3280
set_env_color_for_warp_pot_particles: 0x32A8
custom_warp_pot_prm_color: 0x32D0
custom_warp_pot_env_color: 0x32D4