Skip to content

Commit

Permalink
Miscellaneous Bug Fixes (#711)
Browse files Browse the repository at this point in the history
* Fix player draw function being overwritten by FW

* Don't use custom tunic on title screen Link

* Epona starting inventory fix

* Fix ice trap on dungeon reward in water

* Allow getting OVR_TEMPLE item at water surface

* Additional safety check for pending overrides

* Fix music glitch in Desert Colossus
  • Loading branch information
HylianFreddy authored Dec 20, 2023
1 parent 9b85fb2 commit d66ab65
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 5 deletions.
15 changes: 14 additions & 1 deletion code/src/actors/player.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,21 @@
#define PlayerDListGroup_EmptySheathAdult ((void*)0x53C4D8)
#define PlayerDListGroup_EmptySheathChildWithHylianShield ((void*)0x53C4DC)

#define OBJECT_LINK_OPENING 0x19F

u16 healthDecrement = 0;
u8 storedMask = 0;

void** Player_EditAndRetrieveCMB(ZARInfo* zarInfo, u32 objModelIdx) {
void** cmbMan = ZAR_GetCMBByIndex(zarInfo, objModelIdx);
void* cmb = *cmbMan;

if (gActorOverlayTable[0].initInfo->objectId == OBJECT_LINK_OPENING) {
// Title Screen Link uses a different object, so don't apply the custom tunic patches
// to avoid displaying a broken tunic.
return cmbMan;
}

if (gSettingsContext.customTunicColors == ON) {
if (gSaveContext.linkAge == AGE_ADULT) {
CustomModel_EditLinkToCustomTunic(cmb);
Expand All @@ -52,7 +60,7 @@ void** Player_EditAndRetrieveCMB(ZARInfo* zarInfo, u32 objModelIdx) {
}

void* Player_GetCustomTunicCMAB(ZARInfo* originalZarInfo, u32 originalIndex) {
if (gSettingsContext.customTunicColors == OFF) {
if (gSettingsContext.customTunicColors == OFF || gActorOverlayTable[0].initInfo->objectId == OBJECT_LINK_OPENING) {
return ZAR_GetCMABByIndex(originalZarInfo, originalIndex);
}
s16 exObjectBankIdx = Object_GetIndex(&rExtendedObjectCtx, OBJECT_CUSTOM_GENERAL_ASSETS);
Expand Down Expand Up @@ -106,6 +114,11 @@ void PlayerActor_rUpdate(Actor* thisx, GlobalContext* globalCtx) {
Player* this = (Player*)thisx;
PlayerActor_Update(thisx, globalCtx);

// Restore Randomizer draw function in case something (like Farore's Wind) overwrote it
if (thisx->draw == PlayerActor_Draw) {
thisx->draw = PlayerActor_rDraw;
}

Arrow_HandleSwap(this, globalCtx);

if (this->naviActor != 0) {
Expand Down
9 changes: 7 additions & 2 deletions code/src/item_override.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ static u32 ItemOverride_PlayerIsReadyInWater(void) {
(PLAYER->stateFlags2 & 0x000C0000) == 0 && PLAYER->actor.draw != NULL &&
gGlobalContext->actorCtx.titleCtx.delayTimer == 0 && gGlobalContext->actorCtx.titleCtx.durationTimer == 0 &&
gGlobalContext->actorCtx.titleCtx.alpha == 0 && (PLAYER->stateFlags1 & 0x08000000) != 0 && // Player is Swimming
(PLAYER->stateFlags2 & 0x400) != 0 && // Player is underwater
(PLAYER->stateFlags1 & 0x400) == 0 && // Player is not already receiving an item when surfacing
gGlobalContext->sceneLoadFlag == 0 && // Another scene isn't about to be loaded
rPendingOverrideQueue[0].key.type == OVR_TEMPLE // Must be an item received for completing a dungeon
Expand Down Expand Up @@ -394,12 +393,18 @@ void ItemOverride_Update(void) {
CustomModel_Update();
u8 readyStatus = ItemOverride_PlayerIsReady();
if (readyStatus) {
ItemOverride_PopIceTrap();
if (readyStatus == READY_ON_LAND) { // Ice traps effects only work on land
ItemOverride_PopIceTrap();
}

if (IceTrap_IsPending()) {
IceTrap_Give();
} else {
ItemOverride_TryPendingItem();
if (readyStatus == READY_IN_WATER) {
// Force underwater player flag in order to play the correct get-item
// animation even if Link is at the water's surface.
PLAYER->stateFlags2 |= 0x400;
SetupItemInWater(PLAYER, gGlobalContext);
rDummyActor->parent = NULL;
ItemOverride_PopPendingOverride();
Expand Down
4 changes: 3 additions & 1 deletion code/src/menus.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "savefile.h"
#include "settings.h"
#include "dungeon_rewards.h"
#include "item_override.h"

#define gItemsMenuSpritesManager (*(MenuSpriteManager**)0x506734)
#define gBowMenuSpritesManager (*(MenuSpriteManager**)0x506738)
Expand Down Expand Up @@ -147,6 +148,7 @@ u16 GearMenu_GetRewardHint(void) {
}

u16 SaveMenu_IgnoreOpen(void) {
return (gSettingsContext.menuOpeningButton == 0 && rInputCtx.cur.sel) ||
return ItemOverride_IsAPendingOverride() || // safety check to avoid missing pending overrides by save-warping
(gSettingsContext.menuOpeningButton == 0 && rInputCtx.cur.sel) ||
(gSettingsContext.menuOpeningButton == 1 && rInputCtx.cur.strt);
}
4 changes: 3 additions & 1 deletion code/src/savefile.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ void SaveFile_Init(u32 fileBaseIndex) {
gSaveContext.eventChkInf[0x4] |= 0x8020; // Entered MS chamber, Pulled MS from pedestal
gSaveContext.eventChkInf[0xC] |= 0x0020; // Sheik Spawned at MS pedestal as Adult

gSaveContext.sceneFlags[5].swch |= 0x00010000; // remove Ruto cutscene in Water Temple
gSaveContext.sceneFlags[0x05].swch |= 0x00010000; // Met Ruto in Water Temple
gSaveContext.sceneFlags[0x5C].swch |= 0x80000000; // Spoke to owl in Desert Colossus (required for music to play)

gSaveContext.otherNewEventFlags |= 0x01; // Club Moblin cutscene

Expand Down Expand Up @@ -532,6 +533,7 @@ void SaveFile_SetStartingInventory(void) {
// Set Epona as freed if Skip Epona Race is enabled and Epona's Song is in the starting inventory
if (gSettingsContext.skipEponaRace == SKIP && (gSaveContext.questItems >> 13) & 0x1) {
EventSet(0x18);
gSaveContext.horseData.pos.y = 0xF000; // place Epona OoB, so you can't reach her without playing the song
}
}

Expand Down

0 comments on commit d66ab65

Please sign in to comment.