diff --git a/soh/include/z64player.h b/soh/include/z64player.h index 954c36c14..3c2c7c3cd 100644 --- a/soh/include/z64player.h +++ b/soh/include/z64player.h @@ -356,7 +356,20 @@ typedef struct { /* 0x00 */ s32 active; /* 0x04 */ Vec3f tip; /* 0x10 */ Vec3f base; -} WeaponInfo; // size = 0x1C +} WeaponInfo; // size = 0x1C\ + +typedef enum { + FLAG_NONE, + FLAG_SCENE_SWITCH, + FLAG_SCENE_TREASURE, + FLAG_SCENE_CLEAR, + FLAG_SCENE_COLLECTIBLE, +} FlagType; + +typedef struct { + /* 0x00 */ s32 flagID; // which flag to set when Player_SetPendingFlag is called + /* 0x04 */ FlagType flagType; // type of flag to set when Player_SetPendingFlag is called +} PendingFlag; // size = 0x06 #define PLAYER_STATE1_0 (1 << 0) #define PLAYER_STATE1_1 (1 << 1) @@ -612,6 +625,7 @@ typedef struct Player { /* 0x0A86 */ s8 unk_A86; /* 0x0A87 */ u8 unk_A87; /* 0x0A88 */ Vec3f unk_A88; // previous body part 0 position -} Player; // size = 0xA94 + /* 0x0A94 */ PendingFlag pendingFlag; +} Player; // size = 0xAA0 #endif diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 5656f4c07..7c9db9837 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -237,10 +237,11 @@ void GivePlayerRandoRewardZeldaLightArrowsGift(GlobalContext* globalCtx, Randomi if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && LINK_IS_ADULT && (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TOKINOMA) && !Flags_GetTreasure(globalCtx, 0x1E) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) && - globalCtx->sceneLoadFlag == 0 && player->getItemId == GI_NONE) { + globalCtx->sceneLoadFlag == 0) { GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ARROW_LIGHT); GiveItemWithoutActor(globalCtx, getItemId); - Flags_SetTreasure(globalCtx, 0x1E); + player->pendingFlag.flagID = 0x1E; + player->pendingFlag.flagType = FLAG_SCENE_TREASURE; } } diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index 88ce05819..d9f96e177 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -288,14 +288,16 @@ void func_80B3CA38(EnXc* this, GlobalContext* globalCtx) { } void GivePlayerRandoRewardSheikSong(EnXc* sheik, GlobalContext* globalCtx, RandomizerCheck check, int sheikType, GetItemID ogSongId) { - if (sheik->actor.parent != NULL && sheik->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && + Player* player = GET_PLAYER(globalCtx); + if (sheik->actor.parent != NULL && sheik->actor.parent->id == player->actor.id && !(gSaveContext.eventChkInf[5] & sheikType)) { gSaveContext.eventChkInf[5] |= sheikType; } else if (!(gSaveContext.eventChkInf[5] & sheikType)) { GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, ogSongId); if (check == RC_SHEIK_AT_TEMPLE && !Flags_GetTreasure(globalCtx, 0x1F)) { if (func_8002F434(&sheik->actor, globalCtx, getItemId, 10000.0f, 100.0f)) { - Flags_SetTreasure(globalCtx, 0x1F); + player->pendingFlag.flagID = 0x1F; + player->pendingFlag.flagType = FLAG_SCENE_TREASURE; } } else if (check != RC_SHEIK_AT_TEMPLE) { func_8002F434(&sheik->actor, globalCtx, getItemId, 10000.0f, 100.0f); diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 1f1d09a8d..2c3b3d61b 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -167,6 +167,7 @@ void func_8083CA20(GlobalContext* globalCtx, Player* this); void func_8083CA54(GlobalContext* globalCtx, Player* this); void func_8083CA9C(GlobalContext* globalCtx, Player* this); s32 func_8083E0FC(Player* this, GlobalContext* globalCtx); +void Player_SetPendingFlag(Player* this, GlobalContext* globalCtx); s32 func_8083E5A8(Player* this, GlobalContext* globalCtx); s32 func_8083EB44(Player* this, GlobalContext* globalCtx); s32 func_8083F7BC(Player* this, GlobalContext* globalCtx); @@ -6231,6 +6232,30 @@ void func_8083E4C4(GlobalContext* globalCtx, Player* this, GetItemEntry* giEntry func_80078884((this->getItemId < 0) ? NA_SE_SY_GET_BOXITEM : NA_SE_SY_GET_ITEM); } +// Sets a flag according to which type of flag is specified in player->pendingFlag.flagType +// and which flag is specified in player->pendingFlag.flagID. +void Player_SetPendingFlag(Player* this, GlobalContext* globalCtx) { + switch (this->pendingFlag.flagType) { + case FLAG_SCENE_CLEAR: + Flags_SetClear(globalCtx, this->pendingFlag.flagID); + break; + case FLAG_SCENE_COLLECTIBLE: + Flags_SetCollectible(globalCtx, this->pendingFlag.flagID); + break; + case FLAG_SCENE_SWITCH: + Flags_SetSwitch(globalCtx, this->pendingFlag.flagID); + break; + case FLAG_SCENE_TREASURE: + Flags_SetTreasure(globalCtx, this->pendingFlag.flagID); + break; + case FLAG_NONE: + default: + break; + } + this->pendingFlag.flagType = FLAG_NONE; + this->pendingFlag.flagID = 0; +} + s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) { Actor* interactedActor; @@ -6254,6 +6279,7 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) { this->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11); this->actor.colChkInfo.damage = 0; func_80837C0C(globalCtx, this, 3, 0.0f, 0.0f, 0, 20); + Player_SetPendingFlag(this, globalCtx); return; } @@ -12659,6 +12685,8 @@ s32 func_8084DFF4(GlobalContext* globalCtx, Player* this) { Message_StartTextbox(globalCtx, giEntry->textId, &this->actor); Item_Give(globalCtx, giEntry->itemId); + + Player_SetPendingFlag(this, globalCtx); if (((this->getItemId >= GI_RUPEE_GREEN) && (this->getItemId <= GI_RUPEE_RED)) || ((this->getItemId >= GI_RUPEE_PURPLE) && (this->getItemId <= GI_RUPEE_GOLD)) ||