Skip to content

Commit

Permalink
Merge branch 'shuffle-ganon-tower' into dev-fenhl
Browse files Browse the repository at this point in the history
# Conflicts:
#	ASM/build/asm_symbols.txt
#	ASM/build/bundle.o
#	ASM/build/c_symbols.txt
#	EntranceShuffle.py
#	HintList.py
#	ItemPool.py
#	SettingsList.py
#	Spoiler.py
#	World.py
#	data/World/Ganons Castle MQ.json
#	data/World/Ganons Castle.json
#	data/generated/rom_patch.txt
#	data/generated/symbols.json
#	data/presets_default.json
  • Loading branch information
fenhl committed Sep 13, 2024
2 parents 0ce15a8 + 067f5e2 commit 0e63a65
Show file tree
Hide file tree
Showing 16 changed files with 41,065 additions and 40,757 deletions.
2,896 changes: 1,449 additions & 1,447 deletions ASM/build/asm_symbols.txt

Large diffs are not rendered by default.

Binary file modified ASM/build/bundle.o
Binary file not shown.
1,385 changes: 693 additions & 692 deletions ASM/build/c_symbols.txt

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions ASM/c/blue_warp.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

#define TEXT_STATE_CLOSING 2

#define SCENE_VOLVAGIA_BOSS_ROOM 0x0015
#define SCENE_MORPHA_BOSS_ROOM 0x0016

extern uint8_t PLAYER_ID;
extern uint8_t PLAYER_NAME_ID;
extern bool REWARDS_AS_ITEMS;
Expand Down Expand Up @@ -43,13 +46,13 @@ int32_t DoorWarp1_PlayerInRange_Overwrite(z64_actor_t* actor, z64_game_t* game)
extended_savectx.collected_dungeon_rewards[boss_idx] = true;
}
// set time of day each time the blue warp is taken to reduce nonrepeatable access
if (boss_idx == 5) { // Morpha
if (game->scene_index == SCENE_MORPHA_BOSS_ROOM) {
z64_file.skybox_time = z64_file.day_time = 0x4800; // CLOCK_TIME(6, 45)
} else {
z64_file.skybox_time = z64_file.day_time = 0x8000; // CLOCK_TIME(12, 00)
}
// reset heat timer after Volvagia
if (boss_idx == 4) {
if (game->scene_index == SCENE_VOLVAGIA_BOSS_ROOM) {
z64_file.timer_1_state = 0;
}
// immediately activate the blue warp. Queued item will be given after the warp
Expand Down
47 changes: 41 additions & 6 deletions ASM/c/dungeon_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ extern uint8_t CFG_DUNGEON_REWARD_WORLDS[9];

extern uint8_t CFG_DUNGEON_INFO_SILVER_RUPEES;

extern int8_t CFG_DUNGEON_PRECOMPLETED[14];

extern extended_savecontext_static_t extended_savectx;
extern silver_rupee_data_t silver_rupee_vars[0x16][2];

Expand Down Expand Up @@ -220,7 +222,7 @@ void draw_dungeon_info(z64_disp_buf_t* db) {
int bg_left = (Z64_SCREEN_WIDTH - bg_width) / 2;
int bg_top = (Z64_SCREEN_HEIGHT - bg_height) / 2;

int left = bg_left + padding;
uint16_t left = bg_left + padding;
int start_top = bg_top + padding;

// Draw background
Expand Down Expand Up @@ -296,12 +298,29 @@ void draw_dungeon_info(z64_disp_buf_t* db) {

left += icon_size + padding;

// Draw dungeon names

// Draw the list of dungeons.
// Pre completed dungeons are grayed and crossed out.
for (int i = 0; i < rows; i++) {
gDPPipeSync(db->p++);
dungeon_entry_t* d = &(dungeons[i]);
bool empty = CFG_DUNGEON_PRECOMPLETED[d->index];
int top = start_top + ((icon_size + padding) * i) + 1;
text_print_size(db, d->name, left, top, font_width, font_height);
if (empty) {
gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0x7F);
uint16_t sizeRectangle = text_print_size(db, d->name, left, top, font_width, font_height) - left;
gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0xBF);
gDPSetCombineMode(db->p++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
gSPTextureRectangle(db->p++,
left * 4, (top + 5) * 4,
(left + sizeRectangle) * 4, ((top + 5) + 1) * 4,
0,
0, 0,
1024, 1024);
gDPSetCombineMode(db->p++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
} else {
gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF);
text_print_size(db, d->name, left, top, font_width, font_height);
}
}

left += ((SHUFFLE_CHEST_GAME == 1 ? 11 : 8) * font_width) + padding;
Expand Down Expand Up @@ -917,20 +936,36 @@ void draw_dungeon_info(z64_disp_buf_t* db) {
int start_top = bg_top + padding;

draw_background(db, bg_left, bg_top, bg_width, bg_height);
gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF);

// Draw dungeon names

for (int i = 0; i < 12; i++) {
dungeon_entry_t* d = &(dungeons[i + (i > 9 ? 1 : 0)]); // skip Hideout
bool empty = CFG_DUNGEON_PRECOMPLETED[d->index];
int top = start_top + ((icon_size + padding) * i) + 1;
text_print(db, d->name, left, top);
if (empty) {
gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0x7F);
uint16_t sizeRectangle = text_print(db, d->name, left, top) - left;
gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0xBF);
gDPSetCombineMode(db->p++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
gSPTextureRectangle(db->p++,
left * 4, (top + 6) * 4,
(left + sizeRectangle) * 4, (top + 6 + 2) * 4,
0,
0, 0,
1024, 1024);
gDPSetCombineMode(db->p++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
} else {
gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF);
text_print(db, d->name, left, top);
}
}

left += (8 * font_sprite.tile_w) + padding;

// Draw maps and compasses

gDPSetPrimColor(db->p++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF);
if (show_map_compass) {
// Draw maps

Expand Down
9 changes: 9 additions & 0 deletions ASM/src/config.asm
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
;==================================================================================================
; Settings and tables which the front-end may write
;==================================================================================================
; These values must be properly aligned to prevent an Address Error Exception on access. You can
; see what address a symbol was given after building in the build/asm_symbols.txt file.
; Byte values do not need to be aligned.
; Halfword values must be on an even byte boundary. ".align 2" can fix this value type's alignment.
; Word values must be on a byte boundary divisible by 4. ".align 4" can correct a misalignment.
; Doubleword values must be on a byte boundary divisible by 8. ".align 8" can fix a misalignment.

; This is used to determine if and how the cosmetics can be patched
; It this moves then the version will no longer be valid, so it is important that this does not move
Expand Down Expand Up @@ -266,6 +272,9 @@ PASSWORD:
.endarea
REWARDS_AS_ITEMS:
.byte 0x00
.area 14, 0x00
CFG_DUNGEON_PRECOMPLETED:
.endarea
.align 4

; These configuration values are given fixed addresses to aid auto-trackers.
Expand Down
2 changes: 1 addition & 1 deletion Hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -1557,7 +1557,7 @@ def build_gossip_hints(spoiler: Spoiler, worlds: list[World]) -> None:
for world in worlds:
for location in world.hinted_dungeon_reward_locations.values():
if world.settings.enhance_map_compass:
if world.mixed_pools_bosses or world.settings.shuffle_dungeon_rewards not in ('vanilla', 'reward'):
if world.entrance_rando_reward_hints:
# In these settings, there is not necessarily one dungeon reward in each dungeon,
# so we instead have each compass hint the area of its dungeon's vanilla reward.
compass_locations = [
Expand Down
8 changes: 5 additions & 3 deletions Patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -2132,7 +2132,7 @@ def update_scrub_text(message: bytearray, text_replacement: list[str], default_p
update_message_by_id(messages, map_id, map_message, allow_duplicates=True)
else:
dungeon_name, compass_id, map_id = dungeon_list[dungeon.name]
if world.mixed_pools_bosses or world.settings.shuffle_dungeon_rewards not in ('vanilla', 'reward'):
if world.entrance_rando_reward_hints:
vanilla_reward = world.get_location(dungeon.vanilla_boss_name).vanilla_item
vanilla_reward_location = world.hinted_dungeon_reward_locations[vanilla_reward]
area = HintArea.at(vanilla_reward_location)
Expand Down Expand Up @@ -2913,19 +2913,21 @@ def configure_dungeon_info(rom: Rom, world: World) -> None:
dungeon_rewards[codes.index(area.dungeon_name)] = boss_reward_index(location.item)

dungeon_is_mq = [1 if world.dungeon_mq.get(c) else 0 for c in codes]
dungeon_precompleted = [1 if world.empty_dungeons[c].empty else 0 for c in codes]

rom.write_int32(rom.sym('CFG_DUNGEON_INFO_ENABLE'), 2)
rom.write_int32(rom.sym('CFG_DUNGEON_INFO_MQ_ENABLE'), int(mq_enable))
rom.write_int32(rom.sym('CFG_DUNGEON_INFO_MQ_NEED_MAP'), int(enhance_map_compass))
rom.write_int32(rom.sym('CFG_DUNGEON_INFO_REWARD_ENABLE'), int('altar' in world.settings.misc_hints or enhance_map_compass))
rom.write_int32(rom.sym('CFG_DUNGEON_INFO_REWARD_NEED_COMPASS'), (2 if world.mixed_pools_bosses or world.settings.shuffle_dungeon_rewards not in ('vanilla', 'reward') else 1) if enhance_map_compass and world.settings.shuffle_dungeon_rewards != 'dungeon' else 0)
rom.write_int32(rom.sym('CFG_DUNGEON_INFO_REWARD_NEED_COMPASS'), (2 if world.entrance_rando_reward_hints else 1) if enhance_map_compass and world.settings.shuffle_dungeon_rewards != 'dungeon' else 0)
rom.write_int32(rom.sym('CFG_DUNGEON_INFO_REWARD_NEED_ALTAR'), int(not enhance_map_compass and world.settings.shuffle_dungeon_rewards != 'dungeon'))
rom.write_int32(rom.sym('CFG_DUNGEON_INFO_REWARD_SUMMARY_ENABLE'), int(not world.mixed_pools_bosses and world.settings.shuffle_dungeon_rewards in ('vanilla', 'reward')))
rom.write_int32(rom.sym('CFG_DUNGEON_INFO_REWARD_SUMMARY_ENABLE'), int(not world.entrance_rando_reward_hints))
rom.write_bytes(rom.sym('CFG_DUNGEON_REWARDS'), dungeon_rewards)
rom.write_bytes(rom.sym('CFG_DUNGEON_IS_MQ'), dungeon_is_mq)
rom.write_bytes(rom.sym('CFG_DUNGEON_REWARD_AREAS'), dungeon_reward_areas)
rom.write_byte(rom.sym('CFG_DUNGEON_INFO_REWARD_WORLDS_ENABLE'), int(world.settings.world_count > 1 and world.settings.shuffle_dungeon_rewards in ('regional', 'overworld', 'any_dungeon', 'anywhere')))
rom.write_bytes(rom.sym('CFG_DUNGEON_REWARD_WORLDS'), dungeon_reward_worlds)
rom.write_bytes(rom.sym('CFG_DUNGEON_PRECOMPLETED'), dungeon_precompleted)


# Overwrite an actor in rom w/ the actor data from LocationList
Expand Down
2 changes: 1 addition & 1 deletion Plandomizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,7 @@ def to_json(self, include_output: bool = True, spoiler: bool = True) -> dict[str
':enable_distribution_file': self.settings.enable_distribution_file,
}

if not self.settings.password_lock:
if not self.settings.password_lock or not spoiler:
self_dict.pop('password')

world_dist_dicts = [world_dist.to_json() for world_dist in self.world_dists]
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Differences between `dev-fenhl` and [`Dev-R`](https://github.com/Roman971/OoT-Ra
* The GUI tweaks made by [`Dev-R`](https://github.com/Roman971/OoT-Randomizer) are further adjusted to balance consistency with [main `Dev`](https://github.com/OoTRandomizer/OoT-Randomizer) and ease of use.
* The Lens of Truth can be in a foolish area if Treasure Chest Game keys are shuffled and all relevant “lensless” tricks are enabled.
* Bug fixes:
* Blue warps now set time of day even on repeated use (based on [#2287](https://github.com/OoTRandomizer/OoT-Randomizer/pull/2287))
* Blue warps setting time of day even on repeated use is now in logic (based on [#2287](https://github.com/OoTRandomizer/OoT-Randomizer/pull/2287))
* The randomizer no longer silently ignores the `Decompress` program failing ([#2229](https://github.com/OoTRandomizer/OoT-Randomizer/pull/2229))
* A trade item obtained from a skipped location is no longer lost upon obtaining a different item from the same trade quest ([#2217](https://github.com/OoTRandomizer/OoT-Randomizer/pull/2217))
* The ocarina buttons required to play the Song of Time are now included on the path of time ([#2203](https://github.com/OoTRandomizer/OoT-Randomizer/pull/2203))
Expand Down Expand Up @@ -223,6 +223,7 @@ issue. You should always Hard Reset to avoid this issue entirely.
* Fairy pots are now included in `Shuffle Pots`.
* A message is shown the first time a seed with No Logic is generated, to warn the user that the seed may be unbeatable.
* New hint distribution field `excluded_goal_categories` to disable specific goal categories.
* Pre-completed dungeons are crossed out in the dungeon overview menus (A or D-left on the inventory screen).

#### Bug Fixes
* Goal hints can now hint items required to defeat Ganon even if they're not required for the rainbow bridge, Ganon's boss key, or the trials. These items will be hinted as being on the "path of the hero".
Expand Down Expand Up @@ -257,6 +258,7 @@ issue. You should always Hard Reset to avoid this issue entirely.
* Major items from pots, crates, etc now display above Link's head while the text box is open.
* Gameplay is no longer interrupted if you receive a junk item from another player in multiworld.
* Removed the potentially confusing Master Sword icon from the Rainbow Bridge page of the adult Temple of Time altar text.
* Blue warps now set time of day each time they're taken, fixing a potential softlock.

### 8.1

Expand Down
2 changes: 2 additions & 0 deletions World.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ def __init__(self, world_id: int, settings: Settings, resolve_randomized_setting
)
)
)
# in these settings, there's not necessarily one dungeon reward in each main dungeon, so compasses and the pause menu switch to a different behavior
self.entrance_rando_reward_hints = self.mixed_pools_bosses or self.settings.shuffle_ganon_tower or self.settings.shuffle_dungeon_rewards not in ('vanilla', 'reward')

self.ensure_tod_access: bool = bool(self.shuffle_interior_entrances or settings.shuffle_overworld_entrances or self.spawn_positions)
self.disable_trade_revert: bool = self.shuffle_interior_entrances or settings.shuffle_overworld_entrances or settings.adult_trade_shuffle
Expand Down
39 changes: 30 additions & 9 deletions data/Hints/weekly.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "weekly",
"gui_name": "Weekly",
"description": "Hint distribution for the weekly races: 5 Always, 1 Named-Item (light arrows), 5 Goal, 3 Barren (ToT), 1 Song (ToT), 2 Dual, 5 Sometimes; House of Skulltula (30/40/50).",
"description": "Hint distribution for the weekly races: 5 Always, 5 Goal, 3 Barren (ToT), 1 Song (ToT), 2 Dual, 5 Sometimes; HCstorms & HFcow junked; House of Skulltula (30/40/50).",
"add_locations": [
{ "location": "Sheik in Kakariko", "types": ["always"] },
{ "location": "Deku Theater Skull Mask", "types": ["always"] }
Expand All @@ -26,9 +26,7 @@
{ "location": "Graveyard Royal Family Tomb Contents", "types": ["dual"] },
{ "location": "Ice Cavern Final Room", "types": ["dual"] }
],
"add_items": [
{ "item": "Light Arrows", "types": ["named-item"] }
],
"add_items": [],
"remove_items": [
{ "item": "Zeldas Lullaby", "types": ["goal"] }
],
Expand All @@ -38,40 +36,63 @@
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 0, "remove_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)",
"ToT (Left)",
"ToT (Left-Center)",
"ToT (Right-Center)",
"ToT (Right)"
]},
"always": {"order": 2, "weight": 0.0, "fixed": 5, "copies": 2, "remove_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)",
"ToT (Left)",
"ToT (Left-Center)",
"ToT (Right-Center)",
"ToT (Right)"
]},
"named-item": {"order": 3, "weight": 0.0, "fixed": 1, "copies": 2, "remove_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)",
"ToT (Left)",
"ToT (Left-Center)",
"ToT (Right-Center)",
"ToT (Right)"
]},
"goal": {"order": 4, "weight": 0.0, "fixed": 5, "copies": 2, "remove_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)",
"ToT (Left)",
"ToT (Left-Center)",
"ToT (Right-Center)",
"ToT (Right)"
]},
"barren": {"order": 5, "weight": 0.0, "fixed": 3, "copies": 1, "priority_stones": [
"barren": {"order": 5, "weight": 0.0, "fixed": 3, "copies": 1, "remove_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)"
], "priority_stones": [
"ToT (Left)",
"ToT (Left-Center)",
"ToT (Right-Center)"
]},
"song": {"order": 6, "weight": 0.0, "fixed": 1, "copies": 1, "priority_stones": [
"song": {"order": 6, "weight": 0.0, "fixed": 1, "copies": 1, "remove_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)"
], "priority_stones": [
"ToT (Right)"
]},
"dual": {"order": 7, "weight": 0.0, "fixed": 2, "copies": 2},
"sometimes": {"order": 8, "weight": 0.0, "fixed": 5, "copies": 2},
"junk": {"order": 9, "weight": 1.0, "fixed": 0, "copies": 1},
"dual": {"order": 7, "weight": 0.0, "fixed": 2, "copies": 2, "remove_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)"
]},
"sometimes": {"order": 8, "weight": 0.0, "fixed": 5, "copies": 2, "remove_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)"
]},
"junk": {"order": 9, "weight": 1.0, "fixed": 0, "copies": 1, "priority_stones": [
"HC (Storms Grotto)",
"HF (Cow Grotto)"
]},
"entrance_always": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0},
"woth": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0},
"entrance": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0},
Expand Down
Loading

0 comments on commit 0e63a65

Please sign in to comment.