This commit is contained in:
Garrett Cox 2024-04-10 04:31:48 +00:00 committed by GitHub
commit 79905f9495
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
176 changed files with 5339 additions and 3859 deletions

View File

@ -183,6 +183,8 @@ void __osSetWatchLo(u32);
EnItem00* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, s16 params);
EnItem00* Item_DropCollectible2(PlayState* play, Vec3f* spawnPos, s16 params);
void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry giEntry);
void EnItem00_SetupAction(EnItem00* this, EnItem00ActionFunc actionFunc);
void func_8001E5C8(EnItem00* this, PlayState* play);
void Item_DropCollectibleRandom(PlayState* play, Actor* fromActor, Vec3f* spawnPos, s16 params);
void EffectBlure_ChangeType(EffectBlure* this, int type);
void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2);
@ -415,6 +417,7 @@ f32 Actor_WorldDistXZToPoint(Actor* actor, Vec3f* refPoint);
void func_8002DBD0(Actor* actor, Vec3f* result, Vec3f* arg2);
f32 Actor_HeightDiff(Actor* actorA, Actor* actorB);
f32 Player_GetHeight(Player* player);
s32 Player_ActionChange_2(Player* player, PlayState* play);
f32 func_8002DCE4(Player* player);
s32 func_8002DD6C(Player* player);
s32 func_8002DD78(Player* player);
@ -426,7 +429,7 @@ void Actor_MountHorse(PlayState* play, Player* player, Actor* horse);
s32 func_8002DEEC(Player* player);
void func_8002DF18(PlayState* play, Player* player);
s32 func_8002DF38(PlayState* play, Actor* actor, u8 csMode);
s32 func_8002DF54(PlayState* play, Actor* actor, u8 arg2);
s32 Player_SetCsActionWithHaltedActors(PlayState* play, Actor* actor, u8 arg2);
void func_8002DF90(DynaPolyActor* dynaActor);
void func_8002DFA4(DynaPolyActor* dynaActor, f32 arg1, s16 arg2);
s32 Player_IsFacingActor(Actor* actor, s16 angle, PlayState* play);
@ -454,11 +457,11 @@ u32 Actor_TextboxIsClosing(Actor* actor, PlayState* play);
s8 func_8002F368(PlayState* play);
void Actor_GetScreenPos(PlayState* play, Actor* actor, s16* x, s16* y);
u32 Actor_HasParent(Actor* actor, PlayState* play);
// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename func_8002F434 and func_8002F554.
// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename Actor_OfferGetItem and func_8002F554.
s32 GiveItemEntryWithoutActor(PlayState* play, GetItemEntry getItemEntry);
s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEntry, f32 xzRange, f32 yRange);
s32 GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry);
s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange);
s32 Actor_OfferGetItem(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange);
void func_8002F554(Actor* actor, PlayState* play, s32 getItemId);
void func_8002F580(Actor* actor, PlayState* play);
u32 Actor_HasNoParent(Actor* actor, PlayState* play);
@ -572,8 +575,6 @@ void Flags_UnsetRandomizerInf(RandomizerInf flag);
u16 func_80037C30(PlayState* play, s16 arg1);
s32 func_80037D98(PlayState* play, Actor* actor, s16 arg2, s32* arg3);
s32 func_80038290(PlayState* play, Actor* actor, Vec3s* arg2, Vec3s* arg3, Vec3f arg4);
GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, PlayState* play);
s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, PlayState* play);
// ? func_80038600(?);
u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList*);
@ -1106,6 +1107,7 @@ s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input);
u8 PlayerGrounded(Player* player);
void Player_SetBootData(PlayState* play, Player* player);
s32 Player_InBlockingCsMode(PlayState* play, Player* player);
s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction);
s32 Player_InCsMode(PlayState* play);
s32 func_8008E9C4(Player* player);
s32 Player_IsChildWithHylianShield(Player* player);

View File

@ -266,7 +266,12 @@ typedef enum {
/* 0x17 */ ITEM00_TUNIC_ZORA,
/* 0x18 */ ITEM00_TUNIC_GORON,
/* 0x19 */ ITEM00_BOMBS_SPECIAL,
/* 0x20 */ ITEM00_BOMBCHU,
/* 0x1A */ ITEM00_BOMBCHU,
/* 0x1B */ ITEM00_SOH_DUMMY,
/* 0x1C */ ITEM00_SOH_GIVE_ITEM_ENTRY,
/* 0x1D */ ITEM00_SOH_GIVE_ITEM_ENTRY_GI,
/* 0x1E */ ITEM00_MAX,
/* 0xFF */ ITEM00_NONE = 0xFF
} Item00Type;
struct EnItem00;
@ -284,10 +289,13 @@ typedef struct EnItem00 {
/* 0x15A */ s16 unk_15A;
/* 0x15C */ f32 scale;
/* 0x160 */ ColliderCylinder collider;
s16 ogParams;
// #region SOH [Randomizer]
GetItemEntry randoGiEntry;
RandomizerCheck randoCheck;
RandomizerInf randoInf;
/* */ s16 ogParams;
/* */ GetItemEntry itemEntry;
// #endregion
} EnItem00; // size = 0x1AC
// Only A_OBJ_SIGNPOST_OBLONG and A_OBJ_SIGNPOST_ARROW are used in room files.

View File

@ -283,7 +283,7 @@ typedef struct {
// #endregion
// #region SOH [Randomizer]
// Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer
/* */ u16 randomizerInf[16];
/* */ u16 randomizerInf[17];
/* */ u8 mqDungeonCount;
/* */ u16 adultTradeItems;
/* */ u8 triforcePiecesCollected;

View File

@ -505,6 +505,7 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_CHILD_FISHING, "RAND_INF_CHILD_FISHING" },
{ RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" },
{ RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" },
{ RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" },
{ RAND_INF_GOHMA_SOUL, "RAND_INF_GOHMA_SOUL" },
{ RAND_INF_KING_DODONGO_SOUL, "RAND_INF_KING_DODONGO_SOUL" },
@ -515,7 +516,6 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_BONGO_BONGO_SOUL, "RAND_INF_BONGO_BONGO_SOUL" },
{ RAND_INF_TWINROVA_SOUL, "RAND_INF_TWINROVA_SOUL" },
{ RAND_INF_GANON_SOUL, "RAND_INF_GANON_SOUL" },
{ RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" },
{ RAND_INF_HAS_OCARINA_A, "RAND_INF_HAS_OCARINA_A"},
{ RAND_INF_HAS_OCARINA_C_UP, "RAND_INF_HAS_OCARINA_C_UP" },
@ -607,7 +607,19 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_ZD_FISH_2, "RAND_INF_ZD_FISH_2" },
{ RAND_INF_ZD_FISH_3, "RAND_INF_ZD_FISH_3" },
{ RAND_INF_ZD_FISH_4, "RAND_INF_ZD_FISH_4" },
{ RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" }
{ RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" },
{ RAND_INF_LINKS_POCKET, "RAND_INF_LINKS_POCKET" },
{ RAND_INF_LEARNED_EPONA_SONG, "RAND_INF_LEARNED_EPONA_SONG" },
{ RAND_INF_DARUNIAS_JOY, "RAND_INF_DARUNIAS_JOY" },
{ RAND_INF_KING_ZORA_THAWED, "RAND_INF_KING_ZORA_THAWED" },
{ RAND_INF_HC_GREAT_FAIRY_REWARD, "RAND_INF_HC_GREAT_FAIRY_REWARD" },
{ RAND_INF_DMT_GREAT_FAIRY_REWARD, "RAND_INF_DMT_GREAT_FAIRY_REWARD" },
{ RAND_INF_DMC_GREAT_FAIRY_REWARD, "RAND_INF_DMC_GREAT_FAIRY_REWARD" },
{ RAND_INF_ZF_GREAT_FAIRY_REWARD, "RAND_INF_ZF_GREAT_FAIRY_REWARD" },
{ RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, "RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD" },
{ RAND_INF_OGC_GREAT_FAIRY_REWARD, "RAND_INF_OGC_GREAT_FAIRY_REWARD" },
} },
};

View File

@ -34,6 +34,8 @@ std::vector<ValueTableElement> valueTable = {
{ "Text ID", "play->msgCtx.textId", "TEXTID:", TYPE_U16, true, []() -> void* { return &gPlayState->msgCtx.textId; }, WHITE },
{ "Analog Stick X", "play->state.input->cur.stick_x", "AX:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_x; }, WHITE },
{ "Analog Stick Y", "play->state.input->cur.stick_y", "AY:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_y; }, WHITE },
{ "getItemID", "Player->getItemId", "ITEM:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemId; }, WHITE },
{ "getItemEntry", "Player->getItemEntry", "IE:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemEntry.itemId; }, WHITE },
/* TODO: Find these (from GZ)
"XZ Units Traveled (Camera based speed variable)" f32 0x801C9018
"Movement Angle" x16 0x801DBB1C

View File

@ -14,6 +14,13 @@ typedef enum {
CSMC_SIZE
} ChestStyleMatchesContentsType;
typedef enum {
SGIA_DISABLED,
SGIA_JUNK,
SGIA_ALL,
SGIA_SIZE
} SkipGetItemAnimationType;
typedef enum {
BUNNY_HOOD_VANILLA,
BUNNY_HOOD_FAST_AND_JUMP,

View File

@ -3,6 +3,7 @@
#ifndef GameInteractor_h
#define GameInteractor_h
#include "libultraship/libultraship.h"
#include "GameInteractionEffect.h"
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include <z64.h>
@ -67,6 +68,299 @@ typedef enum {
/* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_7,
} GITeleportDestinations;
typedef enum {
// Vanilla condition: gSaveContext.showTitleCard
GI_VB_SHOW_TITLE_CARD,
// Opt: *EnWonderTalk2
GI_VB_WONDER_TALK,
// Opt: *ElfMsg
GI_VB_NAVI_TALK,
// Vanilla condition: INFTABLE_GREETED_BY_SARIA
GI_VB_NOT_BE_GREETED_BY_SARIA,
// Opt: *EnMd
// Vanilla condition: EnMd->interactInfo.talkState == NPC_TALK_STATE_ACTION
GI_VB_MOVE_MIDO_IN_KOKIRI_FOREST,
// Opt: *EnMd
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)
GI_VB_MIDO_CONSIDER_DEKU_TREE_DEAD,
// Opt: *EnKo
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)
GI_VB_OPEN_KOKIRI_FOREST,
// Opt: *EnOwl
// Vanilla condition: EnOwl->actor.xzDistToPlayer < targetDist
GI_VB_OWL_INTERACTION,
// Vanilla condition: EVENTCHKINF_TALON_RETURNED_FROM_CASTLE
GI_VB_MALON_RETURN_FROM_CASTLE,
// Vanilla condition: CUR_UPG_VALUE(UPG_STRENGTH) <= 0
GI_VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD,
/* Vanilla condition:
```
LINK_IS_ADULT &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
```
*/
GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS,
// Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SARIA)
GI_VB_BE_ELIGIBLE_FOR_SARIAS_SONG,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_SONG_EPONA)
GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG,
// Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)
GI_VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER,
// Vanilla condition: (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT
GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER,
// Vanilla condition: !EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT and EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP
GI_VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT,
/* Vanilla Condition:
```
LINK_IS_ADULT &&
gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 &&
Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) &&
Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) &&
Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) &&
!Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL);
```
*/
GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW,
// Opt: *EnGo2
// Vanilla condition: CUR_CAPACITY(UPG_BOMB_BAG) >= 20 && this->waypoint > 7 && this->waypoint < 12
GI_VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD,
// Vanilla condition: !CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON)
GI_VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE,
// Opt: *EnMs
// Vanilla condition: gSaveContext.rupees >= sPrices[BEANS_BOUGHT]
GI_VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE,
// Opt: *EnItem00
// Vanilla condition: Flags_GetCollectible(play, this->collectibleFlag)
GI_VB_ITEM00_DESPAWN,
// Opt: *EnTk
// Vanilla condition: gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD
GI_VB_DAMPE_IN_GRAVEYARD_DESPAWN,
// Opt: *EnTk
// Vanilla condition: this->validDigHere == 1
GI_VB_BE_VALID_GRAVEDIGGING_SPOT,
// Opt: *EnTk
// Vanilla condition: this->currentReward == 3
GI_VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE,
// Opt: *EnTk
// Vanilla condition: !Flags_GetItemGetInf(ITEMGETINF_1C)
GI_VB_DAMPE_GRAVEDIGGING_GRAND_PRIZE_BE_HEART_PIECE,
// Opt: *EnShopnuts
/* Vanilla Condition:
```
((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) ||
((this->actor.params == 0x0009) && (Flags_GetInfTable(INFTABLE_192))) ||
((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193)))
```
*/
GI_VB_BUSINESS_SCRUB_DESPAWN,
// Opt: *EnCow
// Vanilla condition: play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE))
GI_VB_DESPAWN_HORSE_RACE_COW,
// Opt: *EnHs
// Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30)
GI_VB_DESPAWN_GROG,
// Opt: *EnKo
// Vanilla condition: (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false;
GI_VB_SPAWN_LW_FADO,
// Opt: *EnMk
GI_VB_PLAY_EYEDROP_CREATION_ANIM,
// Opt: *EnDs
GI_VB_PLAY_ODD_POTION_ANIM,
// Opt: *EnMk
// Vanilla condition: INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS
GI_VB_USE_EYEDROP_DIALOGUE,
// Opt: *EnMk
// Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30)
GI_VB_OFFER_BLUE_POTION,
// Vanilla condition: Inventory_HasEmptyBottle() == 0
GI_VB_NEED_BOTTLE_FOR_GRANNYS_ITEM,
// Opt: *EnNiwLady
GI_VB_SET_CUCCO_COUNT,
// Opt: *EnKz
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)
GI_VB_KING_ZORA_THANK_CHILD,
// Opt: *EnKz
// Vanilla condition: this->actor.textId == 0x401A
GI_VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER,
// Opt: *EnKz
// Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)
GI_VB_KING_ZORA_BE_MOVED,
// Vanilla condition: gSaveState.bgsFlag
GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE,
// Vanilla condition: gSaveState.bgsFlag
GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED,
// Vanilla condition: Environment_GetBgsDayCount() >= 3
GI_VB_BIGGORON_CONSIDER_SWORD_FORGED,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)
GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_GORON_RUBY)
GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED,
// Opt: *uint16_t
// Vanilla condition: false
GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE,
// Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)
GI_VB_GORONS_CONSIDER_TUNIC_COLLECTED,
// Opt: *EnSyatekiMan
// Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50)
GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD,
// Opt: *EnOkarinaTag
// Vanilla condition: !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME)
GI_VB_BE_ELIGIBLE_TO_OPEN_DOT,
// Opt: *BgDyYoseizo
// Vanilla condition: see soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c
GI_VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD,
/*** Play Cutscenes ***/
GI_VB_PLAY_TRANSITION_CS,
// Opt: *EventChkInf flag
GI_VB_PLAY_ENTRANCE_CS,
// Opt: *cutsceneId
GI_VB_PLAY_ONEPOINT_CS,
// Opt: *actor
GI_VB_PLAY_ONEPOINT_ACTOR_CS,
// Opt: *BgTreemouth
GI_VB_PLAY_DEKU_TREE_INTRO_CS,
// Vanilla condition: !EventChkInf except for spirit & shadow temple which are !medallion, and Jabu which always is true
GI_VB_PLAY_BLUE_WARP_CS,
GI_VB_PLAY_DARUNIAS_JOY_CS,
GI_VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS,
// Vanilla condition: !EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL
GI_VB_PLAY_PULL_MASTER_SWORD_CS,
GI_VB_PLAY_DROP_FISH_FOR_JABU_CS,
// Vanilla condition: player->getItemId == GI_GAUNTLETS_SILVER
GI_VB_PLAY_NABOORU_CAPTURED_CS,
GI_VB_PLAY_ZELDAS_LULLABY_CS,
// Opt: *EnSa
GI_VB_PLAY_SARIAS_SONG_CS,
GI_VB_PLAY_PRELUDE_OF_LIGHT_CS,
GI_VB_PLAY_MINUET_OF_FOREST_CS,
GI_VB_PLAY_BOLERO_OF_FIRE_CS,
GI_VB_PLAY_SERENADE_OF_WATER_CS,
GI_VB_PLAY_EYEDROPS_CS,
// Opt: *EnOkarinaTag
GI_VB_PLAY_DRAIN_WELL_CS,
// Opt: *EnOkarinaTag
// Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SUN)
GI_VB_PLAY_SUNS_SONG_CS,
// Opt: *EnOkarinaTag
GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS,
GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE,
// Opt: *EnOkarinaTag
GI_VB_PLAY_DOOR_OF_TIME_CS,
/*** Give Items ***/
// Opt: *EnBox
GI_VB_GIVE_ITEM_FROM_CHEST,
GI_VB_GIVE_ITEM_FROM_BLUE_WARP,
// Opt: *EnItem00
GI_VB_GIVE_ITEM_FROM_ITEM_00,
// Opt: *EnSi
GI_VB_GIVE_ITEM_SKULL_TOKEN,
// Opt: *EnCow
GI_VB_GIVE_ITEM_FROM_COW,
// Opt: *EnDns
GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB,
// Opt: *EnMk
GI_VB_GIVE_ITEM_FROM_LAB_DIVE,
// Opt: *EnDs
GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP,
// Opt: *EnNiwLady
GI_VB_GIVE_ITEM_FROM_ANJU_AS_CHILD,
// Opt: *EnNiwLady
GI_VB_GIVE_ITEM_FROM_ANJU_AS_ADULT,
// Opt: *EnKz
// Vanilla condition: !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA)
GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA,
// Opt: *EnGo2
GI_VB_GIVE_ITEM_FROM_GORON,
// Opt: *EnJs
GI_VB_GIVE_ITEM_FROM_CARPET_SALESMAN,
// Opt: *EnGm
GI_VB_GIVE_ITEM_FROM_MEDIGORON,
// Opt: *EnMs
GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN,
// Opt: *EnFr
GI_VB_GIVE_ITEM_FROM_FROGS,
// Opt: *EnSkj
GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG,
GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF,
// Opt: *EnSyatekiMan
GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY,
// Opt: *EnExItem
GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS,
// Opt: *EnTa
GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS,
// Opt: *EnDivingGame
GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME,
// Opt: *EnGe1
GI_VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY,
// Opt: *EnSth
GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD,
GI_VB_GIVE_ITEM_FAIRY_OCARINA,
GI_VB_GIVE_ITEM_WEIRD_EGG,
GI_VB_GIVE_ITEM_LIGHT_ARROW,
GI_VB_GIVE_ITEM_STRENGTH_1,
GI_VB_GIVE_ITEM_ZELDAS_LETTER,
GI_VB_GIVE_ITEM_MASTER_SWORD,
GI_VB_GIVE_ITEM_OCARINA_OF_TIME,
GI_VB_GIVE_ITEM_KOKIRI_EMERALD,
GI_VB_GIVE_ITEM_GORON_RUBY,
GI_VB_GIVE_ITEM_ZORA_SAPPHIRE,
GI_VB_GIVE_ITEM_LIGHT_MEDALLION,
GI_VB_GIVE_ITEM_FOREST_MEDALLION,
GI_VB_GIVE_ITEM_FIRE_MEDALLION,
GI_VB_GIVE_ITEM_WATER_MEDALLION,
GI_VB_GIVE_ITEM_SPIRIT_MEDALLION,
GI_VB_GIVE_ITEM_SHADOW_MEDALLION,
/*** Give Songs ***/
GI_VB_GIVE_ITEM_ZELDAS_LULLABY,
GI_VB_GIVE_ITEM_SARIAS_SONG,
GI_VB_GIVE_ITEM_EPONAS_SONG,
GI_VB_GIVE_ITEM_SUNS_SONG,
GI_VB_GIVE_ITEM_SONG_OF_TIME,
GI_VB_GIVE_ITEM_SONG_OF_STORMS,
GI_VB_GIVE_ITEM_MINUET_OF_FOREST,
GI_VB_GIVE_ITEM_BOLERO_OF_FIRE,
GI_VB_GIVE_ITEM_SERENADE_OF_WATER,
GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT,
GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW,
GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT,
/*** Adult Trade ***/
// Opt: *EnNiwLady
GI_VB_TRADE_POCKET_CUCCO,
// Opt: *EnHs
GI_VB_TRADE_COJIRO,
// Opt: *EnDs
GI_VB_TRADE_ODD_MUSHROOM,
// Opt: *EnKo
GI_VB_TRADE_ODD_POTION,
// Opt: *EnToryo
GI_VB_TRADE_SAW,
// Opt: *EnKz,
GI_VB_TRADE_PRESCRIPTION,
// Opt: *EnMk
GI_VB_TRADE_FROG,
GI_VB_TRADE_TIMER_ODD_MUSHROOM,
GI_VB_TRADE_TIMER_EYEDROPS,
GI_VB_TRADE_TIMER_FROG,
// Opt: *EnNiwLady
GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM,
/*** Fixes ***/
// Vanilla condition: false
GI_VB_FIX_SAW_SOFTLOCK,
} GIVanillaBehavior;
#ifdef __cplusplus
extern "C" {
#endif
@ -213,6 +507,8 @@ public:
DEFINE_HOOK(OnPlayDestroy, void());
DEFINE_HOOK(OnPlayDrawEnd, void());
DEFINE_HOOK(OnVanillaBehavior, void(GIVanillaBehavior flag, bool* result, void* opt));
DEFINE_HOOK(OnSaveFile, void(int32_t fileNum));
DEFINE_HOOK(OnLoadFile, void(int32_t fileNum));
DEFINE_HOOK(OnDeleteFile, void(int32_t fileNum));

View File

@ -90,6 +90,11 @@ void GameInteractor_ExecuteOnPlayDrawEnd() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayDrawEnd>();
}
bool GameInteractor_Should(GIVanillaBehavior flag, bool result, void* opt) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnVanillaBehavior>(flag, &result, opt);
return result;
}
// MARK: - Save Files
void GameInteractor_ExecuteOnSaveFile(int32_t fileNum) {

View File

@ -27,6 +27,7 @@ void GameInteractor_ExecuteOnOcarinaSongAction();
void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price);
void GameInteractor_ExecuteOnPlayDestroy();
void GameInteractor_ExecuteOnPlayDrawEnd();
bool GameInteractor_Should(GIVanillaBehavior flag, bool result, void* opt);
// MARK: - Save Files
void GameInteractor_ExecuteOnSaveFile(int32_t fileNum);

View File

@ -10,6 +10,8 @@
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
#include <soh/Enhancements/item-tables/ItemTableManager.h>
#include "soh/Enhancements/nametag.h"
#include "soh/Enhancements/timesaver_hook_handlers.h"
#include "soh/Enhancements/randomizer/hook_handlers.h"
#include "objects/object_gi_compass/object_gi_compass.h"
#include "src/overlays/actors/ovl_En_Bb/z_en_bb.h"
@ -1707,6 +1709,8 @@ void RegisterRandomizerCompasses() {
}
void InitMods() {
RandomizerRegisterHooks();
TimeSaverRegisterHooks();
RegisterTTS();
RegisterInfiniteMoney();
RegisterInfiniteHealth();

View File

@ -280,6 +280,18 @@ const std::vector<const char*> enhancementsCvars = {
"gPermanentHeartLoss",
"gRemoveExplosiveLimit",
"gToggleStrength",
"gTimeSavers.SkipCutscene.Intro",
"gTimeSavers.SkipCutscene.Entrances",
"gTimeSavers.SkipCutscene.Story",
"gTimeSavers.SkipCutscene.LearnSong",
"gTimeSavers.SkipCutscene.BossIntro",
"gTimeSavers.SkipCutscene.GlitchAiding",
"gTimeSavers.SkipCutscene.OnePoint",
"gTimeSavers.NoForcedDialog",
"gTimeSavers.SkipOwlInteractions",
"gTimeSavers.SkipMiscInteractions",
"gTimeSavers.DisableTitleCard",
"gTimeSavers.SkipGetItemAnimation",
};
const std::vector<const char*> cheatCvars = {

View File

@ -1127,7 +1127,19 @@ int Fill() {
std::vector<RandomizerGet> remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; });
FastFill(remainingPool, GetAllEmptyLocations(), false);
//Add prices for scrubsanity, this is unique to SoH because we write/read scrub prices to/from the spoilerfile.
//Add default prices to scrubs
for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) {
if (Rando::StaticData::scrubLocations[i] == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || Rando::StaticData::scrubLocations[i] == RC_LW_DEKU_SCRUB_GROTTO_FRONT) {
ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(40);
} else if (Rando::StaticData::scrubLocations[i] == RC_HF_DEKU_SCRUB_GROTTO) {
ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(10);
} else {
auto loc = Rando::StaticData::GetLocation(Rando::StaticData::scrubLocations[i]);
auto item = Rando::StaticData::RetrieveItem(loc->GetVanillaItem());
ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(item.GetPrice());
}
}
if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_AFFORDABLE)) {
for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) {
ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(10);

View File

@ -904,11 +904,16 @@ void GenerateItemPool() {
} else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK)) {
AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY); // 1 key which will behave as a pack of 6
} else {
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, false, true);
};
if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) {

View File

@ -234,11 +234,11 @@ void AreaTable_Init_CastleTown() {
//Locations
LocationAccess(RC_GREG_HINT, {[]{return true;}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_REWARD, {[]{return logic->ChildsWallet && ((logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
}, {
//Exits
Entrance(RR_THE_MARKET, {[]{return true;}}),

View File

@ -18,16 +18,12 @@ typedef enum {
SPOILER_CHK_ITEM_GET_INF,
SPOILER_CHK_EVENT_CHK_INF,
SPOILER_CHK_INF_TABLE,
SPOILER_CHK_COW,
SPOILER_CHK_FISH,
SPOILER_CHK_MINIGAME,
SPOILER_CHK_SCRUB,
SPOILER_CHK_GERUDO_MEMBERSHIP_CARD,
SPOILER_CHK_POE_POINTS,
SPOILER_CHK_SHOP_ITEM,
SPOILER_CHK_MAGIC_BEANS,
SPOILER_CHK_MASTER_SWORD,
SPOILER_CHK_MERCHANT,
SPOILER_CHK_GRAVEDIGGER,
SPOILER_CHK_RANDOMIZER_INF,
} SpoilerCollectionCheckType;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
#ifndef RANDOMIZER_HOOK_HANDLERS_H
#define RANDOMIZER_HOOK_HANDLERS_H
void RandomizerRegisterHooks();
#endif // RANDOMIZER_HOOK_HANDLERS_H

View File

@ -101,6 +101,18 @@ void ItemLocation::SetCustomPrice(const uint16_t price_) {
hasCustomPrice = true;
}
bool ItemLocation::HasObtained() const {
return obtained;
}
void ItemLocation::MarkAsObtained() {
obtained = true;
}
void ItemLocation::MarkAsNotObtained() {
obtained = false;
}
bool ItemLocation::IsHintable() const {
return isHintable;
}
@ -201,5 +213,6 @@ void ItemLocation::ResetVariables() {
wothCandidate = false;
barrenCandidate = false;
area = RA_NONE;
obtained = false;
}
}

View File

@ -31,6 +31,9 @@ class ItemLocation {
void SetPrice(uint16_t price_);
bool HasCustomPrice() const;
void SetCustomPrice(uint16_t price_);
bool HasObtained() const;
void MarkAsObtained();
void MarkAsNotObtained();
bool IsHintable() const;
void SetAsHintable();
bool IsHintedAt() const;
@ -67,5 +70,6 @@ class ItemLocation {
bool visibleInImGui = false;
bool wothCandidate = false;
bool barrenCandidate = false;
bool obtained = false;
};
} // namespace Rando

View File

@ -16,10 +16,10 @@ class SpoilerCollectionCheck {
public:
SpoilerCollectionCheckType type = SPOILER_CHK_NONE;
uint8_t scene = 0;
uint8_t flag = 0;
uint16_t flag = 0;
SpoilerCollectionCheck() = default;
SpoilerCollectionCheck(const SpoilerCollectionCheckType type_, const uint8_t scene_, const uint8_t flag_)
SpoilerCollectionCheck(const SpoilerCollectionCheckType type_, const uint8_t scene_, const uint16_t flag_)
: type(type_), scene(scene_), flag(flag_) {
}
@ -39,8 +39,8 @@ class SpoilerCollectionCheck {
return SpoilerCollectionCheck(SPOILER_CHK_EVENT_CHK_INF, 0xFF, flag);
}
static auto InfTable(const uint8_t offset, const uint8_t bit) {
return SpoilerCollectionCheck(SPOILER_CHK_INF_TABLE, offset, bit);
static auto InfTable(const uint16_t flag) {
return SpoilerCollectionCheck(SPOILER_CHK_INF_TABLE, 0xFF, flag);
}
static auto Collectable(const uint8_t scene, const uint8_t flag) {
@ -51,10 +51,6 @@ class SpoilerCollectionCheck {
return SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene, flag);
}
static auto Cow(const uint8_t scene, const uint8_t flag) {
return SpoilerCollectionCheck(SPOILER_CHK_COW, scene, flag);
}
static auto Fish(const uint8_t flag, const uint8_t scene = SCENE_FISHING_POND) {
return SpoilerCollectionCheck(SPOILER_CHK_FISH, scene, flag);
}
@ -63,10 +59,6 @@ class SpoilerCollectionCheck {
return SpoilerCollectionCheck(SPOILER_CHK_MINIGAME, 0x00, bit);
}
static auto Scrub(const uint8_t scene, const uint8_t bit) {
return SpoilerCollectionCheck(SPOILER_CHK_SCRUB, scene, bit);
}
static auto GerudoToken() {
return SpoilerCollectionCheck(SPOILER_CHK_GERUDO_MEMBERSHIP_CARD, 0x00, 0x00);
}
@ -83,20 +75,12 @@ class SpoilerCollectionCheck {
return SpoilerCollectionCheck(SPOILER_CHK_SHOP_ITEM, scene, itemSlot);
}
static auto MagicBeans(const uint8_t scene, const uint8_t flag) {
return SpoilerCollectionCheck(SPOILER_CHK_MAGIC_BEANS, scene, flag);
}
static auto MasterSword() {
return SpoilerCollectionCheck(SPOILER_CHK_MASTER_SWORD, 0x00, 0x00);
}
static auto Merchant(const int8_t scene, const uint8_t flag) {
return SpoilerCollectionCheck(SPOILER_CHK_MERCHANT, scene, flag);
}
static auto RandomizerInf(const int8_t scene, const uint8_t flag) {
return SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, scene, flag);
static auto RandomizerInf(const uint16_t flag) {
return SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, 0x00, flag);
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1649,21 +1649,28 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum,
RandomizerCheck specialRc = RC_UNKNOWN_CHECK;
// TODO: Migrate these special cases into table, or at least document why they are special
switch(sceneNum) {
case SCENE_TREASURE_BOX_SHOP:
if(actorParams == 20170) specialRc = RC_MARKET_TREASURE_CHEST_GAME_REWARD;
case SCENE_TREASURE_BOX_SHOP: {
if ((actorId == ACTOR_EN_BOX && actorParams == 20170) || (actorId == ACTOR_ITEM_ETCETERA && actorParams == 2572)) {
specialRc = RC_MARKET_TREASURE_CHEST_GAME_REWARD;
}
// RANDOTODO update logic to match 3ds rando when we implement keysanity
// keep keys og
if ((actorParams & 0x60) == 0x20) break;
if (GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
if((actorParams & 0xF) < 2) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_1;
if((actorParams & 0xF) < 4) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_2;
if((actorParams & 0xF) < 6) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_3;
if((actorParams & 0xF) < 8) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_4;
if((actorParams & 0xF) < 10) specialRc = RC_MARKET_TREASURE_CHEST_GAME_ITEM_5;
// todo: handle the itemetc part of this so drawing works when we implement shuffle
if (actorId == ACTOR_EN_BOX) {
bool isAKey = (actorParams & 0x60) == 0x20;
if ((actorParams & 0xF) < 2) {
specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_1 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_1;
} else if ((actorParams & 0xF) < 4) {
specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_2 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_2;
} else if ((actorParams & 0xF) < 6) {
specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_3 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_3;
} else if ((actorParams & 0xF) < 8) {
specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_4 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_4;
} else if ((actorParams & 0xF) < 10) {
specialRc = isAKey ? RC_MARKET_TREASURE_CHEST_GAME_KEY_5 : RC_MARKET_TREASURE_CHEST_GAME_ITEM_5;
}
}
break;
}
case SCENE_SACRED_FOREST_MEADOW:
if (actorId == ACTOR_EN_SA) {
specialRc = RC_SONG_FROM_SARIA;

View File

@ -733,6 +733,11 @@ typedef enum {
RC_MARKET_TREASURE_CHEST_GAME_ITEM_3,
RC_MARKET_TREASURE_CHEST_GAME_ITEM_4,
RC_MARKET_TREASURE_CHEST_GAME_ITEM_5,
RC_MARKET_TREASURE_CHEST_GAME_KEY_1,
RC_MARKET_TREASURE_CHEST_GAME_KEY_2,
RC_MARKET_TREASURE_CHEST_GAME_KEY_3,
RC_MARKET_TREASURE_CHEST_GAME_KEY_4,
RC_MARKET_TREASURE_CHEST_GAME_KEY_5,
RC_MARKET_GS_GUARD_HOUSE,
RC_MARKET_BAZAAR_ITEM_1,
RC_MARKET_BAZAAR_ITEM_2,
@ -2332,6 +2337,11 @@ typedef enum {
RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3,
RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4,
RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5,
RHT_MARKET_TREASURE_CHEST_GAME_KEY_1,
RHT_MARKET_TREASURE_CHEST_GAME_KEY_2,
RHT_MARKET_TREASURE_CHEST_GAME_KEY_3,
RHT_MARKET_TREASURE_CHEST_GAME_KEY_4,
RHT_MARKET_TREASURE_CHEST_GAME_KEY_5,
RHT_MARKET_GS_GUARD_HOUSE,
RHT_MARKET_BAZAAR_ITEM_1,
RHT_MARKET_BAZAAR_ITEM_2,

View File

@ -419,11 +419,8 @@ bool HasItemBeenCollected(RandomizerCheck rc) {
case SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE:
return (gPlayState->sceneNum == scene && gPlayState->actorCtx.flags.collect & (1 << flag)) ||
gSaveContext.sceneFlags[scene].collect & (1 << flag);
case SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT:
case SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM:
case SpoilerCollectionCheckType::SPOILER_CHK_COW:
case SpoilerCollectionCheckType::SPOILER_CHK_FISH:
case SpoilerCollectionCheckType::SPOILER_CHK_SCRUB:
case SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF:
case SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD:
return Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc));
@ -437,8 +434,6 @@ bool HasItemBeenCollected(RandomizerCheck rc) {
return gSaveContext.infTable[scene] & INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(flag);
case SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF:
return gSaveContext.itemGetInf[flag / 16] & INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(flag);
case SpoilerCollectionCheckType::SPOILER_CHK_MAGIC_BEANS:
return BEANS_BOUGHT >= 10;
case SpoilerCollectionCheckType::SPOILER_CHK_NONE:
return false;
case SpoilerCollectionCheckType::SPOILER_CHK_GRAVEDIGGER:
@ -749,11 +744,8 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) {
Rando::SpoilerCollectionCheck scCheck = loc.GetCollectionCheck();
SpoilerCollectionCheckType scCheckType = scCheck.type;
if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF &&
(scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_COW ||
(scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_FISH ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SCRUB ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF)) {
if (flag == OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(loc.GetRandomizerCheck())) {
@ -1342,6 +1334,11 @@ void DrawLocation(RandomizerCheck rc) {
Rando::ItemLocation* itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
RandomizerCheckTrackerData checkData = gSaveContext.checkTrackerData[rc];
RandomizerCheckStatus status = checkData.status;
if (itemLoc->HasObtained()) {
status = RCSHOW_COLLECTED;
}
bool skipped = checkData.skipped;
if (status == RCSHOW_COLLECTED) {
if (!showHidden && CVarGetInteger("gCheckTrackerCollectedHide", 0)) {
@ -1676,12 +1673,12 @@ void CheckTrackerWindow::InitElement() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnExitGame>([](uint32_t fileNum) {
Teardown();
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>(CheckTrackerItemReceive);
// GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>(CheckTrackerItemReceive);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>(CheckTrackerFrame);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnTransitionEnd>(CheckTrackerTransition);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnShopSlotChange>(CheckTrackerShopSlotChange);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneFlagSet>(CheckTrackerSceneFlagSet);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnFlagSet>(CheckTrackerFlagSet);
// GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneFlagSet>(CheckTrackerSceneFlagSet);
// GameInteractor::Instance->RegisterGameHook<GameInteractor::OnFlagSet>(CheckTrackerFlagSet);
hideShopRightChecks = CVarGetInteger("gCheckTrackerOptionHideRightShopChecks", 1);
alwaysShowGS = CVarGetInteger("gCheckTrackerOptionAlwaysShowGSLocs", 0);

View File

@ -448,34 +448,31 @@ void Entrance_SetWarpSongEntrance(void) {
}
void Entrance_OverrideBlueWarp(void) {
// Set nextEntranceIndex as a flag so that Grotto_CheckSpecialEntrance
// won't return index 0x7FFF, which can't work to override blue warps.
gPlayState->nextEntranceIndex = 0;
// Handles first time entering bluewarp (with item give)
switch (gSaveContext.entranceIndex) {
case ENTR_KOKIRI_FOREST_11: // Gohma blue warp
case ENTR_DEATH_MOUNTAIN_TRAIL_5: // KD blue warp
case ENTR_ZORAS_FOUNTAIN_0: // Barinade blue warp
case ENTR_SACRED_FOREST_MEADOW_3: // Phantom Ganon blue warp
case ENTR_DEATH_MOUNTAIN_CRATER_5: // Volvagia blue warp
case ENTR_LAKE_HYLIA_9: // Morpha blue warp
case ENTR_DESERT_COLOSSUS_8: // Bongo-Bongo blue warp
case ENTR_GRAVEYARD_8: // Twinrova blue warp
gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex);
return;
}
switch (gPlayState->sceneNum) {
case SCENE_DEKU_TREE_BOSS: // Ghoma boss room
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_KOKIRI_FOREST_11);
return;
case SCENE_DODONGOS_CAVERN_BOSS: // King Dodongo boss room
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DEATH_MOUNTAIN_TRAIL_5);
return;
case SCENE_JABU_JABU_BOSS: // Barinade boss room
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_ZORAS_FOUNTAIN_0);
return;
case SCENE_FOREST_TEMPLE_BOSS: // Phantom Ganon boss room
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_SACRED_FOREST_MEADOW_3);
return;
case SCENE_FIRE_TEMPLE_BOSS: // Volvagia boss room
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DEATH_MOUNTAIN_CRATER_5);
return;
case SCENE_WATER_TEMPLE_BOSS: // Morpha boss room
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_9);
return;
case SCENE_SPIRIT_TEMPLE_BOSS: // Twinrova boss room
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DESERT_COLOSSUS_8);
return;
case SCENE_SHADOW_TEMPLE_BOSS: // Bongo-Bongo boss room
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_GRAVEYARD_8);
// Handles second+ times entering bluewarp
switch (gPlayState->nextEntranceIndex) {
case ENTR_KOKIRI_FOREST_11: // Gohma blue warp
case ENTR_DEATH_MOUNTAIN_TRAIL_5: // KD blue warp
case ENTR_ZORAS_FOUNTAIN_0: // Barinade blue warp
case ENTR_SACRED_FOREST_MEADOW_3: // Phantom Ganon blue warp
case ENTR_DEATH_MOUNTAIN_CRATER_5: // Volvagia blue warp
case ENTR_LAKE_HYLIA_9: // Morpha blue warp
case ENTR_DESERT_COLOSSUS_8: // Bongo-Bongo blue warp
case ENTR_GRAVEYARD_8: // Twinrova blue warp
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(gPlayState->nextEntranceIndex);
return;
}
}

View File

@ -143,12 +143,15 @@ typedef enum {
RAND_INF_MERCHANTS_CARPET_SALESMAN,
RAND_INF_MERCHANTS_MEDIGORON,
RAND_INF_MERCHANTS_GRANNYS_SHOP,
RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN,
RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO,
RAND_INF_ADULT_TRADES_GV_TRADE_SAW,
RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD,
RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION,
RAND_INF_ADULT_TRADES_LH_TRADE_FROG,
RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS,
RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK,
RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD,
@ -267,6 +270,29 @@ typedef enum {
RAND_INF_ZD_FISH_4,
RAND_INF_ZD_FISH_5,
RAND_INF_LINKS_POCKET,
RAND_INF_LEARNED_EPONA_SONG,
RAND_INF_DARUNIAS_JOY,
RAND_INF_KING_ZORA_THAWED,
RAND_INF_HC_GREAT_FAIRY_REWARD,
RAND_INF_DMT_GREAT_FAIRY_REWARD,
RAND_INF_DMC_GREAT_FAIRY_REWARD,
RAND_INF_ZF_GREAT_FAIRY_REWARD,
RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD,
RAND_INF_OGC_GREAT_FAIRY_REWARD,
RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1,
RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2,
RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3,
RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4,
RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5,
RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1,
RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2,
RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3,
RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4,
RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5,
// If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16)
RAND_INF_MAX,

View File

@ -97,6 +97,9 @@ void GiveLinksPocketItem() {
if (Randomizer_GetSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, (GetItemID)RG_NONE);
StartingItemGive(getItemEntry);
Rando::Context::GetInstance()->GetItemLocation(RC_LINKS_POCKET)->MarkAsObtained();
// If we re-add the above, we'll get the item on save creation, now it's given on first load
Flags_SetRandomizerInf(RAND_INF_LINKS_POCKET);
}
}
@ -202,95 +205,102 @@ void SetStartingItems() {
}
extern "C" void Randomizer_InitSaveFile() {
// Sets all rando flags to false
for (s32 i = 0; i < ARRAY_COUNT(gSaveContext.randomizerInf); i++) {
gSaveContext.randomizerInf[i] = 0;
}
// Now handled by cutscene skips
// gSaveContext.cutsceneIndex = 0; // no intro cutscene
// Starts pending ice traps out at 0 before potentially incrementing them down the line.
gSaveContext.pendingIceTrapCount = 0;
// Reset triforce pieces collected
gSaveContext.triforcePiecesCollected = 0;
gSaveContext.cutsceneIndex = 0; // no intro cutscene
// Starts pending ice traps out at 0 before potentially incrementing them down the line.
gSaveContext.pendingIceTrapCount = 0;
// Set Cutscene flags and texts to skip them
Flags_SetInfTable(INFTABLE_GREETED_BY_SARIA);
// Now handled by cutscene skips
// Flags_SetInfTable(INFTABLE_GREETED_BY_SARIA);
Flags_SetEventChkInf(EVENTCHKINF_FIRST_SPOKE_TO_MIDO);
Flags_SetEventChkInf(EVENTCHKINF_MET_DEKU_TREE);
Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH);
// Now handled by cutscene skips
// Flags_SetEventChkInf(EVENTCHKINF_MET_DEKU_TREE);
// Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH);
Flags_SetInfTable(INFTABLE_SPOKE_TO_KAEPORA_IN_LAKE_HYLIA);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER);
Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL);
// Now handled by cutscene skips
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER);
// Now using this to grant master sword check
// Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL);
Flags_SetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL);
Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
// Now used to give player LACS rewards
// Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
Flags_SetEventChkInf(EVENTCHKINF_RENTED_HORSE_FROM_INGO);
Flags_SetInfTable(INFTABLE_SPOKE_TO_POE_COLLECTOR_IN_RUINED_MARKET);
Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO);
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_NABOORU_IN_SPIRIT_TEMPLE);
Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET);
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET);
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_INGO_AT_RANCH_BEFORE_TALON_RETURNS);
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_RANCH);
Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON);
Flags_SetInfTable(INFTABLE_CHILD_MALON_SAID_EPONA_WAS_AFRAID_OF_YOU);
Flags_SetInfTable(INFTABLE_SPOKE_TO_INGO_ONCE_AS_ADULT);
// Now handled by cutscene skips
// Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET);
// Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET);
// Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_INGO_AT_RANCH_BEFORE_TALON_RETURNS);
// Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_RANCH);
// Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON);
// Flags_SetInfTable(INFTABLE_CHILD_MALON_SAID_EPONA_WAS_AFRAID_OF_YOU);
// Flags_SetInfTable(INFTABLE_SPOKE_TO_INGO_ONCE_AS_ADULT);
// Ruto already met in jabu and spawns down the hole immediately
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO);
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME);
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE);
// Now handled by cutscene skips
// Skip cutscenes before Nabooru fight
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_NABOORU_BATTLE);
Flags_SetEventChkInf(EVENTCHKINF_NABOORU_ORDERED_TO_FIGHT_BY_TWINROVA);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_NABOORU_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_NABOORU_ORDERED_TO_FIGHT_BY_TWINROVA);
// Now handled by cutscene skips
// Skip boss cutscenes
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE);
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE);
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE);
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE);
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE);
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE);
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE);
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE);
// Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE);
// Entered areas
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_FIELD);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_TRAIL);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_KAKARIKO_VILLAGE);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_DOMAIN);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_CASTLE);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GORON_CITY);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_TEMPLE_OF_TIME);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEKU_TREE);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LAKE_HYLIA);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDO_VALLEY);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDOS_FORTRESS);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LON_LON_RANCH);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_JABU_JABUS_BELLY);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GRAVEYARD);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_FOUNTAIN);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DESERT_COLOSSUS);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_CRATER);
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GANONS_CASTLE_EXTERIOR);
Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE);
// Now handled by cutscene skips
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_FIELD);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_TRAIL);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_KAKARIKO_VILLAGE);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_DOMAIN);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_CASTLE);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GORON_CITY);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_TEMPLE_OF_TIME);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEKU_TREE);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LAKE_HYLIA);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDO_VALLEY);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDOS_FORTRESS);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LON_LON_RANCH);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_JABU_JABUS_BELLY);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GRAVEYARD);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_FOUNTAIN);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DESERT_COLOSSUS);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_CRATER);
// Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GANONS_CASTLE_EXTERIOR);
// Ensure Malon appears at castle first time you enter
// Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE);
// skip the z target talk instructions by the kokiri shop
gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 0x1F);
// Now handled by cutscene skips
// gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 0x1F);
// Go away ruto (water temple first cutscene)
gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10);
// Now handled by cutscene skips
// no more kaepora
gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xC); // hyrule field kaepora outside kokiri forest
gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xB); // hyrule field kaepora outside lake hylia
gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x7); // lost woods kaepora pre-saria
gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x8); // lost woods kaepora post-saria
gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 0x1F); // desert colossus kaepora
gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= (1 << 0x5); // hyrule castle kaepora
// gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xC); // hyrule field kaepora outside kokiri forest
// gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xB); // hyrule field kaepora outside lake hylia
// gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x7); // lost woods kaepora pre-saria
// gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x8); // lost woods kaepora post-saria
// gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 0x1F); // desert colossus kaepora
// gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= (1 << 0x5); // hyrule castle kaepora
if (!Randomizer_GetSettingValue(RSK_ENABLE_GLITCH_CUTSCENES)) {
Flags_SetInfTable(INFTABLE_SPOKE_TO_DARUNIA_IN_FIRE_TEMPLE); // Darunia in Fire Temple
@ -398,15 +408,16 @@ extern "C" void Randomizer_InitSaveFile() {
gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x15);
}
int openForest = Randomizer_GetSettingValue(RSK_FOREST);
switch (openForest) {
case RO_FOREST_OPEN:
Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD);
// Fallthrough
case RO_FOREST_CLOSED_DEKU:
Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD);
break;
}
// Now handled on the fly
// int openForest = Randomizer_GetSettingValue(RSK_FOREST);
// switch (openForest) {
// case RO_FOREST_OPEN:
// Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD);
// // Fallthrough
// case RO_FOREST_CLOSED_DEKU:
// Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD);
// break;
// }
int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME);
switch (doorOfTime) {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
#ifndef TIMESAVER_HOOK_HANDLERS_H
#define TIMESAVER_HOOK_HANDLERS_H
void TimeSaverRegisterHooks();
#endif // TIMESAVER_HOOK_HANDLERS_H

View File

@ -124,6 +124,10 @@ GameInteractorSail* GameInteractorSail::Instance;
#include "soh/config/ConfigUpdaters.h"
extern "C" {
#include "src/overlays/actors/ovl_En_Dns/z_en_dns.h"
}
void SoH_ProcessDroppedFiles(std::string filePath);
OTRGlobals* OTRGlobals::Instance;
@ -2563,9 +2567,9 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
} else if (textId == TEXT_SHEIK_NEED_HOOK || textId == TEXT_SHEIK_HAVE_HOOK) {
messageEntry = OTRGlobals::Instance->gRandomizer->GetSheikMessage(gPlayState->sceneNum, textId);
// textId: TEXT_SCRUB_RANDOM + (randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT)
} else if (textId >= TEXT_SCRUB_RANDOM && textId <= TEXT_SCRUB_RANDOM + NUM_SCRUBS) {
RandomizerInf randoInf = (RandomizerInf)((textId - TEXT_SCRUB_RANDOM) + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT);
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, TEXT_SCRUB_RANDOM, Randomizer_GetSettingValue(RSK_SCRUB_TEXT_HINT) == RO_GENERIC_OFF);
} else if (textId == TEXT_SCRUB_RANDOM) {
EnDns* enDns = (EnDns*)GET_PLAYER(play)->targetActor;
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(enDns->sohScrubIdentity.randomizerInf, TEXT_SCRUB_RANDOM, Randomizer_GetSettingValue(RSK_SCRUB_TEXT_HINT) == RO_GENERIC_OFF);
// Shop items each have two message entries, second one offset by NUM_SHOP_ITEMS
// textId: TEXT_SHOP_ITEM_RANDOM + (randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1)
// textId: TEXT_SHOP_ITEM_RANDOM + ((randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) + NUM_SHOP_ITEMS)

View File

@ -352,6 +352,13 @@ void SaveManager::LoadRandomizerVersion3() {
// all ItemLocations is 0 anyway.
randoContext->GetItemLocation(i)->SetCustomPrice(price);
}
uint16_t obtained = 0;
SaveManager::Instance->LoadData("obtained", obtained, (uint16_t)0);
if (obtained) {
randoContext->GetItemLocation(i)->MarkAsObtained();
} else {
randoContext->GetItemLocation(i)->MarkAsNotObtained();
}
});
});
@ -450,6 +457,7 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
if (randoContext->GetItemLocation(i)->HasCustomPrice()) {
SaveManager::Instance->SaveData("price", randoContext->GetItemLocation(i)->GetPrice());
}
SaveManager::Instance->SaveData("obtained", randoContext->GetItemLocation(i)->HasObtained());
});
});
@ -728,6 +736,9 @@ void SaveManager::InitFileNormal() {
for (int flag = 0; flag < ARRAY_COUNT(gSaveContext.infTable); flag++) {
gSaveContext.infTable[flag] = 0;
}
for (int flag = 0; flag < ARRAY_COUNT(gSaveContext.randomizerInf); flag++) {
gSaveContext.randomizerInf[flag] = 0;
}
gSaveContext.worldMapAreaData = 0;
gSaveContext.scarecrowLongSongSet = 0;
for (int i = 0; i < ARRAY_COUNT(gSaveContext.scarecrowLongSong); i++) {

View File

@ -72,6 +72,7 @@ static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large
};
static const char* chestStyleMatchesContentsOptions[4] = { "Disabled", "Both", "Texture Only", "Size Only" };
static const char* skipGetItemAnimationOptions[3] = { "Disabled", "Junk Items", "All Items" };
static const char* bunnyHoodOptions[3] = { "Disabled", "Faster Run & Longer Jump", "Faster Run" };
static const char* mirroredWorldModes[9] = {
"Disabled", "Always", "Random", "Random (Seeded)", "Dungeons",
@ -574,6 +575,83 @@ void DrawEnhancementsMenu() {
UIWidgets::Spacer(0);
ImGui::Text("Speed-ups:");
UIWidgets::PaddedSeparator();
bool allChecked =
CVarGetInteger("gTimeSavers.SkipCutscene.Intro", IS_RANDO) &&
CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) &&
CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) &&
CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) &&
CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) &&
CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", IS_RANDO) &&
CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) &&
CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) &&
CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) &&
CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) &&
CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO);
bool someChecked =
CVarGetInteger("gTimeSavers.SkipCutscene.Intro", IS_RANDO) ||
CVarGetInteger("gTimeSavers.SkipCutscene.Entrances", IS_RANDO) ||
CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO) ||
CVarGetInteger("gTimeSavers.SkipCutscene.LearnSong", IS_RANDO) ||
CVarGetInteger("gTimeSavers.SkipCutscene.BossIntro", IS_RANDO) ||
CVarGetInteger("gTimeSavers.SkipCutscene.GlitchAiding", IS_RANDO) ||
CVarGetInteger("gTimeSavers.SkipCutscene.OnePoint", IS_RANDO) ||
CVarGetInteger("gTimeSavers.NoForcedDialog", IS_RANDO) ||
CVarGetInteger("gTimeSavers.SkipOwlInteractions", IS_RANDO) ||
CVarGetInteger("gTimeSavers.SkipMiscInteractions", IS_RANDO) ||
CVarGetInteger("gTimeSavers.DisableTitleCard", IS_RANDO);
ImGuiContext* g = ImGui::GetCurrentContext();
ImGuiItemFlags backup_item_flags = g->CurrentItemFlags;
if (!allChecked && someChecked) g->CurrentItemFlags |= ImGuiItemFlags_MixedValue;
if (ImGui::Checkbox("All", &allChecked)) {
if (allChecked) {
CVarSetInteger("gTimeSavers.SkipCutscene.Intro", 1);
CVarSetInteger("gTimeSavers.SkipCutscene.Entrances", 1);
CVarSetInteger("gTimeSavers.SkipCutscene.Story", 1);
CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 1);
CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 1);
CVarSetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 1);
CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 1);
CVarSetInteger("gTimeSavers.NoForcedDialog", 1);
CVarSetInteger("gTimeSavers.SkipOwlInteractions", 1);
CVarSetInteger("gTimeSavers.SkipMiscInteractions", 1);
CVarSetInteger("gTimeSavers.DisableTitleCard", 1);
} else {
CVarSetInteger("gTimeSavers.SkipCutscene.Intro", 0);
CVarSetInteger("gTimeSavers.SkipCutscene.Entrances", 0);
CVarSetInteger("gTimeSavers.SkipCutscene.Story", 0);
CVarSetInteger("gTimeSavers.SkipCutscene.LearnSong", 0);
CVarSetInteger("gTimeSavers.SkipCutscene.BossIntro", 0);
CVarSetInteger("gTimeSavers.SkipCutscene.GlitchAiding", 0);
CVarSetInteger("gTimeSavers.SkipCutscene.OnePoint", 0);
CVarSetInteger("gTimeSavers.NoForcedDialog", 0);
CVarSetInteger("gTimeSavers.SkipOwlInteractions", 0);
CVarSetInteger("gTimeSavers.SkipMiscInteractions", 0);
CVarSetInteger("gTimeSavers.DisableTitleCard", 0);
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
g->CurrentItemFlags = backup_item_flags;
UIWidgets::PaddedEnhancementCheckbox("Skip Intro", "gTimeSavers.SkipCutscene.Intro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedEnhancementCheckbox("Skip Entrance Cutscenes", "gTimeSavers.SkipCutscene.Entrances", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedEnhancementCheckbox("Skip Story Cutscenes", "gTimeSavers.SkipCutscene.Story", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedEnhancementCheckbox("Skip Song Cutscenes", "gTimeSavers.SkipCutscene.LearnSong", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedEnhancementCheckbox("Skip Boss Introductions", "gTimeSavers.SkipCutscene.BossIntro", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::Tooltip("Skip cutscenes that are associated with useful glitches, currently this is only the Fire Temple Darunia CS and Forest Temple Poe Sisters CS");
UIWidgets::PaddedEnhancementCheckbox("Skip One Point Cutscenes (Chests, Door Unlocks, etc)", "gTimeSavers.SkipCutscene.OnePoint", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedEnhancementCheckbox("No Forced Dialog", "gTimeSavers.NoForcedDialog", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::Tooltip("Prevent forced conversations with Navi or other NPCs");
UIWidgets::PaddedEnhancementCheckbox("Skip Owl Interactions", "gTimeSavers.SkipOwlInteractions", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedEnhancementCheckbox("Skip Misc Interactions", "gTimeSavers.SkipMiscInteractions", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedEnhancementCheckbox("Disable Title Card", "gTimeSavers.DisableTitleCard", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
UIWidgets::PaddedText("Skip Get Item Animations", true, false);
UIWidgets::EnhancementCombobox("gTimeSavers.SkipGetItemAnimation", skipGetItemAnimationOptions, SGIA_DISABLED);
if (CVarGetInteger("gTimeSavers.SkipGetItemAnimation", SGIA_DISABLED) != SGIA_DISABLED) {
UIWidgets::EnhancementSliderFloat("Item Scale: %f", "##ItemScale", "gTimeSavers.SkipGetItemAnimationScale", 5.0f, 15.0f, "", 10.0f, false);
UIWidgets::Tooltip("The size of the item when it is picked up");
}
UIWidgets::PaddedEnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "", 1, true, false, true);
UIWidgets::PaddedEnhancementCheckbox("Skip Text", "gSkipText", false, true);
@ -605,7 +683,7 @@ void DrawEnhancementsMenu() {
UIWidgets::Spacer(0);
ImGui::Text("Changes:");
UIWidgets::PaddedSeparator();
UIWidgets::PaddedEnhancementSliderInt("Biggoron Forge Time: %d days", "##FORGETIME", "gForgeTime", 0, 3, "", 3, true, false, true);
UIWidgets::Tooltip("Allows you to change the number of days it takes for Biggoron to forge the Biggoron Sword");
UIWidgets::PaddedEnhancementCheckbox("Remember Save Location", "gRememberSaveLocation", false, false);
@ -1208,7 +1286,8 @@ void DrawEnhancementsMenu() {
UIWidgets::Tooltip("Removes the dungeon entrance icon on the top-left corner of the screen when no dungeon is present on the current map");
UIWidgets::PaddedEnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle", true, false);
UIWidgets::Tooltip("Re-enables the two-handed idle animation, a seemingly finished animation that was disabled on accident in the original game");
UIWidgets::PaddedEnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix", true, false);
UIWidgets::PaddedEnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix", true, false, SaveManager::Instance->IsRandoFile(),
"This setting is always enabled in randomizer files", UIWidgets::CheckboxGraphics::Checkmark);
UIWidgets::Tooltip("Fixes a bug where the Gravedigging Tour Heart Piece disappears if the area reloads");
UIWidgets::PaddedEnhancementCheckbox("Fix Deku Nut upgrade", "gDekuNutUpgradeFix", true, false);
UIWidgets::Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw");

View File

@ -1462,7 +1462,7 @@ s32 func_8002DF38(PlayState* play, Actor* actor, u8 csAction) {
return true;
}
s32 func_8002DF54(PlayState* play, Actor* actor, u8 csAction) {
s32 Player_SetCsActionWithHaltedActors(PlayState* play, Actor* actor, u8 csAction) {
Player* player = GET_PLAYER(play);
func_8002DF38(play, actor, csAction);
@ -2084,9 +2084,8 @@ s32 GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemE
return GiveItemEntryFromActor(actor, play, getItemEntry, 50.0f, 10.0f);
}
// TODO: Rename to GiveItemIdFromActor or similar
// If you're doing something for randomizer, you're probably looking for GiveItemEntryFromActor
s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange) {
s32 Actor_OfferGetItem(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange) {
Player* player = GET_PLAYER(play);
if (!(player->stateFlags1 &
@ -2116,7 +2115,7 @@ s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32
// TODO: Rename to GiveItemIdFromActorWithFixedRange or similar
// If you're doing something for randomizer, you're probably looking for GiveItemEntryFromActorWithFixedRange
void func_8002F554(Actor* actor, PlayState* play, s32 getItemId) {
func_8002F434(actor, play, getItemId, 50.0f, 10.0f);
Actor_OfferGetItem(actor, play, getItemId, 50.0f, 10.0f);
}
void func_8002F580(Actor* actor, PlayState* play) {
@ -6276,58 +6275,3 @@ s32 func_80038290(PlayState* play, Actor* actor, Vec3s* arg2, Vec3s* arg3, Vec3f
return true;
}
GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, PlayState* play) {
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
// RANDOTODO update this logic when we implement keysanity
// because 3drando replaces the keys not the rupees
if (ogDrawId == GID_RUPEE_GREEN ||
ogDrawId == GID_RUPEE_BLUE ||
ogDrawId == GID_RUPEE_RED)
{
switch(room) {
case 1:
if(!Flags_GetCollectible(play, 0x1B)) {
return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, GI_RUPEE_GREEN);
}
break;
case 2:
if(!Flags_GetCollectible(play, 0x1C)) {
return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, GI_RUPEE_GREEN);
}
break;
case 3:
if(!Flags_GetCollectible(play, 0x1D)) {
return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, GI_RUPEE_BLUE);
}
break;
case 4:
if(!Flags_GetCollectible(play, 0x1E)) {
return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, GI_RUPEE_BLUE);
}
break;
case 5:
if(!Flags_GetCollectible(play, 0x1F)) {
return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, GI_RUPEE_RED);
}
break;
}
}
}
if(ogDrawId == GID_HEART_PIECE) {
return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_REWARD, GI_HEART_PIECE);
}
return (GetItemEntry)GET_ITEM_NONE;
}
s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, PlayState* play) {
GetItemEntry randoGetItem = GetChestGameRandoGetItem(room, ogDrawId, play);
if (randoGetItem.itemId != ITEM_NONE) {
return randoGetItem.gid;
}
return ogDrawId;
}

View File

@ -6184,14 +6184,14 @@ s32 Camera_Demo5(Camera* camera) {
pad = camera->play->state.frames - sDemo5PrevAction12Frame;
if (player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) {
// holding object over head.
func_8002DF54(camera->play, camera->target, 8);
Player_SetCsActionWithHaltedActors(camera->play, camera->target, 8);
} else if (ABS(pad) > 3000) {
func_8002DF54(camera->play, camera->target, 12);
Player_SetCsActionWithHaltedActors(camera->play, camera->target, 12);
} else {
func_8002DF54(camera->play, camera->target, 69);
Player_SetCsActionWithHaltedActors(camera->play, camera->target, 69);
}
} else {
func_8002DF54(camera->play, camera->target, 1);
Player_SetCsActionWithHaltedActors(camera->play, camera->target, 1);
}
}
@ -6250,7 +6250,7 @@ s32 Camera_Demo6(Camera* camera) {
camera->animState++;
case 1:
if (stateTimers[camera->animState] < anim->animTimer) {
func_8002DF54(camera->play, &camera->player->actor, 8);
Player_SetCsActionWithHaltedActors(camera->play, &camera->player->actor, 8);
Actor_GetWorld(&focusPosRot, camFocus);
anim->atTarget.x = focusPosRot.pos.x;
anim->atTarget.y = focusPosRot.pos.y - 20.0f;
@ -7735,7 +7735,7 @@ void Camera_Finish(Camera* camera) {
player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE;
if (player->csAction != 0) {
func_8002DF54(camera->play, &player->actor, 7);
Player_SetCsActionWithHaltedActors(camera->play, &player->actor, 7);
osSyncPrintf("camera: player demo end!!\n");
}

View File

@ -32,6 +32,7 @@
#include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
u16 D_8011E1C0 = 0;
u16 D_8011E1C4 = 0;
@ -485,6 +486,7 @@ void func_80065134(PlayState* play, CutsceneContext* csCtx, CsCmdDayTime* cmd) {
gSaveContext.dayTime = temp1 + temp2;
gSaveContext.skyboxTime = temp1 + temp2;
LUSLOG_INFO("SET TIME %d", gSaveContext.dayTime);
}
}
@ -493,11 +495,16 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
Player* player = GET_PLAYER(play);
s32 temp = 0;
// Automatically skip certain cutscenes when in rando
// cmd->base == 8: Traveling back/forward in time cutscene
// cmd->base == 24: Dropping a fish for Jabu Jabu
// cmd->base == 33: Zelda escaping with impa cutscene
bool randoCsSkip = (IS_RANDO && (cmd->base == 8 || cmd->base == 24 || cmd->base == 33));
bool shouldSkipCommand = false;
if (cmd->base == 8 && !GameInteractor_Should(GI_VB_PLAY_PULL_MASTER_SWORD_CS, true, NULL)) {
shouldSkipCommand = true;
}
if (cmd->base == 24 && !GameInteractor_Should(GI_VB_PLAY_DROP_FISH_FOR_JABU_CS, true, NULL)) {
shouldSkipCommand = true;
}
bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) &&
(gSaveContext.fileNum != 0xFEDC) && CVarGetInteger("gDebugEnabled", 0));
@ -558,7 +565,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
}
}
if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (randoCsSkip || debugCsSkip))) {
if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (shouldSkipCommand || debugCsSkip))) {
csCtx->state = CS_STATE_UNSKIPPABLE_EXEC;
Audio_SetCutsceneFlag(0);
@ -624,7 +631,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
gSaveContext.fw.set = 0;
gSaveContext.respawn[RESPAWN_MODE_TOP].data = 0;
}
if (!Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL)) {
if (GameInteractor_Should(GI_VB_PLAY_PULL_MASTER_SWORD_CS, !Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL), NULL)) {
Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL);
play->nextEntranceIndex = ENTR_CUTSCENE_MAP_0;
play->transitionTrigger = TRANS_TRIGGER_START;
@ -716,7 +723,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
play->transitionType = TRANS_TYPE_FADE_WHITE;
break;
case 22:
Item_Give(play, ITEM_SONG_REQUIEM);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) {
Item_Give(play, ITEM_SONG_REQUIEM);
}
play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0;
play->transitionTrigger = TRANS_TRIGGER_START;
gSaveContext.cutsceneIndex = 0xFFF0;
@ -768,7 +777,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_WHITE;
Item_Give(play, ITEM_MEDALLION_FIRE);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) {
Item_Give(play, ITEM_MEDALLION_FIRE);
}
gSaveContext.chamberCutsceneNum = 1;
break;
case 31:
@ -848,7 +859,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
play->transitionType = TRANS_TYPE_FADE_BLACK_FAST;
break;
case 47:
Item_Give(play, ITEM_SONG_NOCTURNE);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) {
Item_Give(play, ITEM_SONG_NOCTURNE);
}
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_NOCTURNE_OF_SHADOW);
play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0;
play->transitionTrigger = TRANS_TRIGGER_START;
@ -1292,7 +1305,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
break;
}
if (randoCsSkip) {
if (shouldSkipCommand && IS_RANDO) {
Entrance_OverrideCutsceneEntrance(cmd->base);
}
}
@ -1561,7 +1574,49 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText
} else if ((cmd->type == 4) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) {
Message_StartTextbox(play, cmd->textId1, NULL);
} else {
GetItemEntry getItemEntry = GET_ITEM_NONE;
if (IS_RANDO) {
switch (cmd->base) {
case 0x80:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_QUEEN_GOHMA, RG_KOKIRI_EMERALD);
break;
case 0x81:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KING_DODONGO, RG_GORON_RUBY);
break;
case 0x82:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE);
break;
case 0x3E:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_PHANTOM_GANON, RG_FOREST_MEDALLION);
break;
case 0x3C:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_VOLVAGIA, RG_FIRE_MEDALLION);
break;
case 0x3D:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MORPHA, RG_WATER_MEDALLION);
break;
case 0x3F:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TWINROVA, RG_SPIRIT_MEDALLION);
break;
case 0x41:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BONGO_BONGO, RG_SHADOW_MEDALLION);
break;
case 0x40:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION);
break;
case 0x72:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS);
break;
}
if (getItemEntry.getItemId != GI_NONE) {
// cmd->base = getItemEntry.textId;
// GET_PLAYER(play)->getItemEntry = getItemEntry;
}
}
Message_StartTextbox(play, cmd->base, NULL);
if (IS_RANDO && getItemEntry.getItemId != GI_NONE) {
// GET_PLAYER(play)->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
}
}
return;
}
@ -1584,12 +1639,14 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText
if ((dialogState == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) {
if (play->msgCtx.choiceIndex == 0) {
if (cmd->textId1 != 0xFFFF) {
// LUSLOG_INFO("Cutscene_Command_Textbox D: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2);
Message_ContinueTextbox(play, cmd->textId1);
} else {
csCtx->frames++;
}
} else {
if (cmd->textId2 != 0xFFFF) {
// LUSLOG_INFO("Cutscene_Command_Textbox E: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2);
Message_ContinueTextbox(play, cmd->textId2);
} else {
csCtx->frames++;
@ -1599,6 +1656,7 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText
if (dialogState == TEXT_STATE_9) {
if (cmd->textId1 != 0xFFFF) {
// LUSLOG_INFO("Cutscene_Command_Textbox F: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2);
Message_ContinueTextbox(play, cmd->textId1);
} else {
csCtx->frames++;
@ -2113,34 +2171,23 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) {
u8 requiredAge;
s16 i;
if (IS_RANDO &&
// don't skip epona escape cutscenes
gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_11 &&
gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_12 &&
gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_13 &&
gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_15 &&
// don't skip nabooru iron knuckle cs
gSaveContext.entranceIndex != ENTR_SPIRIT_TEMPLE_BOSS_0) {
gSaveContext.showTitleCard = false;
return;
}
for (i = 0; i < ARRAY_COUNT(sEntranceCutsceneTable); i++) {
entranceCutscene = &sEntranceCutsceneTable[i];
requiredAge = entranceCutscene->ageRestriction;
if (requiredAge == 2) {
requiredAge = gSaveContext.linkAge;
}
if ((gSaveContext.entranceIndex == entranceCutscene->entrance) &&
(!Flags_GetEventChkInf(entranceCutscene->flag) || (entranceCutscene->flag == 0x18)) &&
(!Flags_GetEventChkInf(entranceCutscene->flag) || (entranceCutscene->flag == EVENTCHKINF_EPONA_OBTAINED)) &&
(gSaveContext.cutsceneIndex < 0xFFF0) && ((u8)gSaveContext.linkAge == requiredAge) &&
(gSaveContext.respawnFlag <= 0)) {
Flags_SetEventChkInf(entranceCutscene->flag);
Cutscene_SetSegment(play, entranceCutscene->segAddr);
gSaveContext.cutsceneTrigger = 2;
gSaveContext.showTitleCard = false;
if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &entranceCutscene->flag)) {
Cutscene_SetSegment(play, entranceCutscene->segAddr);
gSaveContext.cutsceneTrigger = 2;
gSaveContext.showTitleCard = false;
}
break;
}
}
@ -2148,48 +2195,48 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) {
void Cutscene_HandleConditionalTriggers(PlayState* play) {
osSyncPrintf("\ngame_info.mode=[%d] restart_flag", ((void)0, gSaveContext.respawnFlag));
LUSLOG_INFO("Cutscene_HandleConditionalTriggers - entranceIndex: %#x cutsceneIndex: %#x", gSaveContext.entranceIndex, gSaveContext.cutsceneIndex);
if (!GameInteractor_Should(GI_VB_PLAY_TRANSITION_CS, true, NULL)) {
return;
}
if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) {
const bool bShouldTowerRandoSkip =
(IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE));
if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) {
if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT);
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0;
gSaveContext.cutsceneIndex = 0xFFF0;
}
} else if ((gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) && LINK_IS_ADULT && (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) &&
(Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) &&
!Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) {
if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL);
gSaveContext.cutsceneIndex = 0xFFF0;
}
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT);
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0;
gSaveContext.cutsceneIndex = 0xFFF0;
} else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, (
(gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) &&
LINK_IS_ADULT &&
Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) &&
Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) &&
Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) &&
!Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)
), NULL)) {
Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL);
gSaveContext.cutsceneIndex = 0xFFF0;
} else if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) {
if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE);
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FAIRY_OCARINA, true, NULL)) {
Item_Give(play, ITEM_OCARINA_FAIRY);
gSaveContext.entranceIndex = ENTR_LOST_WOODS_0;
gSaveContext.cutsceneIndex = 0xFFF0;
}
} else if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME)) {
if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0;
gSaveContext.cutsceneIndex = 0xFFF8;
}
} else if ((!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) &&
gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS) ||
(bShouldTowerRandoSkip &&
gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR)) {
gSaveContext.entranceIndex = ENTR_LOST_WOODS_0;
gSaveContext.cutsceneIndex = 0xFFF0;
} else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, (
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
LINK_IS_ADULT &&
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME)
), NULL)) {
Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0;
gSaveContext.cutsceneIndex = 0xFFF8;
} else if (!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS)) {
Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO);
gSaveContext.entranceIndex = ENTR_GANON_BOSS_0;
// In rando, skip the cutscene for the tower falling down after the escape.
if (IS_RANDO) {
return;
}
gSaveContext.cutsceneIndex = 0xFFF0;
}
}

View File

@ -3,6 +3,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h"
#include "textures/icon_item_static/icon_item_static.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS 0
@ -349,6 +350,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
s32 getItemId = GI_NONE;
this->randoGiEntry = (GetItemEntry)GET_ITEM_NONE;
this->randoCheck = (RandomizerCheck)RC_UNKNOWN_CHECK;
this->itemEntry = (GetItemEntry)GET_ITEM_NONE;
s16 spawnParam8000 = this->actor.params & 0x8000;
s32 pad1;
@ -358,7 +360,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->actor.params &= 0xFF;
if (Flags_GetCollectible(play, this->collectibleFlag)) {
if (GameInteractor_Should(GI_VB_ITEM00_DESPAWN, Flags_GetCollectible(play, this->collectibleFlag), this)) {
Actor_Kill(&this->actor);
return;
}
@ -381,12 +383,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->unk_158 = 0;
Actor_SetScale(&this->actor, 0.03f);
this->scale = 0.03f;
// Offset keys in randomizer slightly higher for their GID replacement
if (!IS_RANDO) {
yOffset = 350.0f;
} else {
yOffset = 430.0f;
}
yOffset = 350.0f;
break;
case ITEM00_HEART_PIECE:
this->unk_158 = 0;
@ -479,6 +476,14 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
Actor_SetScale(&this->actor, 0.03f);
this->scale = 0.03f;
break;
case ITEM00_SOH_GIVE_ITEM_ENTRY:
case ITEM00_SOH_GIVE_ITEM_ENTRY_GI:
case ITEM00_SOH_DUMMY:
this->unk_158 = 0;
Actor_SetScale(&this->actor, 0.03f);
this->scale = 0.03f;
yOffset = 430.0f;
break;
}
this->unk_156 = 0;
@ -507,6 +512,10 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->actor.velocity.y = 0.0f;
this->actor.gravity = 0.0f;
if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ITEM_00, true, this)) {
return;
}
switch (this->actor.params) {
case ITEM00_RUPEE_GREEN:
Item_Give(play, ITEM_RUPEE_GREEN);
@ -576,16 +585,8 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
break;
}
if (!Actor_HasParent(&this->actor, play)) {
if (getItemId != GI_NONE) {
if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) {
func_8002F554(&this->actor, play, getItemId);
} else {
if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) {
Flags_SetRandomizerInf(this->randoInf);
}
}
}
if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) {
func_8002F554(&this->actor, play, getItemId);
}
EnItem00_SetupAction(this, func_8001E5C8);
@ -603,8 +604,7 @@ void func_8001DFC8(EnItem00* this, PlayState* play) {
(this->actor.params == ITEM00_HEART_PIECE)) {
this->actor.shape.rot.y += 960;
} else {
if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params != ITEM00_BOMBS_SPECIAL) &&
(this->actor.params != ITEM00_BOMBCHU)) {
if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params < ITEM00_BOMBS_SPECIAL)) {
if (this->unk_15A == -1) {
if (Math_SmoothStepToS(&this->actor.shape.rot.x, this->actor.world.rot.x - 0x4000, 2, 3000, 1500) ==
0) {
@ -697,8 +697,7 @@ void func_8001E304(EnItem00* this, PlayState* play) {
if (this->actor.params <= ITEM00_RUPEE_RED) {
this->actor.shape.rot.y += 960;
} else if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params != ITEM00_BOMBS_SPECIAL) &&
(this->actor.params != ITEM00_BOMBCHU)) {
} else if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params < ITEM00_BOMBS_SPECIAL)) {
this->actor.world.rot.x -= 700;
this->actor.shape.rot.y += 400;
this->actor.shape.rot.x = this->actor.world.rot.x - 0x4000;
@ -733,13 +732,7 @@ void func_8001E5C8(EnItem00* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (this->getItemId != GI_NONE) {
if (!Actor_HasParent(&this->actor, play)) {
if (!IS_RANDO) {
func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f);
} else {
if (GiveItemEntryFromActor(&this->actor, play, this->randoGiEntry, 50.0f, 80.0f) && this->randoInf != RAND_INF_MAX) {
Flags_SetRandomizerInf(this->randoInf);
}
}
Actor_OfferGetItem(&this->actor, play, this->getItemId, 50.0f, 80.0f);
this->unk_15A++;
} else {
this->getItemId = GI_NONE;
@ -781,13 +774,15 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
s32 pad;
// Rotate some drops when 3D drops are on, otherwise reset rotation back to 0 for billboard effect
if ((this->actor.params == ITEM00_HEART && this->unk_15A >= 0) ||
if (
(this->actor.params == ITEM00_HEART && this->unk_15A >= 0) ||
(this->actor.params >= ITEM00_ARROWS_SMALL && this->actor.params <= ITEM00_SMALL_KEY) ||
this->actor.params == ITEM00_BOMBS_A || this->actor.params == ITEM00_ARROWS_SINGLE ||
this->actor.params == ITEM00_BOMBS_SPECIAL || this->actor.params == ITEM00_BOMBCHU) {
if (CVarGetInteger("gNewDrops", 0) ||
// Keys in randomizer need to always rotate for their GID replacement
(IS_RANDO && this->actor.params == ITEM00_SMALL_KEY)) {
this->actor.params == ITEM00_BOMBS_A ||
this->actor.params == ITEM00_ARROWS_SINGLE ||
this->actor.params == ITEM00_BOMBS_SPECIAL ||
(this->actor.params >= ITEM00_BOMBCHU && this->actor.params <= ITEM00_SOH_GIVE_ITEM_ENTRY_GI)
) {
if (CVarGetInteger("gNewDrops", 0) || (this->actor.params >= ITEM00_SOH_DUMMY && this->actor.params <= ITEM00_SOH_GIVE_ITEM_ENTRY_GI)) {
this->actor.shape.rot.y += 960;
} else {
this->actor.shape.rot.y = 0;
@ -871,6 +866,10 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
return;
}
if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ITEM_00, true, this)) {
return;
}
switch (this->actor.params) {
case ITEM00_RUPEE_GREEN:
Item_Give(play, ITEM_RUPEE_GREEN);
@ -955,14 +954,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
params = &this->actor.params;
if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) {
if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) {
func_8002F554(&this->actor, play, getItemId);
} else {
getItemId = this->randoGiEntry.getItemId;
if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) {
Flags_SetRandomizerInf(this->randoInf);
}
}
func_8002F554(&this->actor, play, getItemId);
}
switch (*params) {
@ -1052,7 +1044,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
}
break;
case ITEM00_HEART_PIECE:
if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) {
if (CVarGetInteger("gNewDrops", 0)) {
mtxScale = 21.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
GetItem_Draw(play, GID_HEART_PIECE);
@ -1162,7 +1154,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
break;
}
case ITEM00_SMALL_KEY:
if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) {
if (CVarGetInteger("gNewDrops", 0)) {
mtxScale = 8.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
GetItem_Draw(play, GID_KEY_SMALL);
@ -1368,17 +1360,7 @@ static const Vtx customDropVtx[] = {
* Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...).
*/
void EnItem00_DrawCollectible(EnItem00* this, PlayState* play) {
if (IS_RANDO && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) {
if (this->randoCheck != RC_UNKNOWN_CHECK) {
this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE);
this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING;
}
f32 mtxScale = 10.67f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry);
GetItemEntry_Draw(play, this->randoGiEntry);
} else if (this->actor.params == ITEM00_BOMBCHU) {
if (this->actor.params == ITEM00_BOMBCHU) {
OPEN_DISPS(play->state.gfxCtx);
Matrix_ReplaceRotation(&play->billboardMtxF);
@ -1458,29 +1440,17 @@ void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play) {
* Draw Function used for the Piece of Heart type of En_Item00.
*/
void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) {
if (IS_RANDO) {
if (this->randoCheck != RC_UNKNOWN_CHECK) {
this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE);
this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING;
}
s32 pad;
f32 mtxScale = 16.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry);
GetItemEntry_Draw(play, this->randoGiEntry);
} else {
s32 pad;
OPEN_DISPS(play->state.gfxCtx);
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
func_8002ED80(&this->actor, play, 0);
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
func_8002ED80(&this->actor, play, 0);
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL);
CLOSE_DISPS(play->state.gfxCtx);
}
CLOSE_DISPS(play->state.gfxCtx);
}
/**

View File

@ -2607,8 +2607,23 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
msgCtx->lastPlayedSong = msgCtx->ocarinaStaff->state;
msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_SUCCESS;
if (!IS_RANDO) {
Item_Give(play, ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]);
u8 songItemId = ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state];
if (
(songItemId == ITEM_SONG_MINUET && GameInteractor_Should(GI_VB_GIVE_ITEM_MINUET_OF_FOREST, true, NULL)) ||
(songItemId == ITEM_SONG_BOLERO && GameInteractor_Should(GI_VB_GIVE_ITEM_BOLERO_OF_FIRE, true, NULL)) ||
(songItemId == ITEM_SONG_SERENADE && GameInteractor_Should(GI_VB_GIVE_ITEM_SERENADE_OF_WATER, true, NULL)) ||
(songItemId == ITEM_SONG_REQUIEM && GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) ||
(songItemId == ITEM_SONG_NOCTURNE && GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) ||
(songItemId == ITEM_SONG_PRELUDE && GameInteractor_Should(GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT, true, NULL)) ||
(songItemId == ITEM_SONG_LULLABY && GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LULLABY, true, NULL)) ||
(songItemId == ITEM_SONG_EPONA && GameInteractor_Should(GI_VB_GIVE_ITEM_EPONAS_SONG, true, NULL)) ||
(songItemId == ITEM_SONG_SARIA && GameInteractor_Should(GI_VB_GIVE_ITEM_SARIAS_SONG, true, NULL)) ||
(songItemId == ITEM_SONG_SUN && GameInteractor_Should(GI_VB_GIVE_ITEM_SUNS_SONG, true, NULL)) ||
(songItemId == ITEM_SONG_TIME && GameInteractor_Should(GI_VB_GIVE_ITEM_SONG_OF_TIME, true, NULL)) ||
(songItemId == ITEM_SONG_STORMS && GameInteractor_Should(GI_VB_GIVE_ITEM_SONG_OF_STORMS, true, NULL))
) {
Item_Give(play, songItemId);
}
osSyncPrintf(VT_FGCOL(YELLOW));

View File

@ -1,6 +1,7 @@
#include "global.h"
#include "vt.h"
#include "overlays/actors/ovl_En_Sw/z_en_sw.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
static s16 sDisableAttention = false;
static s16 sUnused = -1;
@ -267,7 +268,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
case 2290: {
Actor* rideActor = player->rideActor;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
if (rideActor != NULL) {
rideActor->freezeTimer = 180;
}
@ -278,7 +279,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
} break;
case 5120:
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
csInfo->keyFrames = D_80121314;
csInfo->keyFrameCnt = 1;
@ -288,7 +289,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
case 4510:
D_8012133C[0].eyeTargetInit = actor->world.pos;
D_8012133C[0].eyeTargetInit.y = player->actor.world.pos.y + 40.0f;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
csInfo->keyFrames = D_8012133C;
csInfo->keyFrameCnt = 3;
@ -306,7 +307,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
OnePointCutscene_AddVecSphToVec3f(&spB4, &spC0, &spD0);
Play_CameraChangeSetting(play, camIdx, CAM_SET_FREE2);
Play_CameraSetAtEye(play, camIdx, &spC0, &spB4);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
csCam->roll = 0;
csCam->fov = 50.0f;
if (csCam->childCamIdx != SUBCAM_FREE) {
@ -320,7 +321,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
if (Rand_ZeroOne() < 0.0f) {
D_801213B4[3].eyeTargetInit.x = -D_801213B4[3].eyeTargetInit.x;
}
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
csInfo->keyFrames = D_801213B4;
csInfo->keyFrameCnt = 5;
@ -373,10 +374,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
Play_CameraSetAtEye(play, camIdx, &spC0, &spB4);
csCam->roll = 6;
csCam->fov = 75.0f;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
break;
case 3040:
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
D_8012151C[0].timerInit = timer - 1;
csInfo->keyFrames = D_8012151C;
@ -400,7 +401,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrameCnt = 2;
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
break;
case 3010:
D_801215BC[0].timerInit = timer;
@ -428,7 +429,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
case 3090:
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
csInfo->keyFrames = D_80121814;
csInfo->keyFrameCnt = 4;
@ -444,14 +445,14 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
Play_CameraSetAtEye(play, camIdx, &spC0, &spB4);
csCam->roll = 0;
csCam->fov = 70.0f;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
break;
case 3380:
case 3065:
csInfo->keyFrames = D_801218B4;
csInfo->keyFrameCnt = 2;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
i = Quake_Add(csCam, 1);
@ -463,12 +464,12 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_80121904;
csInfo->keyFrameCnt = 2;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
case 3050:
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
func_8002DF54(play, &player->actor, 5);
Player_SetCsActionWithHaltedActors(play, &player->actor, 5);
OnePointCutscene_SetCsCamPoints(csCam, D_80120304 | 0x2000, D_80120300, D_8012013C, D_8012021C);
func_80078884(NA_SE_SY_CORRECT_CHIME);
OnePointCutscene_Vec3sToVec3f(&mainCam->at, &D_8012013C[D_801202FC - 2].pos);
@ -497,14 +498,14 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csCam->unk_14C |= 2;
csInfo->keyFrameCnt = 2;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
case 3130:
csInfo->keyFrames = D_80121A44;
csInfo->keyFrameCnt = 12;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
csCam->unk_14C |= 2;
break;
@ -635,7 +636,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csCam->roll = 0;
csCam->fov = 75.0f;
player->actor.shape.rot.y = player->actor.world.rot.y = player->yaw = spD0.yaw + 0x7FFF;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
break;
case 3240:
D_80121D3C[2].timerInit = timer - 5;
@ -643,12 +644,12 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_80121D3C;
csInfo->keyFrameCnt = 3;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
case 6001:
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
Actor_GetWorld(&spA0, actor);
if (spA0.pos.z > -750.0f) {
OnePointCutscene_SetCsCamPoints(csCam, D_801208E8, D_801208E4, D_801206A0, D_80120820);
@ -679,12 +680,12 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_80121DB4;
csInfo->keyFrameCnt = 9;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
case 3310:
Play_CameraChangeSetting(play, camIdx, CAM_SET_FIRE_STAIRCASE);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
Play_CopyCamera(play, camIdx, MAIN_CAM);
i = Quake_Add(csCam, 1);
@ -717,7 +718,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_80121FBC;
csInfo->keyFrameCnt = 4;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
i = Quake_Add(csCam, 3);
@ -744,7 +745,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
D_801220D4[1].eyeTargetInit.y = 80.0f;
D_801220D4[1].eyeTargetInit.x = -D_801220D4[1].eyeTargetInit.x;
}
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
csInfo->keyFrames = D_801220D4;
csInfo->keyFrameCnt = 5;
@ -762,7 +763,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_801222B4;
csInfo->keyFrameCnt = 5;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
i = Quake_Add(csCam, 1);
@ -786,7 +787,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_801223CC;
csInfo->keyFrameCnt = 6;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
player->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
player->actor.freezeTimer = 90;
@ -800,7 +801,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_801224BC;
csInfo->keyFrameCnt = 7;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
i = Quake_Add(csCam, 1);
@ -810,16 +811,11 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
break;
case 4100:
csInfo->keyFrames = D_801225D4;
// RANDO: Waterfall opening cutscene skips to the end of the cutscene data earlier by doing this
if (!(IS_RANDO)) {
csInfo->keyFrameCnt = 5;
} else {
csInfo->keyFrameCnt = 2;
}
csInfo->keyFrameCnt = ARRAY_COUNT(D_801225D4);
player->actor.shape.rot.y = player->actor.world.rot.y = player->yaw = 0x3FFC;
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
break;
case 4110:
csInfo->keyFrames = D_8012269C;
@ -829,7 +825,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
case 4120:
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
D_80122714[1].timerInit = 80;
csInfo->keyFrames = D_80122714;
csInfo->keyFrameCnt = 4;
@ -847,7 +843,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_801228A4;
csInfo->keyFrameCnt = 5;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
Camera_ChangeMode(mainCam, CAM_MODE_NORMAL);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
@ -855,7 +851,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_8012296C;
csInfo->keyFrameCnt = 4;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
Camera_ChangeMode(mainCam, CAM_MODE_NORMAL);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
@ -863,7 +859,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_80122A0C;
csInfo->keyFrameCnt = 2;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
Camera_ChangeMode(mainCam, CAM_MODE_NORMAL);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
@ -912,11 +908,11 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
csInfo->keyFrames = D_80122C8C;
csInfo->keyFrameCnt = 1;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
case 3260:
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
D_80122CB4[1].timerInit = timer - 5;
csInfo->keyFrames = D_80122CB4;
@ -925,7 +921,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
func_800C0808(play, camIdx, player, CAM_SET_CS_C);
break;
case 3261:
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
D_80122D04[1].timerInit = timer - 10;
csInfo->keyFrames = D_80122D04;
@ -1176,6 +1172,16 @@ s16 OnePointCutscene_Init(PlayState* play, s16 csId, s16 timer, Actor* actor, s1
s16 csCamIdx;
Camera* csCam;
if (actor != NULL && actor->id != ACTOR_PLAYER) {
if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, actor)) {
return SUBCAM_NONE;
}
} else {
if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_CS, true, &csId)) {
return SUBCAM_NONE;
}
}
if (parentCamIdx == SUBCAM_ACTIVE) {
parentCamIdx = play->activeCamera;
}

View File

@ -2128,7 +2128,9 @@ u8 Item_Give(PlayState* play, u8 item) {
AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS);
}
}
item = ITEM_STICK;
// [SOH] This results in the same behavior as the original code, but also allows us to get an accurate ReceivedItemEntry hook
INV_CONTENT(ITEM_STICK) = ITEM_STICK;
return Return_Item(item, MOD_NONE, returnItem);
} else if (item == ITEM_NUT) {
if (gSaveContext.inventory.items[slot] == ITEM_NONE) {
Inventory_ChangeUpgrade(UPG_NUTS, 1);
@ -2152,7 +2154,9 @@ u8 Item_Give(PlayState* play, u8 item) {
AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS);
}
}
item = ITEM_NUT;
// [SOH] This results in the same behavior as the original code, but also allows us to get an accurate ReceivedItemEntry hook
INV_CONTENT(ITEM_NUT) = ITEM_NUT;
return Return_Item(item, MOD_NONE, returnItem);
} else if (item == ITEM_BOMB) {
// "Bomb Bomb Bomb Bomb Bomb Bomb Bomb"
osSyncPrintf(" 爆弾 爆弾 爆弾 爆弾 爆弾 爆弾 爆弾 \n");
@ -6155,7 +6159,7 @@ void Interface_Draw(PlayState* play) {
gSaveContext.timer2State = 5;
gSaveContext.cutsceneIndex = 0;
Message_StartTextbox(play, 0x71B0, NULL);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
} else {
D_8015FFE6 = 40;
gSaveContext.timer2State = 6;

View File

@ -226,60 +226,6 @@ void Play_Destroy(GameState* thisx) {
gPlayState = NULL;
}
void GivePlayerRandoRewardSongOfTime(PlayState* play, RandomizerCheck check) {
Player* player = GET_PLAYER(play);
if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_16 && player != NULL && !Player_InBlockingCsMode(play, player) &&
!Flags_GetTreasure(play, 0x1F) && gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT && !gSaveContext.pendingIceTrapCount) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME);
GiveItemEntryWithoutActor(play, getItemEntry);
player->pendingFlag.flagID = 0x1F;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
}
void GivePlayerRandoRewardNocturne(PlayState* play, RandomizerCheck check) {
Player* player = GET_PLAYER(play);
if ((gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 ||
gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_1 ||
gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_2) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && player != NULL &&
!Player_InBlockingCsMode(play, player) && !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_NOCTURNE_OF_SHADOW);
GiveItemEntryWithoutActor(play, getItemEntry);
player->pendingFlag.flagID = 0xAA;
player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF;
}
}
void GivePlayerRandoRewardRequiem(PlayState* play, RandomizerCheck check) {
Player* player = GET_PLAYER(play);
if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) {
if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT) && player != NULL &&
!Player_InBlockingCsMode(play, player)) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME);
GiveItemEntryWithoutActor(play, getItemEntry);
player->pendingFlag.flagID = 0xAC;
player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF;
}
}
}
void GivePlayerRandoRewardMasterSword(PlayState* play, RandomizerCheck check) {
Player* player = GET_PLAYER(play);
if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_2 && LINK_IS_ADULT && player != NULL &&
!Player_InBlockingCsMode(play, player) && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) &&
!Flags_GetRandomizerInf(RAND_INF_TOT_MASTER_SWORD)) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_MASTER_SWORD);
GiveItemEntryWithoutActor(play, getItemEntry);
player->pendingFlag.flagID = RAND_INF_TOT_MASTER_SWORD;
player->pendingFlag.flagType = FLAG_RANDOMIZER_INF;
}
}
u8 CheckStoneCount() {
u8 stoneCount = 0;
@ -402,69 +348,6 @@ u8 CheckLACSRewardCount() {
return lacsRewardCount;
}
void GivePlayerRandoRewardZeldaLightArrowsGift(PlayState* play, RandomizerCheck check) {
Player* player = GET_PLAYER(play);
u8 meetsRequirements = 0;
switch (Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY)) {
case RO_GANON_BOSS_KEY_LACS_STONES:
if ((CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_STONE_COUNT)) {
meetsRequirements = true;
}
break;
case RO_GANON_BOSS_KEY_LACS_MEDALLIONS:
if ((CheckMedallionCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_MEDALLION_COUNT)) {
meetsRequirements = true;
}
break;
case RO_GANON_BOSS_KEY_LACS_REWARDS:
if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_REWARD_COUNT)) {
meetsRequirements = true;
}
break;
case RO_GANON_BOSS_KEY_LACS_DUNGEONS:
if ((CheckDungeonCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_DUNGEON_COUNT)) {
meetsRequirements = true;
}
break;
case RO_GANON_BOSS_KEY_LACS_TOKENS:
if (gSaveContext.inventory.gsTokens >= Randomizer_GetSettingValue(RSK_LACS_TOKEN_COUNT)) {
meetsRequirements = true;
}
break;
default:
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) {
meetsRequirements = true;
}
break;
}
if (meetsRequirements && LINK_IS_ADULT &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) &&
!Flags_GetTreasure(play, 0x1E) && player != NULL && !Player_InBlockingCsMode(play, player) &&
play->transitionTrigger == TRANS_TRIGGER_OFF) {
GetItemEntry getItem = Randomizer_GetItemFromKnownCheck(check, GI_ARROW_LIGHT);
if (GiveItemEntryWithoutActor(play, getItem)) {
player->pendingFlag.flagID = 0x1E;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
}
}
void GivePlayerRandoRewardSariaGift(PlayState* play, RandomizerCheck check) {
Player* player = GET_PLAYER(play);
if (gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY);
if (!Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE) && player != NULL && !Player_InBlockingCsMode(play, player)) {
GiveItemEntryWithoutActor(play, getItemEntry);
player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF;
player->pendingFlag.flagID = 0xC1;
}
}
}
void Play_Init(GameState* thisx) {
PlayState* play = (PlayState*)thisx;
GraphicsContext* gfxCtx = play->state.gfxCtx;
@ -1448,15 +1331,6 @@ skip:
Environment_Update(play, &play->envCtx, &play->lightCtx, &play->pauseCtx, &play->msgCtx,
&play->gameOverCtx, play->state.gfxCtx);
if (IS_RANDO) {
GivePlayerRandoRewardSariaGift(play, RC_LW_GIFT_FROM_SARIA);
GivePlayerRandoRewardSongOfTime(play, RC_SONG_FROM_OCARINA_OF_TIME);
GivePlayerRandoRewardZeldaLightArrowsGift(play, RC_TOT_LIGHT_ARROWS_CUTSCENE);
GivePlayerRandoRewardNocturne(play, RC_SHEIK_IN_KAKARIKO);
GivePlayerRandoRewardRequiem(play, RC_SHEIK_AT_COLOSSUS);
GivePlayerRandoRewardMasterSword(play, RC_TOT_MASTER_SWORD);
}
}
void Play_DrawOverlayElements(PlayState* play) {

View File

@ -6,6 +6,7 @@
#include "z_bg_bdan_switch.h"
#include "objects/object_bdan_objects/object_bdan_objects.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@ -224,10 +225,12 @@ void func_8086D4B4(BgBdanSwitch* this, PlayState* play) {
if (!Flags_GetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F)) {
type = this->dyna.actor.params & 0xFF;
Flags_SetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F);
if (type == BLUE || type == YELLOW_TALL_2) {
OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR);
} else {
OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME);
if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) {
if (type == BLUE || type == YELLOW_TALL_2) {
OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR);
} else {
OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_CORRECT_CHIME);
}
}
}
}
@ -236,7 +239,9 @@ void func_8086D548(BgBdanSwitch* this, PlayState* play) {
if (Flags_GetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F)) {
Flags_UnsetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F);
if ((this->dyna.actor.params & 0xFF) == YELLOW_TALL_2) {
OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR);
if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) {
OnePointCutscene_AttentionSetSfx(play, &this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR);
}
}
}
}

View File

@ -8,6 +8,7 @@
#include "scenes/dungeons/ddan/ddan_scene.h"
#include "objects/object_bwall/object_bwall.h"
#include "objects/object_kingdodongo/object_kingdodongo.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@ -300,10 +301,13 @@ void BgBreakwall_Wait(BgBreakwall* this, PlayState* play) {
if ((wallType == BWALL_DC_ENTRANCE) && (!Flags_GetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN))) {
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN);
Cutscene_SetSegment(play, gDcOpeningCs);
gSaveContext.cutsceneTrigger = 1;
s32 flag = EVENTCHKINF_ENTERED_DODONGOS_CAVERN;
if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &flag)) {
Cutscene_SetSegment(play, gDcOpeningCs);
gSaveContext.cutsceneTrigger = 1;
Player_SetCsActionWithHaltedActors(play, NULL, 0x31);
}
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
func_8002DF54(play, NULL, 0x31);
}
if (this->dyna.actor.params < 0) {

View File

@ -11,6 +11,7 @@
#include "scenes/indoors/yousei_izumi_yoko/yousei_izumi_yoko_scene.h"
#include "scenes/indoors/daiyousei_izumi/daiyousei_izumi_scene.h"
#include "soh/frame_interpolation.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA)
@ -68,19 +69,6 @@ const ActorInit Bg_Dy_Yoseizo_InitVars = {
NULL,
};
void GivePlayerRandoRewardGreatFairy(BgDyYoseizo* this, PlayState* play) {
Player* player = GET_PLAYER(play);
GetItemEntry getItemEntry = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->fountainType + 1, GI_NONE);
if (this->actor.parent == GET_PLAYER(play) && !Flags_GetTreasure(play, this->fountainType + 1) &&
!Player_InBlockingCsMode(play, GET_PLAYER(play))) {
Flags_SetTreasure(play, this->fountainType + 1);
Actor_Kill(&this->actor);
} else if (!Flags_GetTreasure(play, this->fountainType + 1)) {
GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 100.0f);
}
}
void BgDyYoseizo_Init(Actor* thisx, PlayState* play2) {
PlayState* play = play2;
BgDyYoseizo* this = (BgDyYoseizo*)thisx;
@ -196,32 +184,26 @@ void BgDyYoseizo_Bob(BgDyYoseizo* this, PlayState* play) {
}
void BgDyYoseizo_CheckMagicAcquired(BgDyYoseizo* this, PlayState* play) {
u8 isEligible = true;
if (Flags_GetSwitch(play, 0x38)) {
play->msgCtx.ocarinaMode = OCARINA_MODE_04;
if(IS_RANDO) {
gSaveContext.healthAccumulator = 0x140;
Magic_Fill(play);
if(Flags_GetTreasure(play, this->fountainType + 1)) {
Actor_Kill(&this->actor);
} else {
GivePlayerRandoRewardGreatFairy(this, play);
}
return;
}
if (play->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC) {
if (!gSaveContext.isMagicAcquired && (this->fountainType != FAIRY_UPGRADE_MAGIC)) {
Actor_Kill(&this->actor);
return;
isEligible = false;
}
} else {
if (!gSaveContext.isMagicAcquired) {
Actor_Kill(&this->actor);
return;
isEligible = false;
}
}
func_8002DF54(play, &this->actor, 1);
if (!GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD, isEligible, this)) {
Actor_Kill(&this->actor);
return;
}
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->actionFunc = BgDyYoseizo_ChooseType;
}
}
@ -229,7 +211,7 @@ void BgDyYoseizo_CheckMagicAcquired(BgDyYoseizo* this, PlayState* play) {
void BgDyYoseizo_ChooseType(BgDyYoseizo* this, PlayState* play) {
s32 givingReward;
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
// "Mode"
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ もうど ☆☆☆☆☆ %d\n" VT_RST, play->msgCtx.ocarinaMode);
givingReward = false;
@ -345,12 +327,12 @@ void BgDyYoseizo_SetupSpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) {
}
Audio_PlayActorSound2(&this->actor, NA_SE_VO_FR_LAUGH_0);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->actionFunc = BgDyYoseizo_SpinGrow_NoReward;
}
void BgDyYoseizo_SpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) {
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
Math_ApproachF(&this->actor.world.pos.y, this->grownHeight, this->heightFraction, 100.0f);
Math_ApproachF(&this->scale, 0.035f, this->scaleFraction, 0.005f);
Math_ApproachF(&this->heightFraction, 0.8f, 0.1f, 0.02f);
@ -376,7 +358,7 @@ void BgDyYoseizo_SpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) {
void BgDyYoseizo_CompleteSpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) {
f32 curFrame = this->skelAnime.curFrame;
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
if ((this->frameCount * 1273.0f) <= this->bobTimer) {
this->bobTimer = 0.0f;
@ -390,7 +372,7 @@ void BgDyYoseizo_CompleteSpinGrow_NoReward(BgDyYoseizo* this, PlayState* play) {
}
void BgDyYoseizo_SetupGreetPlayer_NoReward(BgDyYoseizo* this, PlayState* play) {
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
if (play->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC) {
this->frameCount = Animation_GetLastFrame(&gGreatFairySittingAnim);
@ -410,7 +392,7 @@ void BgDyYoseizo_SetupGreetPlayer_NoReward(BgDyYoseizo* this, PlayState* play) {
}
void BgDyYoseizo_GreetPlayer_NoReward(BgDyYoseizo* this, PlayState* play) {
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->bobTimer = this->skelAnime.curFrame * 1273.0f;
if ((this->frameCount * 1273.0f) <= this->bobTimer) {
@ -578,7 +560,7 @@ void BgDyYoseizo_Vanish(BgDyYoseizo* this, PlayState* play) {
Actor* findOcarinaSpot;
if (this->vanishTimer == 0) {
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
play->envCtx.unk_BF = 0;
findOcarinaSpot = play->actorCtx.actorLists[ACTORCAT_PROP].head;
@ -600,7 +582,7 @@ void BgDyYoseizo_SetupSpinGrow_Reward(BgDyYoseizo* this, PlayState* play) {
if (play->csCtx.state != CS_STATE_IDLE) {
if ((play->csCtx.npcActions[0] != NULL) && (play->csCtx.npcActions[0]->action == 2)) {
this->actor.draw = BgDyYoseizo_Draw;
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->finishedSpinGrow = false;
if (play->sceneNum == SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC) {

View File

@ -241,7 +241,7 @@ void BgGndIceblock_Idle(BgGndIceblock* this, PlayState* play) {
if (this->dyna.unk_150 > 0.0f) {
BgGndIceblock_SetNextPosition(this);
if (Actor_WorldDistXZToPoint(&this->dyna.actor, &this->targetPos) > 1.0f) {
func_8002DF54(play, &this->dyna.actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8);
this->actionFunc = BgGndIceblock_Slide;
}
}
@ -282,7 +282,7 @@ void BgGndIceblock_Fall(BgGndIceblock* this, PlayState* play) {
thisx->world.pos.y = thisx->home.pos.y - 100.0f;
thisx->world.pos.z = thisx->home.pos.z;
if (Player_InCsMode(play)) {
func_8002DF54(play, thisx, 7);
Player_SetCsActionWithHaltedActors(play, thisx, 7);
}
this->actionFunc = BgGndIceblock_Reset;
}
@ -295,7 +295,7 @@ void BgGndIceblock_Hole(BgGndIceblock* this, PlayState* play) {
if (Math_StepToF(&thisx->world.pos.y, thisx->home.pos.y - 100.0f, thisx->velocity.y)) {
thisx->velocity.y = 0.0f;
if (Player_InCsMode(play)) {
func_8002DF54(play, thisx, 7);
Player_SetCsActionWithHaltedActors(play, thisx, 7);
}
this->actionFunc = BgGndIceblock_Idle;
}
@ -319,7 +319,7 @@ void BgGndIceblock_Slide(BgGndIceblock* this, PlayState* play) {
switch (BgGndIceblock_NextAction(this)) {
case GNDICE_IDLE:
this->actionFunc = BgGndIceblock_Idle;
func_8002DF54(play, thisx, 7);
Player_SetCsActionWithHaltedActors(play, thisx, 7);
break;
case GNDICE_FALL:
this->actionFunc = BgGndIceblock_Fall;

View File

@ -370,7 +370,7 @@ void BgHeavyBlock_LiftedUp(BgHeavyBlock* this, PlayState* play) {
this->timer++;
if (!CVarGetInteger("gFasterHeavyBlockLift", 0)) {
func_8002DF54(play, &player->actor, 8);
Player_SetCsActionWithHaltedActors(play, &player->actor, 8);
}
// if parent is NULL, link threw it

View File

@ -138,7 +138,7 @@ void BgHidanDalm_Wait(BgHidanDalm* this, PlayState* play) {
this->dyna.actor.world.pos.x += 32.5f * Math_SinS(this->dyna.actor.world.rot.y);
this->dyna.actor.world.pos.z += 32.5f * Math_CosS(this->dyna.actor.world.rot.y);
func_8002DF54(play, &this->dyna.actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8);
this->dyna.actor.flags |= ACTOR_FLAG_UPDATE_WHILE_CULLED;
this->actionFunc = BgHidanDalm_Shrink;
this->dyna.actor.bgCheckFlags &= ~2;
@ -159,7 +159,7 @@ void BgHidanDalm_Shrink(BgHidanDalm* this, PlayState* play) {
Vec3f pos;
if (Math_StepToF(&this->dyna.actor.scale.x, 0.0f, 0.004f)) {
func_8002DF54(play, &this->dyna.actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 7);
Actor_Kill(&this->dyna.actor);
}

View File

@ -14,4 +14,7 @@ typedef struct BgHidanKousi {
/* 0x0168 */ s16 unk_168;
} BgHidanKousi; // size = 0x016C
void BgHidanKousi_SetupAction(BgHidanKousi* bgHidanKousi, BgHidanKousiActionFunc actionFunc);
void func_80889C18(BgHidanKousi* bgHidanKousi, PlayState* play);
#endif

View File

@ -126,7 +126,7 @@ void BgIceObjects_CheckPits(BgIceObjects* this, PlayState* play) {
thisx->world.pos.y = thisx->home.pos.y - 60.0f;
thisx->world.pos.z = thisx->home.pos.z;
if (thisx->params != 0) {
func_8002DF54(play, thisx, 7);
Player_SetCsActionWithHaltedActors(play, thisx, 7);
}
this->actionFunc = BgIceObjects_Reset;
}
@ -143,7 +143,7 @@ void BgIceObjects_Idle(BgIceObjects* this, PlayState* play) {
BgIceObjects_SetNextTarget(this, play);
if (Actor_WorldDistXZToPoint(thisx, &this->targetPos) > 1.0f) {
thisx->flags |= ACTOR_FLAG_UPDATE_WHILE_CULLED;
func_8002DF54(play, thisx, 8);
Player_SetCsActionWithHaltedActors(play, thisx, 8);
thisx->params = 1;
this->actionFunc = BgIceObjects_Slide;
}
@ -173,7 +173,7 @@ void BgIceObjects_Slide(BgIceObjects* this, PlayState* play) {
thisx->flags &= ~ACTOR_FLAG_UPDATE_WHILE_CULLED;
}
thisx->params = 0;
func_8002DF54(play, thisx, 7);
Player_SetCsActionWithHaltedActors(play, thisx, 7);
Audio_PlayActorSound2(thisx, NA_SE_EV_BLOCK_BOUND);
if ((fabsf(thisx->world.pos.x + 1387.0f) < 1.0f) && (fabsf(thisx->world.pos.z + 260.0f) < 1.0f)) {
this->actionFunc = BgIceObjects_Stuck;

View File

@ -6,6 +6,7 @@
#include "z_bg_mori_bigst.h"
#include "objects/object_mori_objects/object_mori_objects.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@ -149,7 +150,9 @@ void BgMoriBigst_StalfosFight(BgMoriBigst* this, PlayState* play) {
if ((this->dyna.actor.home.rot.z == 0) &&
((this->dyna.actor.home.pos.y - 5.0f) <= GET_PLAYER(play)->actor.world.pos.y)) {
BgMoriBigst_SetupFall(this, play);
OnePointCutscene_Init(play, 3220, 72, &this->dyna.actor, MAIN_CAM);
if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) {
OnePointCutscene_Init(play, 3220, 72, &this->dyna.actor, MAIN_CAM);
}
}
}
@ -163,8 +166,10 @@ void BgMoriBigst_Fall(BgMoriBigst* this, PlayState* play) {
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y;
BgMoriBigst_SetupLanding(this, play);
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND);
OnePointCutscene_Init(play, 1020, 8, &this->dyna.actor, MAIN_CAM);
func_8002DF38(play, NULL, 0x3C);
if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) {
OnePointCutscene_Init(play, 1020, 8, &this->dyna.actor, MAIN_CAM);
func_8002DF38(play, NULL, 0x3C);
}
}
}

View File

@ -96,7 +96,7 @@ void BgMoriKaitenkabe_Wait(BgMoriKaitenkabe* this, PlayState* play) {
this->timer++;
if ((this->timer > (28 - CVarGetInteger("gFasterBlockPush", 0) * 4)) && !Player_InCsMode(play)) {
BgMoriKaitenkabe_SetupRotate(this);
func_8002DF54(play, &this->dyna.actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8);
Math_Vec3f_Copy(&this->lockedPlayerPos, &player->actor.world.pos);
push.x = Math_SinS(this->dyna.unk_158);
push.y = 0.0f;
@ -130,7 +130,7 @@ void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, PlayState* play) {
Math_StepToF(&this->rotSpeed, 0.6f, 0.02f);
if (Math_StepToF(&this->rotYdeg, this->rotDirection * 45.0f, this->rotSpeed)) {
BgMoriKaitenkabe_SetupWait(this);
func_8002DF54(play, thisx, 7);
Player_SetCsActionWithHaltedActors(play, thisx, 7);
if (this->rotDirection > 0.0f) {
thisx->home.rot.y += 0x2000;
} else {

View File

@ -321,7 +321,7 @@ void BgPoEvent_BlockFall(BgPoEvent* this, PlayState* play) {
if (firstFall == 0) {
firstFall = 1;
} else {
func_8002DF54(play, &GET_PLAYER(play)->actor, 7);
Player_SetCsActionWithHaltedActors(play, &GET_PLAYER(play)->actor, 7);
}
}
this->direction = 0;
@ -358,7 +358,7 @@ void BgPoEvent_BlockIdle(BgPoEvent* this, PlayState* play) {
if (sBgPoEventPuzzleState == 0x10) {
sBgPoEventPuzzleState = 0x40;
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_RISING);
func_8002DF54(play, &player->actor, 8);
Player_SetCsActionWithHaltedActors(play, &player->actor, 8);
}
} else if (this->dyna.unk_150 != 0.0f) {
if (this->direction == 0) {

View File

@ -223,7 +223,7 @@ void BgSpot00Hanebasi_Update(Actor* thisx, PlayState* play) {
Flags_SetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE);
Flags_SetEventChkInf(EVENTCHKINF_DRAWBRIDGE_OPENED_AFTER_ZELDA_FLED);
this->actionFunc = BgSpot00Hanebasi_DoNothing;
func_8002DF54(play, &player->actor, 8);
Player_SetCsActionWithHaltedActors(play, &player->actor, 8);
play->nextEntranceIndex = ENTR_HYRULE_FIELD_0;
gSaveContext.nextCutsceneIndex = 0xFFF1;
play->transitionTrigger = TRANS_TRIGGER_START;

View File

@ -6,6 +6,7 @@
#include "z_bg_spot02_objects.h"
#include "objects/object_spot02_objects/object_spot02_objects.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
@ -129,20 +130,7 @@ void func_808AC908(BgSpot02Objects* this, PlayState* play) {
static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
Vec3f pos;
// We want to do most of the same things in rando, but we're not in a cutscene and the flag for
// destroying the royal tombstone is already set.
if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GRAVE_EXPLOSION);
this->timer = 25;
pos.x = (Math_SinS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.x;
pos.y = this->dyna.actor.world.pos.y + 30.0f;
pos.z = (Math_CosS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.z;
EffectSsBomb2_SpawnLayered(play, &pos, &zeroVec, &zeroVec, 70, 30);
this->actionFunc = func_808ACA08;
}
if (play->csCtx.state != 0) {
if (play->csCtx.npcActions[3] != NULL && play->csCtx.npcActions[3]->action == 2) {
if (GameInteractor_Should(GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE, play->csCtx.state != 0 && play->csCtx.npcActions[3] != NULL && play->csCtx.npcActions[3]->action == 2, this)) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GRAVE_EXPLOSION);
Flags_SetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB);
this->timer = 25;
@ -151,7 +139,6 @@ void func_808AC908(BgSpot02Objects* this, PlayState* play) {
pos.z = (Math_CosS(this->dyna.actor.shape.rot.y) * 50.0f) + this->dyna.actor.world.pos.z;
EffectSsBomb2_SpawnLayered(play, &pos, &zeroVec, &zeroVec, 70, 30);
this->actionFunc = func_808ACA08;
}
}
}
@ -174,7 +161,7 @@ void func_808ACA08(BgSpot02Objects* this, PlayState* play) {
// This shouldn't execute in rando even without the check since we never
// enter the cutscene context.
if (play->csCtx.frames == 402 && !(IS_RANDO)) {
if (play->csCtx.frames == 402) {
if (!LINK_IS_ADULT) {
Player_PlaySfx(&player->actor, NA_SE_VO_LI_DEMO_DAMAGE_KID);
} else {
@ -217,13 +204,6 @@ void BgSpot02Objects_Draw(Actor* thisx, PlayState* play) {
}
void func_808ACC34(BgSpot02Objects* this, PlayState* play) {
// This is the actionFunc that the game settles on when you load the Graveyard
// When we're in rando and the flag for the gravestone being destroyed gets set,
// set the actionFunc to the function where the gravestone explodes.
if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB)) {
this->actionFunc = func_808AC908;
}
if (play->csCtx.state != 0 && play->csCtx.npcActions[0] != NULL &&
play->csCtx.npcActions[0]->action == 2) {
this->unk_16A++;

View File

@ -19,4 +19,7 @@ typedef struct BgSpot02Objects {
/* 0x0172 */ u16 unk_172;
} BgSpot02Objects; // size = 0x0174
void func_808ACC34(BgSpot02Objects* bgSpot02Objects, PlayState* play);
void func_808AC908(BgSpot02Objects* bgSpot02Objects, PlayState* play);
#endif

View File

@ -6,6 +6,7 @@
#include "z_bg_toki_swd.h"
#include "objects/object_toki_objects/object_toki_objects.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@ -115,14 +116,17 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) {
if (((Flags_GetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER)) == 0) && (gSaveContext.sceneSetupIndex < 4) &&
Actor_IsFacingAndNearPlayer(&this->actor, 800.0f, 0x7530) && !Play_InCsMode(play)) {
Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER);
play->csCtx.segment = D_808BBD90;
gSaveContext.cutsceneTrigger = 1;
s32 flag = EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER;
if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &flag)) {
play->csCtx.segment = D_808BBD90;
gSaveContext.cutsceneTrigger = 1;
}
}
if (!LINK_IS_ADULT || (Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && !IS_RANDO) || IS_RANDO) {
if (Actor_HasParent(&this->actor, play)) {
if (!LINK_IS_ADULT) {
if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_MASTER_SWORD, true, NULL)) {
Item_Give(play, ITEM_SWORD_MASTER);
}
play->csCtx.segment = D_808BB2F0;

View File

@ -7,6 +7,7 @@
#include "z_bg_treemouth.h"
#include "objects/object_spot04_objects/object_spot04_objects.h"
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
@ -73,11 +74,7 @@ void BgTreemouth_Init(Actor* thisx, PlayState* play) {
if ((gSaveContext.sceneSetupIndex < 4) && !LINK_IS_ADULT) {
BgTreemouth_SetupAction(this, func_808BC8B8);
// If dungeon entrance randomizer is on, keep the tree mouth open
// when Link is adult and sword & shield have been shown to Mido
} else if ((LINK_IS_ADULT && (!IS_RANDO ||
Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) == RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) ||
!Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) || (gSaveContext.sceneSetupIndex == 7)) {
} else if (LINK_IS_ADULT || (gSaveContext.sceneSetupIndex == 7)) {
this->unk_168 = 0.0f;
BgTreemouth_SetupAction(this, BgTreemouth_DoNothing);
} else {
@ -157,9 +154,11 @@ void func_808BC8B8(BgTreemouth* this, PlayState* play) {
}
} else if (Actor_IsFacingAndNearPlayer(&this->dyna.actor, 1658.0f, 0x4E20)) {
Flags_SetEventChkInf(EVENTCHKINF_MET_DEKU_TREE);
play->csCtx.segment = D_808BCE20;
gSaveContext.cutsceneTrigger = 1;
BgTreemouth_SetupAction(this, func_808BC9EC);
if (GameInteractor_Should(GI_VB_PLAY_DEKU_TREE_INTRO_CS, true, this)) {
play->csCtx.segment = D_808BCE20;
gSaveContext.cutsceneTrigger = 1;
BgTreemouth_SetupAction(this, func_808BC9EC);
}
}
}
} else {

View File

@ -15,4 +15,7 @@ typedef struct BgTreemouth {
/* 0x016C */ BgTreemouthActionFunc actionFunc;
} BgTreemouth; // size = 0x0170
void BgTreemouth_SetupAction(BgTreemouth* actor, BgTreemouthActionFunc actionFunc);
void func_808BC6F8(BgTreemouth* actor, PlayState* play);
#endif

View File

@ -443,7 +443,7 @@ void BossDodongo_IntroCutscene(BossDodongo* this, PlayState* play) {
break;
case 1:
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
Play_ClearAllSubCameras(play);
this->cutsceneCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, 0, 1);
@ -470,11 +470,11 @@ void BossDodongo_IntroCutscene(BossDodongo* this, PlayState* play) {
}
if (this->unk_198 == 110) {
func_8002DF54(play, &this->actor, 9);
Player_SetCsActionWithHaltedActors(play, &this->actor, 9);
}
if (this->unk_198 == 5) {
func_8002DF54(play, &this->actor, 12);
Player_SetCsActionWithHaltedActors(play, &this->actor, 12);
}
if (this->unk_198 < 6) {
@ -589,7 +589,7 @@ void BossDodongo_IntroCutscene(BossDodongo* this, PlayState* play) {
func_800C08AC(play, this->cutsceneCamera, 0);
this->cutsceneCamera = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
BossDodongo_SetupWalk(this);
this->unk_1DA = 50;
this->unk_1BC = 0;
@ -1535,7 +1535,7 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) {
case 0:
this->csState = 5;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->cutsceneCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_UNK3);
Play_ChangeCameraStatus(play, this->cutsceneCamera, CAM_STAT_ACTIVE);
@ -1850,7 +1850,7 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) {
this->csState = 100;
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
if (!IS_BOSS_RUSH) {
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_CHILD);
} else {

View File

@ -323,7 +323,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) {
this->introState = BFD_CS_START;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->introCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->introCamera, CAM_STAT_ACTIVE);
@ -399,7 +399,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) {
Math_ApproachF(&this->camData.shake, 2.0f, 1.0f, 0.8 * 0.01f);
}
if (this->timers[0] == 40) {
func_8002DF54(play, &this->actor, 0x13);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x13);
}
if (this->timers[0] == 0) {
this->introState = BFD_CS_LOOK_GROUND;
@ -428,7 +428,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) {
this->timers[0] = 170;
this->camData.speedMod = 0.0f;
this->camData.accel = 0.0f;
func_8002DF54(play, &this->actor, 0x14);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x14);
}
break;
case BFD_CS_COLLAPSE:
@ -478,7 +478,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) {
if (this->timers[3] == 190) {
this->camData.atMaxVel.x = this->camData.atMaxVel.y = this->camData.atMaxVel.z = 0.05f;
this->platformSignal = VBSIMA_KILL;
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
}
if (this->actor.world.pos.y > 120.0f) {
this->camData.nextAt = this->actor.world.pos;
@ -546,7 +546,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) {
func_800C08AC(play, this->introCamera, 0);
this->introState = this->introFlyState = this->introCamera = BFD_CS_NONE;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
this->actionFunc = BossFd_Wait;
this->handoffSignal = FD2_SIGNAL_GROUND;
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE);
@ -854,7 +854,7 @@ void BossFd_Fly(BossFd* this, PlayState* play) {
this->work[BFD_CAM_SHAKE_TIMER] = 20;
Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_LAND2, &this->actor.projectedPos, 4, &D_801333E0,
&D_801333E0, &D_801333E8);
func_8002DF54(play, &this->actor, 5);
Player_SetCsActionWithHaltedActors(play, &this->actor, 5);
for (i1 = 0; i1 < 15; i1++) {
Vec3f sp144 = { 0.0f, 0.0f, 0.0f };
Vec3f sp138 = { 0.0f, 0.0f, 0.0f };

View File

@ -661,7 +661,7 @@ void BossFd2_Death(BossFd2* this, PlayState* play) {
case DEATH_START:
this->deathState = DEATH_RETREAT;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->deathCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->deathCamera, CAM_STAT_ACTIVE);
@ -754,7 +754,7 @@ void BossFd2_Death(BossFd2* this, PlayState* play) {
this->work[FD2_ACTION_STATE]++;
this->camData.speedMod = 0.0f;
this->camData.accel = 0.02f;
func_8002DF54(play, &bossFd->actor, 1);
Player_SetCsActionWithHaltedActors(play, &bossFd->actor, 1);
}
}
if ((bossFd->work[BFD_ACTION_STATE] == BOSSFD_BONES_FALL) && (bossFd->timers[0] == 5)) {
@ -788,7 +788,7 @@ void BossFd2_Death(BossFd2* this, PlayState* play) {
func_800C08AC(play, this->deathCamera, 0);
this->deathCamera = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
if (!IS_BOSS_RUSH) {
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0,
0, WARP_DUNGEON_ADULT);

View File

@ -564,7 +564,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) {
this->actor.shape.rot.y = 0;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->csCamIndex = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->csCamIndex, CAM_STAT_ACTIVE);
@ -609,7 +609,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) {
BossGanon_SetIntroCsCamera(this, 1);
if (this->csTimer == 10) {
func_8002DF54(play, &this->actor, 5);
Player_SetCsActionWithHaltedActors(play, &this->actor, 5);
}
if (this->csTimer == 13) {
@ -642,7 +642,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) {
break;
}
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->csState = 4;
BossGanon_SetIntroCsCamera(this, 2);
this->csTimer = 0;
@ -674,7 +674,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) {
}
if (this->csTimer == 10) {
func_8002DF54(play, &this->actor, 0x4B);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4B);
}
if (this->csTimer == 70) {
@ -740,7 +740,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) {
this->csState = 9;
this->csTimer = 0;
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
sBossGanonZelda->unk_3C8 = 0;
this->triforceType = GDF_TRIFORCE_ZELDA;
this->fwork[GDF_TRIFORCE_SCALE] = 10.0f;
@ -794,7 +794,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) {
player->actor.world.pos.z = 20.0f;
if (this->csTimer == 20) {
func_8002DF54(play, &this->actor, 0x17);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x17);
Interface_ChangeAlpha(11); // show hearts only
}
@ -1031,7 +1031,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) {
}
if (this->csTimer == 30) {
func_8002DF54(play, &this->actor, 0x4A);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4A);
}
if (this->csTimer <= 50) {
@ -1154,7 +1154,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) {
func_800C08AC(play, this->csCamIndex, 0);
this->csState = this->csCamIndex = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
BossGanon_SetupWait(this, play);
}
@ -1267,7 +1267,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) {
switch (this->csState) {
case 0:
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->csCamIndex = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->csCamIndex, CAM_STAT_ACTIVE);
@ -1510,7 +1510,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_BODY_SPARK - SFX_FLAG);
if (this->csTimer == 2) {
func_8002DF54(play, &this->actor, 0x39);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39);
}
if (this->csTimer > 50) {
@ -1552,7 +1552,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) {
case 100:
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->csCamIndex = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->csCamIndex, CAM_STAT_ACTIVE);
@ -1651,11 +1651,11 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) {
this->csCamAt.z = -135.0f;
if (this->csTimer == 5) {
func_8002DF54(play, &this->actor, 0x4C);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4C);
}
if (this->csTimer == 70) {
func_8002DF54(play, &this->actor, 0x4D);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4D);
}
if (this->csTimer == 90) {
@ -1754,7 +1754,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) {
if (this->csTimer == 20) {
sBossGanonZelda->unk_3C8 = 5;
func_8002DF54(play, &this->actor, 0x39);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39);
}
if (this->csTimer == 40) {
@ -1821,7 +1821,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) {
this->csState = 107;
this->csTimer = 0;
Message_StartTextbox(play, 0x70D2, NULL);
func_8002DF54(play, &this->actor, 0x39);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39);
}
break;
@ -1863,7 +1863,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) {
this->csState = 109;
this->csCamIndex = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
Flags_SetSwitch(play, 0x37);
}
break;

View File

@ -228,7 +228,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
objectIdx = Object_GetIndex(&play->objectCtx, OBJECT_GANON_ANIME3);
if (Object_IsLoaded(&play->objectCtx, objectIdx)) {
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->unk_39E = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE);
@ -306,11 +306,11 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
}
if (this->csTimer == 40) {
sBossGanon2Zelda->unk_3C8 = 1;
func_8002DF54(play, &this->actor, 0x4E);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4E);
}
if (this->csTimer == 85) {
sBossGanon2Zelda->unk_3C8 = 2;
func_8002DF54(play, &this->actor, 0x4F);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x4F);
}
this->unk_3A4.x = 930.0f;
this->unk_3A4.y = 1129.0f;
@ -339,14 +339,14 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
}
if (this->csTimer == 20) {
sBossGanon2Zelda->unk_3C8 = 3;
func_8002DF54(play, &this->actor, 0x50);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x50);
}
if (this->csTimer == 55) {
this->csState = 4;
this->csTimer = 0;
this->unk_410.x = 0.0f;
sBossGanon2Zelda->unk_3C8 = 4;
func_8002DF54(play, &this->actor, 0x50);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x50);
}
break;
case 4:
@ -363,7 +363,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
func_800C08AC(play, this->unk_39E, 0);
this->unk_39E = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
this->csState = 5;
this->csTimer = 0;
}
@ -409,7 +409,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
}
if (this->csTimer == 30) {
sBossGanon2Zelda->unk_3C8 = 5;
func_8002DF54(play, &this->actor, 0x51);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x51);
}
if (this->csTimer == 50) {
this->csTimer = 0;
@ -440,7 +440,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
func_80078884(NA_SE_EV_STONE_BOUND);
}
if (this->csTimer == 30) {
func_8002DF54(play, &this->actor, 0x52);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x52);
}
if (this->csTimer == 50) {
this->csTimer = 0;
@ -505,7 +505,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
this->unk_3B0.y = player->actor.world.pos.y;
this->unk_3B0.z = player->actor.world.pos.z - 200.0f;
if (this->csTimer == 20) {
func_8002DF54(play, &this->actor, 0x1E);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x1E);
}
if (this->csTimer == 60) {
this->unk_3A4.x = (this->actor.world.pos.x + 200.0f) - 154.0f;
@ -593,7 +593,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
SkelAnime_Free(&this->skelAnime, play);
SkelAnime_InitFlex(play, &this->skelAnime, &gGanonSkel, NULL, NULL, NULL, 0);
BossGanon2_SetObjectSegment(this, play, OBJECT_GANON_ANIME3, false);
func_8002DF54(play, &this->actor, 0x54);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x54);
this->unk_314 = 3;
// At this point, the actor has Ganon's skeleton but is still playing an animation for Ganondorf. This
@ -657,7 +657,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
this->actor.world.pos.x += 250;
this->actor.world.pos.y = 1886.0f;
this->unk_394 = 0.0f;
func_8002DF54(play, &this->actor, 0x53);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x53);
this->unk_30C = 5.0f;
this->unk_228 = 1.0f;
}
@ -742,7 +742,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
if (this->csTimer == 215) {
this->csState = 23;
this->unk_224 = 0.0f;
func_8002DF54(play, &this->actor, 0x55);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x55);
}
break;
case 23:
@ -762,7 +762,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
this->unk_3B0.z = player->actor.world.pos.z;
if (this->csTimer == 228) {
func_80078884(NA_SE_IT_SHIELD_REFLECT_SW);
func_8002DF54(play, &this->actor, 0x56);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x56);
func_800A9F6C(0.0f, 0xFF, 0xA, 0x32);
}
if (this->csTimer >= 229) {
@ -799,7 +799,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
func_80078884(NA_SE_IT_SWORD_SWING);
}
if (this->csTimer == 25) {
func_8002DF54(play, &this->actor, 0x57);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x57);
this->csState = 25;
this->csTimer = 0;
}
@ -846,7 +846,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
case 27:
this->unk_3BC.z = 0.0f;
if (this->csTimer == 4) {
func_8002DF54(play, &this->actor, 0x58);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x58);
}
this->unk_3A4.x = player->actor.world.pos.x - 20.0f;
this->unk_3A4.y = player->actor.world.pos.y + 50.0f;
@ -919,7 +919,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) {
func_800C08AC(play, this->unk_39E, 0);
this->unk_39E = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
this->csState = 0;
this->unk_337 = 1;
func_808FFDB0(this, play);
@ -1340,7 +1340,7 @@ void func_80900890(BossGanon2* this, PlayState* play) {
this->unk_39E = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->csState = 1;
this->unk_3A4 = sp4C->eye;
this->unk_3B0 = sp4C->at;
@ -1388,7 +1388,7 @@ void func_80900890(BossGanon2* this, PlayState* play) {
func_800C08AC(play, this->unk_39E, 0);
this->unk_39E = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
this->csState = 3;
}
break;
@ -1399,7 +1399,7 @@ void func_80900890(BossGanon2* this, PlayState* play) {
Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE);
this->csState = 11;
this->unk_334 = 1;
func_8002DF54(play, &this->actor, 0x60);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x60);
this->csTimer = 0;
case 11:
player->actor.world.pos.x = sBossGanon2Zelda->actor.world.pos.x + 50.0f + 10.0f;
@ -1420,7 +1420,7 @@ void func_80900890(BossGanon2* this, PlayState* play) {
func_800C08AC(play, this->unk_39E, 0);
this->unk_39E = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
}
break;
}
@ -1536,7 +1536,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) {
this->unk_39E = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->csState = 1;
this->csTimer = 0;
sBossGanon2Zelda->unk_3C8 = 9;
@ -1572,7 +1572,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) {
this->skelAnime.playSpeed = 3.0f;
}
if (this->csTimer == 120) {
func_8002DF54(play, &this->actor, 0x63);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x63);
}
this->actor.world.rot.y = 0x4000;
this->actor.world.pos.x = this->actor.world.pos.z = 0.0f;
@ -1640,7 +1640,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) {
this->csState = 5;
this->csTimer = 40;
this->skelAnime.playSpeed = 1.0f;
func_8002DF54(play, &this->actor, 0x64);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x64);
}
break;
case 5:
@ -1654,10 +1654,10 @@ void func_8090120C(BossGanon2* this, PlayState* play) {
Math_ApproachZeroF(&this->unk_38C, 1.0f, 8.0f);
}
if (this->csTimer == 70) {
func_8002DF54(play, &this->actor, 0x65);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x65);
}
if (this->csTimer == 150) {
func_8002DF54(play, &this->actor, 0x66);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x66);
}
this->unk_30C = 10.0f;
player->actor.world.pos.x = 250.0f;
@ -1676,7 +1676,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) {
func_800C08AC(play, this->unk_39E, 0);
this->unk_39E = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
this->csState = 6;
}
break;
@ -1764,7 +1764,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) {
if (this->csTimer == 55) {
Animation_MorphToPlayOnce(&this->skelAnime, &gGanonDeadStartAnim, 0.0f);
this->unk_194 = Animation_GetLastFrame(&gGanonDeadStartAnim);
func_8002DF54(play, &this->actor, 0x62);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x62);
this->csState = 8;
this->csTimer = 1000;
}

View File

@ -926,7 +926,7 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) {
switch (this->deathState) {
case DEATH_START:
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->deathCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
osSyncPrintf("7\n");
@ -1104,7 +1104,7 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) {
func_800C08AC(play, this->deathCamera, 0);
this->deathCamera = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
if (!IS_BOSS_RUSH) {
Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, GND_BOSSROOM_CENTER_X, GND_BOSSROOM_CENTER_Y,
GND_BOSSROOM_CENTER_Z + 200.0f, 0, 0, 0, 0, true);

View File

@ -628,7 +628,7 @@ void BossGoma_SetupEncounterState4(BossGoma* this, PlayState* play) {
this->actionState = 4;
this->actor.flags |= ACTOR_FLAG_TARGETABLE;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->subCameraId = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, 0, 3);
Play_ChangeCameraStatus(play, this->subCameraId, 7);
@ -685,7 +685,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) {
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_SHUTTER, 164.72f,
-480.0f, 397.68002f, 0, -0x705C, 0, 0x180);
} else {
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->actionState = 1;
}
}
@ -756,7 +756,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) {
}
if (this->frameCount == 190) {
func_8002DF54(play, &this->actor, 2);
Player_SetCsActionWithHaltedActors(play, &this->actor, 2);
}
if (this->frameCount >= 228) {
@ -767,7 +767,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) {
func_800C08AC(play, this->subCameraId, 0);
this->subCameraId = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
this->actionState = 3;
}
break;
@ -964,7 +964,7 @@ void BossGoma_Encounter(BossGoma* this, PlayState* play) {
this->disableGameplayLogic = false;
this->patienceTimer = 200;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
}
break;
}
@ -1054,7 +1054,7 @@ void BossGoma_Defeated(BossGoma* this, PlayState* play) {
case 0:
this->actionState = 1;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->subCameraId = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, 0, 3);
Play_ChangeCameraStatus(play, this->subCameraId, 7);
@ -1189,7 +1189,7 @@ void BossGoma_Defeated(BossGoma* this, PlayState* play) {
func_800C08AC(play, this->subCameraId, 0);
this->subCameraId = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
Actor_Kill(&this->actor);
}

View File

@ -1249,7 +1249,7 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) {
(fabsf(player->actor.world.pos.x - -180.0f) < 40.0f))) {
// checks if Link is on one of the four platforms
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->csCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->csCamera, CAM_STAT_ACTIVE);
@ -1357,11 +1357,11 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) {
Math_ApproachF(&this->actor.speedXZ, sp80, 1.0f, sp78);
Math_ApproachF(&this->cameraYawRate, sp7C, 1.0f, 128.0f);
if (this->work[MO_TENT_MOVE_TIMER] == 525) {
func_8002DF54(play, &this->actor, 2);
Player_SetCsActionWithHaltedActors(play, &this->actor, 2);
}
if (this->work[MO_TENT_MOVE_TIMER] > 540) {
this->csState = MO_INTRO_REVEAL;
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
sMorphaTent1->drawActor = true;
player->actor.world.pos.x = 180.0f;
player->actor.world.pos.z = -210.0f;
@ -1468,7 +1468,7 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) {
func_800C08AC(play, this->csCamera, 0);
this->csState = this->csCamera = MO_BATTLE;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
}
break;
}
@ -1533,7 +1533,7 @@ void BossMo_DeathCs(BossMo* this, PlayState* play) {
switch (this->csState) {
case MO_DEATH_START:
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->csCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->csCamera, CAM_STAT_ACTIVE);
@ -1700,7 +1700,7 @@ void BossMo_DeathCs(BossMo* this, PlayState* play) {
func_800C08AC(play, this->csCamera, 0);
this->csCamera = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
sMorphaTent1->actor.world.pos.y = -1000.0f;
}
} else {

View File

@ -390,7 +390,7 @@ void BossSst_HeadSetupIntro(BossSst* this, PlayState* play) {
player->stateFlags1 |= PLAYER_STATE1_INPUT_DISABLED;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
sCutsceneCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, sCutsceneCamera, CAM_STAT_ACTIVE);
@ -423,7 +423,7 @@ void BossSst_HeadIntro(BossSst* this, PlayState* play) {
sHands[LEFT]->actor.flags |= ACTOR_FLAG_TARGETABLE;
player->stateFlags1 &= ~PLAYER_STATE1_INPUT_DISABLED;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
sCameraAt.y += 30.0f;
sCameraAt.z += 300.0f;
Play_CameraSetAtEye(play, sCutsceneCamera, &sCameraAt, &sCameraEye);
@ -1032,7 +1032,7 @@ void BossSst_HeadSetupDeath(BossSst* this, PlayState* play) {
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, sCutsceneCamera, CAM_STAT_ACTIVE);
Play_CopyCamera(play, sCutsceneCamera, MAIN_CAM);
func_8002DF54(play, &player->actor, 8);
Player_SetCsActionWithHaltedActors(play, &player->actor, 8);
func_80064520(play, &play->csCtx);
Math_Vec3f_Copy(&sCameraEye, &GET_ACTIVE_CAM(play)->eye);
this->actionFunc = BossSst_HeadDeath;
@ -1194,7 +1194,7 @@ void BossSst_HeadFinish(BossSst* this, PlayState* play) {
Play_ChangeCameraStatus(play, sCutsceneCamera, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
Play_ClearCamera(play, sCutsceneCamera);
func_8002DF54(play, &GET_PLAYER(play)->actor, 7);
Player_SetCsActionWithHaltedActors(play, &GET_PLAYER(play)->actor, 7);
func_80064534(play, &play->csCtx);
Actor_Kill(&this->actor);
Actor_Kill(&sHands[LEFT]->actor);

View File

@ -1466,7 +1466,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) {
case 0:
this->csState2 = 1;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 0x39);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39);
this->subCamId = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, 0, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE);
@ -1606,7 +1606,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) {
Animation_MorphToPlayOnce(&this->skelAnime, &gTwinrovaIntroAnim, 0.0f);
this->workf[ANIM_SW_TGT] = Animation_GetLastFrame(&gTwinrovaIntroAnim);
this->timers[0] = 50;
func_8002DF54(play, &this->actor, 2);
Player_SetCsActionWithHaltedActors(play, &this->actor, 2);
Audio_PlayActorSound2(&this->actor, NA_SE_EN_TWINROBA_TRANSFORM);
Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS);
}
@ -1649,7 +1649,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) {
}
if (this->timers[3] == 19) {
func_8002DF54(play, &this->actor, 5);
Player_SetCsActionWithHaltedActors(play, &this->actor, 5);
}
if (this->timers[3] == 16) {
@ -1682,7 +1682,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) {
this->subCamId = 0;
this->csState2 = this->subCamId;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
this->work[TW_PLLR_IDX] = 0;
this->targetPos = sTwinrovaPillarPos[0];
BossTw_TwinrovaSetupFly(this, play);
@ -1762,7 +1762,7 @@ void BossTw_TwinrovaIntroCS(BossTw* this, PlayState* play) {
player->actor.world.pos.x = player->actor.world.pos.z = .0f;
this->csState2 = 1;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 0x39);
Player_SetCsActionWithHaltedActors(play, &this->actor, 0x39);
this->subCamId = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, 0, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE);
@ -2245,7 +2245,7 @@ void BossTw_TwinrovaIntroCS(BossTw* this, PlayState* play) {
this->subCamId = 0;
this->csState2 = this->subCamId;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
BossTw_SetupWait(this, play);
}
break;
@ -2666,7 +2666,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) {
case 0:
this->csState2 = 1;
func_80064520(play, &play->csCtx);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
this->subCamId = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, 0, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE);
@ -2705,7 +2705,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) {
sKoumePtr->actor.world.pos.z = sKotakePtr->actor.world.pos.z;
sKoumePtr->work[YAW_TGT] = sKotakePtr->work[YAW_TGT] = sKoumePtr->actor.shape.rot.x =
sKotakePtr->actor.shape.rot.x = sKoumePtr->actor.shape.rot.y = sKotakePtr->actor.shape.rot.y = 0;
func_8002DF54(play, &sKoumePtr->actor, 1);
Player_SetCsActionWithHaltedActors(play, &sKoumePtr->actor, 1);
sKoumePtr->actor.flags |= ACTOR_FLAG_TARGETABLE;
}
break;
@ -2793,7 +2793,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) {
this->csState2 = 4;
this->subCamId = 0;
func_80064534(play, &play->csCtx);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS_CLEAR);
if (!IS_BOSS_RUSH) {
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0,

View File

@ -657,7 +657,7 @@ void BossVa_Init(Actor* thisx, PlayState* play2) {
} else {
sCsState = INTRO_CALL_BARI;
sDoorState = 100;
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
play->envCtx.screenFillColor[0] = 0xDC;
play->envCtx.screenFillColor[1] = 0xDC;
play->envCtx.screenFillColor[2] = 0xBE;
@ -799,7 +799,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) {
play->envCtx.screenFillColor[1] = 0xDC;
play->envCtx.screenFillColor[2] = 0xBE;
play->envCtx.screenFillColor[3] = 0xD2;
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
player->actor.world.rot.y = player->actor.shape.rot.y = 0x7FFF;
sCsState++;
break;
@ -827,7 +827,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) {
case INTRO_CLOSE_DOOR:
this->timer--;
if (this->timer == 0) {
func_8002DF54(play, &this->actor, 2);
Player_SetCsActionWithHaltedActors(play, &this->actor, 2);
sCsState++;
this->timer = 30;
}
@ -842,7 +842,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) {
}
break;
case INTRO_CRACKLE:
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
sCsState++;
break;
case INTRO_SPAWN_BARI:
@ -973,7 +973,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) {
sCameraAtMaxVel = sCameraEyeMaxVel;
if (this->timer >= 45000) {
play->envCtx.unk_BF = 1;
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
} else if (this->timer >= 35000) {
Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS);
}
@ -1030,7 +1030,7 @@ void BossVa_BodyIntro(BossVa* this, PlayState* play) {
sCsCamera = 0;
func_80064534(play, &play->csCtx);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
sCsState++;
Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE);
player->actor.shape.rot.y = player->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000;
@ -1550,7 +1550,7 @@ void BossVa_BodyDeath(BossVa* this, PlayState* play) {
switch (sCsState) {
case DEATH_START:
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
func_80064520(play, &play->csCtx);
sCsCamera = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
@ -1613,7 +1613,7 @@ void BossVa_BodyDeath(BossVa* this, PlayState* play) {
0x28);
this->onCeiling = 2; // Not used by body
BossVa_SetDeathEnv(play);
func_8002DF54(play, &this->actor, 8);
Player_SetCsActionWithHaltedActors(play, &this->actor, 8);
}
break;
case DEATH_CORE_BURST:
@ -1654,7 +1654,7 @@ void BossVa_BodyDeath(BossVa* this, PlayState* play) {
camera->at = sCameraAt;
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
sCsState++;
if (!IS_BOSS_RUSH) {
@ -2444,7 +2444,7 @@ void BossVa_BariIntro(BossVa* this, PlayState* play) {
switch (sCsState) {
case INTRO_LOOK_BARI:
if (this->actor.params == BOSSVA_BARI_UPPER_1) {
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
if (Math_SmoothStepToF(&this->actor.world.pos.y, 60.0f, 0.3f, 1.0f, 0.15f) == 0.0f) {
this->timer--;
if (this->timer == 0) {

View File

@ -3,6 +3,7 @@
#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@ -184,7 +185,9 @@ void func_80969F38(DemoDu* this, PlayState* play) {
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0,
DEMO_EFFECT_MEDAL_FIRE);
Item_Give(play, ITEM_MEDALLION_FIRE);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) {
Item_Give(play, ITEM_MEDALLION_FIRE);
}
}
void func_80969FB4(DemoDu* this, PlayState* play) {
@ -201,7 +204,9 @@ void DemoDu_CsFireMedallion_AdvanceTo01(DemoDu* this, PlayState* play) {
this->updateIndex = CS_FIREMEDALLION_SUBSCENE(1);
play->csCtx.segment = D_8096C1A4;
gSaveContext.cutsceneTrigger = 2;
Item_Give(play, ITEM_MEDALLION_FIRE);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) {
Item_Give(play, ITEM_MEDALLION_FIRE);
}
player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000;
}

View File

@ -142,7 +142,7 @@ f32 DemoEffect_InterpolateCsFrames(PlayState* play, s32 csActionId) {
*/
void DemoEffect_InitJewel(PlayState* play, DemoEffect* this) {
this->initDrawFunc = DemoEffect_DrawJewel;
if (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) {
if (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) {
this->initDrawFunc = DemoEffect_DrawGetItem;
}
if (!LINK_IS_ADULT) {
@ -156,7 +156,7 @@ void DemoEffect_InitJewel(PlayState* play, DemoEffect* this) {
Actor_SetScale(&this->actor, 0.10f);
}
this->csActionId = 1;
this->actor.shape.rot.x = (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) ? 0 : 16384;
this->actor.shape.rot.x = (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) ? 0 : 16384;
DemoEffect_InitJewelColor(this);
this->jewel.alpha = 0;
this->jewelCsRotation.x = this->jewelCsRotation.y = this->jewelCsRotation.z = 0;
@ -2087,13 +2087,48 @@ void DemoEffect_DrawGetItem(Actor* thisx, PlayState* play) {
this->getItem.isLoaded = 1;
return;
}
if (IS_RANDO && play->sceneNum == SCENE_JABU_JABU) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE);
this->getItem.drawId = getItemEntry.gid;
func_8002EBCC(thisx, play, 0);
func_8002ED80(thisx, play, 0);
GetItemEntry_Draw(play, getItemEntry);
return;
if (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) {
GetItemEntry getItemEntry = GET_ITEM_NONE;
switch (this->actor.params) {
case DEMO_EFFECT_JEWEL_KOKIRI:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_QUEEN_GOHMA, RG_KOKIRI_EMERALD);
break;
case DEMO_EFFECT_JEWEL_GORON:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KING_DODONGO, RG_GORON_RUBY);
break;
case DEMO_EFFECT_JEWEL_ZORA:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE);
break;
case DEMO_EFFECT_MEDAL_FOREST:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_PHANTOM_GANON, RG_FOREST_MEDALLION);
break;
case DEMO_EFFECT_MEDAL_FIRE:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_VOLVAGIA, RG_FIRE_MEDALLION);
break;
case DEMO_EFFECT_MEDAL_WATER:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MORPHA, RG_WATER_MEDALLION);
break;
case DEMO_EFFECT_MEDAL_SPIRIT:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TWINROVA, RG_SPIRIT_MEDALLION);
break;
case DEMO_EFFECT_MEDAL_SHADOW:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BONGO_BONGO, RG_SHADOW_MEDALLION);
break;
case DEMO_EFFECT_MEDAL_LIGHT:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION);
break;
case DEMO_EFFECT_LIGHTARROW:
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS);
break;
}
if (getItemEntry.getItemId != GI_NONE) {
this->getItem.drawId = getItemEntry.gid;
func_8002EBCC(thisx, play, 0);
func_8002ED80(thisx, play, 0);
GetItemEntry_Draw(play, getItemEntry);
return;
}
}
func_8002EBCC(thisx, play, 0);
func_8002ED80(thisx, play, 0);

View File

@ -10,6 +10,7 @@
#include "scenes/indoors/nakaniwa/nakaniwa_scene.h"
#include "objects/object_im/object_im.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@ -318,7 +319,9 @@ void func_809853B4(DemoIm* this, PlayState* play) {
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, playerX, playerY, playerZ, 0,
0, 0, 0xD);
Item_Give(play, ITEM_MEDALLION_SHADOW);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_SHADOW_MEDALLION, true, NULL)) {
Item_Give(play, ITEM_MEDALLION_SHADOW);
}
}
void func_80985430(DemoIm* this, PlayState* play) {
@ -334,7 +337,9 @@ void func_8098544C(DemoIm* this, PlayState* play) {
this->action = 1;
play->csCtx.segment = D_8098786C;
gSaveContext.cutsceneTrigger = 2;
Item_Give(play, ITEM_MEDALLION_SHADOW);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_SHADOW_MEDALLION, true, NULL)) {
Item_Give(play, ITEM_MEDALLION_SHADOW);
}
player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000;
}
}
@ -875,7 +880,7 @@ void func_80986B2C(PlayState* play) {
}
play->transitionType = TRANS_TYPE_CIRCLE(TCA_STARBURST, TCC_BLACK, TCS_FAST);
play->transitionTrigger = TRANS_TRIGGER_START;
func_8002DF54(play, &player->actor, 8);
Player_SetCsActionWithHaltedActors(play, &player->actor, 8);
}
}
@ -903,40 +908,17 @@ void func_80986BF8(DemoIm* this, PlayState* play) {
}
}
void GivePlayerRandoRewardImpa(Actor* impa, PlayState* play, RandomizerCheck check) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY);
if (impa->parent != NULL && impa->parent->id == GET_PLAYER(play)->actor.id &&
!Flags_GetTreasure(play, 0x1F)) {
Flags_SetTreasure(play, 0x1F);
} else if (!Flags_GetTreasure(play, 0x1F) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) {
GiveItemEntryFromActor(impa, play, getItemEntry, 75.0f, 50.0f);
} else if (!Player_InBlockingCsMode(play, GET_PLAYER(play))) {
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY);
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_WHITE;
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE;
// In entrance rando have impa bring link back to the front of castle grounds
if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) {
play->nextEntranceIndex = ENTR_HYRULE_CASTLE_0;
} else {
play->nextEntranceIndex = ENTR_HYRULE_FIELD_17;
}
gSaveContext.nextCutsceneIndex = 0;
}
}
void func_80986C30(DemoIm* this, PlayState* play) {
if (func_80986A5C(this, play)) {
if (IS_RANDO) {
GivePlayerRandoRewardImpa(this, play, RC_SONG_FROM_IMPA);
} else {
if (GameInteractor_Should(GI_VB_PLAY_ZELDAS_LULLABY_CS, true, this)) {
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gZeldasCourtyardLullabyCs);
gSaveContext.cutsceneTrigger = 1;
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY);
Item_Give(play, ITEM_SONG_LULLABY);
func_80985F54(this);
}
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LULLABY, true, NULL)) {
Item_Give(play, ITEM_SONG_LULLABY);
}
}
}
@ -960,7 +942,7 @@ void func_80986D40(DemoIm* this, PlayState* play) {
if (gSaveContext.sceneSetupIndex == 6) {
this->action = 19;
this->drawConfig = 1;
} else if ((Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) && !IS_RANDO) {
} else if ((Flags_GetEventChkInf(EVENTCHKINF_ZELDA_FLED_HYRULE_CASTLE)) && !IS_RANDO) { // SoH [Randomizer] Not sure why we're not killing impa here.
Actor_Kill(&this->actor);
} else if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY)) {
this->action = 23;

View File

@ -51,4 +51,6 @@ typedef struct DemoIm {
/* 0x02D4 */ NpcInteractInfo interactInfo;
} DemoIm; // size = 0x02FC
void func_80986794(DemoIm* demoIm);
#endif

View File

@ -9,6 +9,7 @@
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "objects/object_sa/object_sa.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "vt.h"
@ -241,7 +242,9 @@ void func_8098E8C8(DemoSa* this, PlayState* play) {
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0,
0xB);
Item_Give(play, ITEM_MEDALLION_FOREST);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FOREST_MEDALLION, true, NULL)) {
Item_Give(play, ITEM_MEDALLION_FOREST);
}
}
void func_8098E944(DemoSa* this, PlayState* play) {
@ -258,7 +261,9 @@ void func_8098E960(DemoSa* this, PlayState* play) {
this->action = 1;
play->csCtx.segment = D_8099010C;
gSaveContext.cutsceneTrigger = 2;
Item_Give(play, ITEM_MEDALLION_FOREST);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FOREST_MEDALLION, true, NULL)) {
Item_Give(play, ITEM_MEDALLION_FOREST);
}
player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y + 0x8000;
} else {
this->action = 1;

View File

@ -20,7 +20,6 @@ void DoorAna_WaitClosed(DoorAna* this, PlayState* play);
void DoorAna_WaitOpen(DoorAna* this, PlayState* play);
void DoorAna_GrabPlayer(DoorAna* this, PlayState* play);
s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, PlayState* play);
void Grotto_OverrideActorEntrance(Actor* thisx);
const ActorInit Door_Ana_InitVars = {

View File

@ -23,6 +23,7 @@
#include "objects/object_menkuri_objects/object_menkuri_objects.h"
#include "objects/object_demo_kekkai/object_demo_kekkai.h"
#include "objects/object_ouke_haka/object_ouke_haka.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@ -354,9 +355,11 @@ void func_80996A54(DoorShutter* this, PlayState* play) {
if (Flags_GetClear(play, this->dyna.actor.room) || Flags_GetTempClear(play, this->dyna.actor.room)) {
Flags_SetClear(play, this->dyna.actor.room);
DoorShutter_SetupAction(this, func_80997150);
OnePointCutscene_Attention(play, &this->dyna.actor);
OnePointCutscene_Attention(play, &GET_PLAYER(play)->actor);
this->unk_16F = -100;
if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) {
OnePointCutscene_Attention(play, &this->dyna.actor);
OnePointCutscene_Attention(play, &GET_PLAYER(play)->actor);
this->unk_16F = -100;
}
} else if (func_809968D4(this, play) != 0) {
Player* player = GET_PLAYER(play);
@ -470,8 +473,10 @@ void func_80996EE8(DoorShutter* this, PlayState* play) {
if (func_80996E08(this, play, 1.0f)) {
if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) {
DoorShutter_SetupAction(this, func_80997150);
OnePointCutscene_Attention(play, &this->dyna.actor);
this->unk_16F = -100;
if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) {
OnePointCutscene_Attention(play, &this->dyna.actor);
this->unk_16F = -100;
}
} else if (func_809968D4(this, play)) {
Player* player = GET_PLAYER(play);
// Jabu navi text for switch doors is different
@ -555,7 +560,7 @@ void func_80997220(DoorShutter* this, PlayState* play) {
this->dyna.actor.velocity.y = 0.0f;
if (DoorShutter_SetupDoor(this, play) && !(player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
DoorShutter_SetupAction(this, func_80997568);
func_8002DF54(play, NULL, 2);
Player_SetCsActionWithHaltedActors(play, NULL, 2);
}
}
@ -589,7 +594,7 @@ void func_80997528(DoorShutter* this, PlayState* play) {
void func_80997568(DoorShutter* this, PlayState* play) {
if (this->unk_16F++ > 30) {
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
DoorShutter_SetupDoor(this, play);
}
}

View File

@ -2,6 +2,7 @@
#include "objects/object_warp1/object_warp1.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS 0
@ -487,44 +488,6 @@ s32 DoorWarp1_PlayerInRange(DoorWarp1* this, PlayState* play) {
return ret;
}
void GivePlayerRandoReward(DoorWarp1* this, Player* player, PlayState* play, u8 ruto, u8 adult) {
GetItemEntry getItemEntry = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, 0x00, GI_NONE);
if (this->actor.parent != NULL && this->actor.parent->id == GET_PLAYER(play)->actor.id &&
!Flags_GetTreasure(play, 0x1F)) {
Flags_SetTreasure(play, 0x1F);
} else if (!Flags_GetTreasure(play, 0x1F)) {
GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 100.0f);
} else if (!Player_InBlockingCsMode(play, GET_PLAYER(play))) {
if (adult) {
OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM);
func_8002DF54(play, &this->actor, 10);
player->unk_450.x = this->actor.world.pos.x;
player->unk_450.z = this->actor.world.pos.z;
this->unk_1B2 = 20;
DoorWarp1_SetupAction(this, func_8099A508);
} else {
if (ruto) {
this->rutoWarpState = WARP_BLUE_RUTO_STATE_ENTERED;
func_8002DF54(play, &this->actor, 10);
this->unk_1B2 = 1;
DoorWarp1_SetupAction(this, func_80999EE0);
} else {
Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0,
&D_801333E8);
OnePointCutscene_Init(play, 0x25E7, 999, &this->actor, MAIN_CAM);
func_8002DF54(play, &this->actor, 10);
player->unk_450.x = this->actor.world.pos.x;
player->unk_450.z = this->actor.world.pos.z;
this->unk_1B2 = 1;
DoorWarp1_SetupAction(this, DoorWarp1_ChildWarpOut);
}
}
}
}
void DoorWarp1_ChildWarpIdle(DoorWarp1* this, PlayState* play) {
Player* player;
@ -532,16 +495,11 @@ void DoorWarp1_ChildWarpIdle(DoorWarp1* this, PlayState* play) {
if (DoorWarp1_PlayerInRange(this, play)) {
player = GET_PLAYER(play);
if (IS_RANDO) {
GivePlayerRandoReward(this, player, play, 0, 0);
return;
}
Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0,
&D_801333E8);
OnePointCutscene_Init(play, 0x25E7, 999, &this->actor, MAIN_CAM);
func_8002DF54(play, &this->actor, 10);
Player_SetCsActionWithHaltedActors(play, &this->actor, 10);
player->unk_450.x = this->actor.world.pos.x;
player->unk_450.z = this->actor.world.pos.z;
@ -570,36 +528,26 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) {
osSyncPrintf("\n\n\nじかんがきたからおーしまい fade_direction=[%d]", play->transitionTrigger, TRANS_TRIGGER_START);
if (play->sceneNum == SCENE_DODONGOS_CAVERN_BOSS) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) {
if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP), EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) {
Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN);
if (IS_RANDO) {
play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5;
gSaveContext.nextCutsceneIndex = 0;
} else {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_GORON_RUBY)) {
Item_Give(play, ITEM_GORON_RUBY);
play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0;
gSaveContext.nextCutsceneIndex = 0xFFF1;
}
play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0;
gSaveContext.nextCutsceneIndex = 0xFFF1;
} else {
play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5;
gSaveContext.nextCutsceneIndex = 0;
}
} else if (play->sceneNum == SCENE_DEKU_TREE_BOSS) {
if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || IS_RANDO) {
if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD), EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD)) {
Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD);
Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE);
if (IS_RANDO) {
play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11;
gSaveContext.nextCutsceneIndex = 0;
// Skip Mido complaining about dead Deku tree
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH);
} else {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_KOKIRI_EMERALD)) {
Item_Give(play, ITEM_KOKIRI_EMERALD);
play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0;
gSaveContext.nextCutsceneIndex = 0xFFF1;
}
play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0;
gSaveContext.nextCutsceneIndex = 0xFFF1;
} else {
play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11;
gSaveContext.nextCutsceneIndex = 0;
@ -635,14 +583,8 @@ void DoorWarp1_RutoWarpIdle(DoorWarp1* this, PlayState* play) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_WARP_HOLE - SFX_FLAG);
if (this->rutoWarpState != WARP_BLUE_RUTO_STATE_INITIAL && DoorWarp1_PlayerInRange(this, play)) {
if (IS_RANDO) {
GivePlayerRandoReward(this, GET_PLAYER(play), play, 1, 0);
return;
}
this->rutoWarpState = WARP_BLUE_RUTO_STATE_ENTERED;
func_8002DF54(play, &this->actor, 10);
Player_SetCsActionWithHaltedActors(play, &this->actor, 10);
this->unk_1B2 = 1;
DoorWarp1_SetupAction(this, func_80999EE0);
}
@ -670,9 +612,8 @@ void func_80999EE0(DoorWarp1* this, PlayState* play) {
Play_CameraSetAtEye(play, sRutoWarpSubCamId, &at, &eye);
Play_CameraSetFov(play, sRutoWarpSubCamId, 90.0f);
this->rutoWarpState = WARP_BLUE_RUTO_STATE_TALKING;
if (!IS_RANDO) {
Message_StartTextbox(play, 0x4022, NULL);
}
// TODO: Why was this disabled in rando?
Message_StartTextbox(play, 0x4022, NULL);
DoorWarp1_SetupAction(this, func_80999FE4);
}
}
@ -704,17 +645,14 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) {
this->warpTimer++;
if (this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF) {
Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY);
if (IS_RANDO) {
play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0;
gSaveContext.nextCutsceneIndex = 0;
} else {
Item_Give(play, ITEM_ZORA_SAPPHIRE);
play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0;
if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, true, EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) {
Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_ZORA_SAPPHIRE)) {
Item_Give(play, ITEM_ZORA_SAPPHIRE);
}
gSaveContext.nextCutsceneIndex = 0xFFF0;
}
play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0;
if (IS_RANDO && (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
@ -767,13 +705,8 @@ void DoorWarp1_AdultWarpIdle(DoorWarp1* this, PlayState* play) {
player = GET_PLAYER(play);
if (IS_RANDO) {
GivePlayerRandoReward(this, player, play, 0, 1);
return;
}
OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM);
func_8002DF54(play, &this->actor, 10);
Player_SetCsActionWithHaltedActors(play, &this->actor, 10);
player->unk_450.x = this->actor.world.pos.x;
player->unk_450.z = this->actor.world.pos.z;
this->unk_1B2 = 20;
@ -829,19 +762,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
if (IS_BOSS_RUSH) {
BossRush_HandleBlueWarp(play, this->actor.world.pos.x, this->actor.world.pos.z);
} else if (play->sceneNum == SCENE_FOREST_TEMPLE_BOSS) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) {
if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) {
Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE);
if (IS_RANDO) {
play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3;
gSaveContext.nextCutsceneIndex = 0;
} else {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FOREST)) {
Item_Give(play, ITEM_MEDALLION_FOREST);
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST;
}
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST;
} else {
if (!LINK_IS_ADULT) {
play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_2;
@ -851,20 +779,13 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0;
}
} else if (play->sceneNum == SCENE_FIRE_TEMPLE_BOSS) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) {
if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) {
Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE);
if (IS_RANDO) {
play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5;
gSaveContext.nextCutsceneIndex = 0;
// Change Death Mountain cloud since we aren't warping to the cutscene
Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED);
} else {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FIRE)) {
Item_Give(play, ITEM_MEDALLION_FIRE);
play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0;
gSaveContext.nextCutsceneIndex = 0xFFF3;
}
play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0;
gSaveContext.nextCutsceneIndex = 0xFFF3;
} else {
if (!LINK_IS_ADULT) {
play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_4;
@ -874,21 +795,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0;
}
} else if (play->sceneNum == SCENE_WATER_TEMPLE_BOSS) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE);
if (IS_RANDO) {
play->nextEntranceIndex = ENTR_LAKE_HYLIA_9;
gSaveContext.nextCutsceneIndex = 0;
// Fill Lake Hylia since we aren't warping to the cutscene
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
} else {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_WATER)) {
Item_Give(play, ITEM_MEDALLION_WATER);
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER;
}
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER;
} else {
if (!LINK_IS_ADULT) {
play->nextEntranceIndex = ENTR_LAKE_HYLIA_8;
@ -898,18 +812,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0;
}
} else if (play->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) {
if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) || IS_RANDO) {
if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT), RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE)) {
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE);
if (IS_RANDO) {
play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8;
gSaveContext.nextCutsceneIndex = 0;
} else {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SPIRIT)) {
Item_Give(play, ITEM_MEDALLION_SPIRIT);
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT;
}
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT;
} else {
if (!LINK_IS_ADULT) {
play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_5;
@ -919,18 +829,14 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0;
}
} else if (play->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) {
if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) || IS_RANDO) {
if (GameInteractor_Should(GI_VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW), RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)) {
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE);
if (IS_RANDO) {
play->nextEntranceIndex = ENTR_GRAVEYARD_8;
gSaveContext.nextCutsceneIndex = 0;
} else {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SHADOW)) {
Item_Give(play, ITEM_MEDALLION_SHADOW);
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW;
}
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW;
} else {
if (!LINK_IS_ADULT) {
play->nextEntranceIndex = ENTR_GRAVEYARD_7;

View File

@ -7,6 +7,7 @@
#include "z_elf_msg.h"
#include "vt.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@ -110,7 +111,7 @@ void ElfMsg_Destroy(Actor* thisx, PlayState* play) {
s32 ElfMsg_GetMessageId(ElfMsg* this) {
// Negative message ID forces link to talk to Navi
if (this->actor.params & 0x8000 || CVarGetInteger("gNoForcedNavi", 0) != 0) {
if (this->actor.params & 0x8000) {
return (this->actor.params & 0xFF) + 0x100;
} else {
return -((this->actor.params & 0xFF) + 0x100);
@ -125,8 +126,10 @@ void ElfMsg_CallNaviCuboid(ElfMsg* this, PlayState* play) {
(this->actor.world.pos.y <= player->actor.world.pos.y) &&
((player->actor.world.pos.y - this->actor.world.pos.y) < (100.0f * this->actor.scale.y)) &&
(fabsf(player->actor.world.pos.z - this->actor.world.pos.z) < (100.0f * this->actor.scale.z))) {
player->naviTextId = ElfMsg_GetMessageId(this);
navi->elfMsg = this;
if (GameInteractor_Should(GI_VB_NAVI_TALK, true, this)) {
player->naviTextId = ElfMsg_GetMessageId(this);
navi->elfMsg = this;
}
}
}
@ -145,8 +148,10 @@ void ElfMsg_CallNaviCylinder(ElfMsg* this, PlayState* play) {
if (ElfMsg_WithinXZDistance(&player->actor.world.pos, &this->actor.world.pos, this->actor.scale.x * 100.0f) &&
(this->actor.world.pos.y <= player->actor.world.pos.y) &&
((player->actor.world.pos.y - this->actor.world.pos.y) < (100.0f * this->actor.scale.y))) {
player->naviTextId = ElfMsg_GetMessageId(this);
navi->elfMsg = this;
if (GameInteractor_Should(GI_VB_NAVI_TALK, true, this)) {
player->naviTextId = ElfMsg_GetMessageId(this);
navi->elfMsg = this;
}
}
}

View File

@ -6,6 +6,7 @@
#include "z_en_ani.h"
#include "objects/object_ani/object_ani.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@ -119,7 +120,7 @@ void func_809B0524(EnAni* this, PlayState* play) {
}
void func_809B0558(EnAni* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, true, NULL)) {
this->actor.parent = NULL;
if (!LINK_IS_ADULT) {
EnAni_SetupAction(this, func_809B04F0);
@ -128,11 +129,8 @@ void func_809B0558(EnAni* this, PlayState* play) {
}
Flags_SetItemGetInf(ITEMGETINF_15);
} else {
if (!IS_RANDO) {
func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f);
} else {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE);
GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 200.0f);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, true, NULL)) {
Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f);
}
}
}
@ -142,11 +140,8 @@ void func_809B05F0(EnAni* this, PlayState* play) {
EnAni_SetupAction(this, func_809B0558);
}
if (!IS_RANDO) {
func_8002F434(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f);
} else {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE);
GiveItemEntryFromActor(&this->actor, play, getItemEntry, 10000.0f, 200.0f);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF, true, NULL)) {
Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 10000.0f, 200.0f);
}
}

View File

@ -295,7 +295,7 @@ void EnBomBowMan_RunGame(EnBomBowlMan* this, PlayState* play) {
Message_StartTextbox(play, this->actor.textId, NULL);
if (this->gameResult == 2) {
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
}
this->actionFunc = EnBomBowlMan_HandlePlayChoice;
} else {
@ -345,7 +345,7 @@ void EnBomBowlMan_HandlePlayChoice(EnBomBowlMan* this, PlayState* play) {
Message_ContinueTextbox(play, this->actor.textId);
this->dialogState = TEXT_STATE_EVENT;
OnePointCutscene_Init(play, 8010, -99, NULL, MAIN_CAM);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = EnBomBowMan_SetupChooseShowPrize;
}
} else {
@ -381,11 +381,11 @@ void func_809C41FC(EnBomBowlMan* this, PlayState* play) {
Message_ContinueTextbox(play, this->actor.textId);
this->dialogState = TEXT_STATE_EVENT;
OnePointCutscene_Init(play, 8010, -99, NULL, MAIN_CAM);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = EnBomBowMan_SetupChooseShowPrize;
} else {
if (this->gameResult == 2) {
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
}
this->actionFunc = EnBomBowMan_SetupRunGame;
}
@ -509,7 +509,7 @@ void EnBomBowlMan_BeginPlayGame(EnBomBowlMan* this, PlayState* play) {
// "Wow"
osSyncPrintf(VT_FGCOL(YELLOW) "☆ わー ☆ %d\n" VT_RST, play->bombchuBowlingStatus);
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
this->actionFunc = EnBomBowMan_SetupRunGame;
}
}

View File

@ -68,7 +68,7 @@ void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play) {
if (((fabsf(chuPosDiff.x) < 40.0f) || (BREG(2))) && ((fabsf(chuPosDiff.y) < 40.0f) || (BREG(2))) &&
((fabsf(chuPosDiff.z) < 40.0f) || (BREG(2)))) {
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
chu->timer = 1;
this->camId = Play_CreateSubCamera(play);
@ -107,7 +107,7 @@ void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play) {
Message_StartTextbox(play, this->actor.textId, NULL);
this->unk_154 = TEXT_STATE_EVENT;
func_80078884(NA_SE_EV_HIT_SOUND);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->status = 1;
this->actionFunc = EnBomBowlPit_CameraDollyIn;
break;
@ -167,7 +167,7 @@ void EnBomBowlPit_SetupGivePrize(EnBomBowlPit* this, PlayState* play) {
Play_ClearCamera(play, this->camId);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = EnBomBowlPit_GivePrize;
}
}
@ -175,7 +175,7 @@ void EnBomBowlPit_SetupGivePrize(EnBomBowlPit* this, PlayState* play) {
void EnBomBowlPit_GivePrize(EnBomBowlPit* this, PlayState* play) {
Player* player = GET_PLAYER(play);
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
this->getItemId = sGetItemIds[this->prizeIndex];
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
@ -203,7 +203,7 @@ void EnBomBowlPit_GivePrize(EnBomBowlPit* this, PlayState* play) {
player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE;
this->actor.parent = NULL;
if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) {
func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
} else {
GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f);
}
@ -216,7 +216,7 @@ void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, PlayState* play) {
this->actionFunc = EnBomBowlPit_Reset;
} else {
if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) {
func_8002F434(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
} else {
GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f);
}

View File

@ -3,6 +3,7 @@
#include "soh_assets.h"
#include "soh/Enhancements/enhancementTypes.h"
#include <assert.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS 0
@ -192,10 +193,12 @@ void EnBox_Init(Actor* thisx, PlayState* play2) {
SkelAnime_Init(play, &this->skelanime, &gTreasureChestSkel, anim, this->jointTable, this->morphTable, 5);
Animation_Change(&this->skelanime, anim, 1.5f, animFrameStart, endFrame, ANIMMODE_ONCE, 0.0f);
this->getItemEntry = ItemTable_RetrieveEntry(MOD_NONE, this->dyna.actor.params >> 5 & 0x7F);
if (IS_RANDO) {
this->getItemEntry = Randomizer_GetItemFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params, this->dyna.actor.params >> 5 & 0x7F);
} else {
this->getItemEntry = ItemTable_RetrieveEntry(MOD_NONE, this->dyna.actor.params >> 5 & 0x7F);
RandomizerCheck rc = Randomizer_GetCheckFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params);
if (rc != RC_UNKNOWN_CHECK) {
this->getItemEntry = Randomizer_GetItemFromKnownCheck(rc, this->dyna.actor.params >> 5 & 0x7F);
}
}
EnBox_UpdateSizeAndTexture(this, play);
@ -275,7 +278,9 @@ void EnBox_Fall(EnBox* this, PlayState* play) {
this->dyna.actor.shape.rot.z = 0;
this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight;
EnBox_SetupAction(this, EnBox_WaitOpen);
OnePointCutscene_EndCutscene(play, this->unk_1AC);
if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, this)) {
OnePointCutscene_EndCutscene(play, this->unk_1AC);
}
}
Audio_PlaySoundGeneral(NA_SE_EV_COFFIN_CAP_BOUND, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0,
&D_801333E8);
@ -445,74 +450,12 @@ void EnBox_WaitOpen(EnBox* this, PlayState* play) {
}
osSyncPrintf("Actor_Environment_Tbox_On() %d\n", this->dyna.actor.params & 0x1F);
Flags_SetTreasure(play, this->dyna.actor.params & 0x1F);
// treasure chest game rando
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
if (IS_RANDO && play->sceneNum == SCENE_TREASURE_BOX_SHOP && (this->dyna.actor.params & 0x60) != 0x20) {
if((this->dyna.actor.params & 0xF) < 2) {
Flags_SetCollectible(play, 0x1B);
}
if((this->dyna.actor.params & 0xF) >= 2 && (this->dyna.actor.params & 0xF) < 4) {
Flags_SetCollectible(play, 0x1C);
}
if((this->dyna.actor.params & 0xF) >= 4 && (this->dyna.actor.params & 0xF) < 6) {
Flags_SetCollectible(play, 0x1D);
}
if((this->dyna.actor.params & 0xF) >= 6 && (this->dyna.actor.params & 0xF) < 8) {
Flags_SetCollectible(play, 0x1E);
}
if((this->dyna.actor.params & 0xF) >= 8 && (this->dyna.actor.params & 0xF) < 10) {
Flags_SetCollectible(play, 0x1F);
}
}
}
} else {
player = GET_PLAYER(play);
func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos);
if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f &&
Player_IsFacingActor(&this->dyna.actor, 0x3000, play)) {
GetItemEntry sItem = Randomizer_GetItemFromActor(this->dyna.actor.id, play->sceneNum, this->dyna.actor.params, this->dyna.actor.params >> 5 & 0x7F);
GetItemEntry blueRupee = ItemTable_RetrieveEntry(MOD_NONE, GI_RUPEE_BLUE);
// RANDOTODO treasure chest game rando
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
if (IS_RANDO && play->sceneNum == SCENE_TREASURE_BOX_SHOP && (this->dyna.actor.params & 0x60) != 0x20) {
if((this->dyna.actor.params & 0xF) < 2) {
if(Flags_GetCollectible(play, 0x1B)) {
sItem = blueRupee;
}
}
if((this->dyna.actor.params & 0xF) >= 2 && (this->dyna.actor.params & 0xF) < 4) {
if(Flags_GetCollectible(play, 0x1C)) {
sItem = blueRupee;
}
}
if((this->dyna.actor.params & 0xF) >= 4 && (this->dyna.actor.params & 0xF) < 6) {
if(Flags_GetCollectible(play, 0x1D)) {
sItem = blueRupee;
}
}
if((this->dyna.actor.params & 0xF) >= 6 && (this->dyna.actor.params & 0xF) < 8) {
if(Flags_GetCollectible(play, 0x1E)) {
sItem = blueRupee;
}
}
if((this->dyna.actor.params & 0xF) >= 8 && (this->dyna.actor.params & 0xF) < 10) {
if(Flags_GetCollectible(play, 0x1F)) {
sItem = blueRupee;
}
}
}
}
// Chests need to have a negative getItemId in order to not immediately give their item
// when approaching.
if (IS_RANDO) {
sItem.getItemId = 0 - sItem.getItemId;
sItem.getItemFrom = ITEM_FROM_CHEST;
GiveItemEntryFromActorWithFixedRange(&this->dyna.actor, play, sItem);
} else {
func_8002F554(&this->dyna.actor, play, -(this->dyna.actor.params >> 5 & 0x7F));
}
}
if (Flags_GetTreasure(play, this->dyna.actor.params & 0x1F)) {
EnBox_SetupAction(this, EnBox_Open);
@ -626,12 +569,9 @@ void EnBox_Update(Actor* thisx, PlayState* play) {
Actor_SetFocus(&this->dyna.actor, 40.0f);
}
if (((!IS_RANDO && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) ||
(IS_RANDO && this->getItemEntry.getItemId == RG_ICE_TRAP)) &&
this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) {
if (!CVarGetInteger("gAddTraps.enabled", 0)) {
EnBox_SpawnIceSmoke(this, play);
}
if ((this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open &&
this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) {
EnBox_SpawnIceSmoke(this, play);
}
}

View File

@ -4,6 +4,7 @@
#include <libultraship/libultra.h>
#include "global.h"
#define ENBOX_PARAMS(type, itemId, treasureFlag) ((type) << 12 | (itemId) << 5 | (treasureFlag))
#define ENBOX_TREASURE_FLAG_UNK_MIN 20
#define ENBOX_TREASURE_FLAG_UNK_MAX 32
@ -45,7 +46,7 @@ typedef struct EnBox {
/* 0x01F9 */ u8 type;
/* 0x01FA */ u8 iceSmokeTimer;
/* 0x01FB */ u8 unk_1FB;
/* */ GetItemEntry getItemEntry;
/* */ GetItemEntry getItemEntry; // This is only to determine the Chest Style, randomzier item gives are handled elsewhere
/* */ Gfx* boxLidDL;
/* */ Gfx* boxBodyDL;
} EnBox; // size = 0x01FC

View File

@ -6,6 +6,7 @@
#include "z_en_cow.h"
#include "objects/object_cow/object_cow.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@ -18,7 +19,6 @@ void func_809E0070(Actor* thisx, PlayState* play);
void func_809DF494(EnCow* this, PlayState* play);
void func_809DF6BC(EnCow* this, PlayState* play);
void EnCow_MoveForRandomizer(EnCow* this, PlayState* play);
void func_809DF778(EnCow* this, PlayState* play);
void func_809DF7D8(EnCow* this, PlayState* play);
void func_809DF870(EnCow* this, PlayState* play);
@ -107,10 +107,6 @@ void EnCow_Init(Actor* thisx, PlayState* play) {
EnCow* this = (EnCow*)thisx;
s32 pad;
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_COWS)) {
EnCow_MoveForRandomizer(thisx, play);
}
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f);
switch (this->actor.params) {
case 0:
@ -122,18 +118,15 @@ void EnCow_Init(Actor* thisx, PlayState* play) {
Collider_SetCylinder(play, &this->colliders[1], &this->actor, &sCylinderInit);
func_809DEE9C(this);
this->actionFunc = func_809DF96C;
if (play->sceneNum == SCENE_LINKS_HOUSE) {
if (!LINK_IS_ADULT && !CVarGetInteger("gCowOfTime", 0)) {
Actor_Kill(&this->actor);
return;
}
if (!Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE)) {
Actor_Kill(&this->actor);
return;
}
if (GameInteractor_Should(GI_VB_DESPAWN_HORSE_RACE_COW, (
play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE))
), this)) {
Actor_Kill(&this->actor);
return;
}
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_COW, this->actor.world.pos.x,
this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 1);
this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 1);
this->unk_278 = Rand_ZeroFloat(1000.0f) + 40.0f;
this->unk_27A = 0;
this->actor.targetMode = 6;
@ -216,36 +209,12 @@ void func_809DF730(EnCow* this, PlayState* play) {
}
}
void EnCow_MoveForRandomizer(EnCow* this, PlayState* play) {
// Only move the cow body (the tail will be moved with the body)
if (this->actor.params != 0) {
return;
}
// Move left cow in lon lon tower
if (play->sceneNum == SCENE_LON_LON_BUILDINGS && this->actor.world.pos.x == -108 && this->actor.world.pos.z == -65) {
this->actor.world.pos.x = -229.0f;
this->actor.world.pos.z = 157.0f;
this->actor.shape.rot.y = 15783.0f;
// Move right cow in lon lon stable
} else if (play->sceneNum == SCENE_STABLE && this->actor.world.pos.x == -3 && this->actor.world.pos.z == -254) {
this->actor.world.pos.x += 119.0f;
}
}
void EnCow_SetCowMilked(EnCow* this, PlayState* play) {
CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z);
Player* player = GET_PLAYER(play);
player->pendingFlag.flagID = cowIdentity.randomizerInf;
player->pendingFlag.flagType = FLAG_RANDOMIZER_INF;
}
void func_809DF778(EnCow* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
this->actor.parent = NULL;
this->actionFunc = func_809DF730;
} else {
func_8002F434(&this->actor, play, GI_MILK, 10000.0f, 100.0f);
Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 100.0f);
}
}
@ -254,7 +223,7 @@ void func_809DF7D8(EnCow* this, PlayState* play) {
this->actor.flags &= ~ACTOR_FLAG_WILL_TALK;
Message_CloseTextbox(play);
this->actionFunc = func_809DF778;
func_8002F434(&this->actor, play, GI_MILK, 10000.0f, 100.0f);
Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 100.0f);
}
}
@ -281,23 +250,6 @@ void func_809DF8FC(EnCow* this, PlayState* play) {
func_809DF494(this, play);
}
bool EnCow_HasBeenMilked(EnCow* this, PlayState* play) {
CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z);
return Flags_GetRandomizerInf(cowIdentity.randomizerInf);
}
void EnCow_GivePlayerRandomizedItem(EnCow* this, PlayState* play) {
if (!EnCow_HasBeenMilked(this, play)) {
CowIdentity cowIdentity = Randomizer_IdentifyCow(play->sceneNum, this->actor.world.pos.x, this->actor.world.pos.z);
GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(cowIdentity.randomizerCheck, GI_MILK);
GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 100.0f);
} else {
// once we've gotten the rando reward from the cow,
// return them to the their default action function
this->actionFunc = func_809DF96C;
}
}
void func_809DF96C(EnCow* this, PlayState* play) {
if ((play->msgCtx.ocarinaMode == OCARINA_MODE_00) || (play->msgCtx.ocarinaMode == OCARINA_MODE_04)) {
if (DREG(53) != 0) {
@ -308,23 +260,14 @@ void func_809DF96C(EnCow* this, PlayState* play) {
if ((this->actor.xzDistToPlayer < 150.0f) &&
(ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x61A8)) {
DREG(53) = 0;
// when randomized with cowsanity, if we haven't gotten the
// reward from this cow yet, give that, otherwise use the
// vanilla cow behavior
if (IS_RANDO &&
Randomizer_GetSettingValue(RSK_SHUFFLE_COWS) &&
!EnCow_HasBeenMilked(this, play)) {
EnCow_SetCowMilked(this, play);
// setting the ocarina mode here prevents intermittent issues
// with the item get not triggering until walking away
play->msgCtx.ocarinaMode = OCARINA_MODE_00;
this->actionFunc = EnCow_GivePlayerRandomizedItem;
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_COW, true, this)) {
this->actionFunc = func_809DF8FC;
this->actor.flags |= ACTOR_FLAG_WILL_TALK;
func_8002F2CC(&this->actor, play, 170.0f);
this->actor.textId = 0x2006;
} else {
return;
}
this->actionFunc = func_809DF8FC;
this->actor.flags |= ACTOR_FLAG_WILL_TALK;
func_8002F2CC(&this->actor, play, 170.0f);
this->actor.textId = 0x2006;
} else {
this->unk_276 |= 4;
}

View File

@ -21,4 +21,6 @@ typedef struct EnCow {
/* 0x027C */ EnCowActionFunc actionFunc;
} EnCow; // size = 0x0280
void func_809DEE9C(EnCow* enCow);
#endif

View File

@ -470,7 +470,7 @@ void EnDaiku_InitSubCamera(EnDaiku* this, PlayState* play) {
Play_CameraSetAtEye(play, this->subCamId, &this->subCamAt, &this->subCamEye);
Play_CameraSetFov(play, this->subCamId, play->mainCamera.fov);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
}
void EnDaiku_UpdateSubCamera(EnDaiku* this, PlayState* play) {
@ -507,7 +507,7 @@ void EnDaiku_EscapeSuccess(EnDaiku* this, PlayState* play) {
Actor_Kill(&this->actor);
}
} else {
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
}
}

View File

@ -8,6 +8,7 @@
#include "overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.h"
#include "objects/object_zo/object_zo.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@ -138,7 +139,7 @@ s32 EnDivingGame_HasMinigameFinished(EnDivingGame* this, PlayState* play) {
Message_StartTextbox(play, this->actor.textId, NULL);
this->unk_292 = TEXT_STATE_EVENT;
this->allRupeesThrown = this->state = this->phase = this->unk_2A2 = this->grabbedRupeesCounter = 0;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = func_809EE048;
return true;
} else {
@ -163,7 +164,7 @@ s32 EnDivingGame_HasMinigameFinished(EnDivingGame* this, PlayState* play) {
this->unk_292 = TEXT_STATE_EVENT;
func_800F5B58();
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
if (!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_SILVER_SCALE)) {
this->actionFunc = func_809EE96C;
} else {
@ -191,7 +192,7 @@ void EnDivingGame_Talk(EnDivingGame* this, PlayState* play) {
if (this->unk_292 != TEXT_STATE_DONE) {
switch (this->state) {
case ENDIVINGGAME_STATE_NOTPLAYING:
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = EnDivingGame_HandlePlayChoice;
break;
case ENDIVINGGAME_STATE_AWARDPRIZE:
@ -258,7 +259,7 @@ void EnDivingGame_HandlePlayChoice(EnDivingGame* this, PlayState* play) {
this->actionFunc = func_809EE048;
} else {
play->msgCtx.msgMode = MSGMODE_PAUSED;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = func_809EE0FC;
}
}
@ -270,11 +271,11 @@ void func_809EE048(EnDivingGame* this, PlayState* play) {
if (this->unk_292 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play)) {
if (this->phase == ENDIVINGGAME_PHASE_ENDED) {
Message_CloseTextbox(play);
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
this->actionFunc = func_809EDCB0;
} else {
play->msgCtx.msgMode = MSGMODE_PAUSED;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = func_809EE0FC;
}
}
@ -419,7 +420,7 @@ void func_809EE800(EnDivingGame* this, PlayState* play) {
func_80088B34(BREG(2) + 50);
}
func_800F5ACC(NA_BGM_TIMED_MINI_GAME);
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
this->actor.textId = 0x405B;
this->unk_292 = TEXT_STATE_EVENT;
this->state = ENDIVINGGAME_STATE_PLAYING;
@ -442,7 +443,7 @@ void func_809EE96C(EnDivingGame* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
if ((this->unk_292 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play))) {
Message_CloseTextbox(play);
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
this->actor.textId = 0x4056;
this->unk_292 = TEXT_STATE_EVENT;
this->state = ENDIVINGGAME_STATE_AWARDPRIZE;
@ -455,11 +456,8 @@ void func_809EEA00(EnDivingGame* this, PlayState* play) {
if ((this->unk_292 == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play))) {
Message_CloseTextbox(play);
this->actor.parent = NULL;
if (!IS_RANDO) {
func_8002F434(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f);
} else {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER);
GiveItemEntryFromActor(&this->actor, play, getItemEntry, 90.0f, 10.0f);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, true, &this->actor)) {
Actor_OfferGetItem(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f);
}
this->actionFunc = func_809EEA90;
}
@ -467,14 +465,11 @@ void func_809EEA00(EnDivingGame* this, PlayState* play) {
void func_809EEA90(EnDivingGame* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
if (Actor_HasParent(&this->actor, play)) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, true, &this->actor)) {
this->actionFunc = func_809EEAF8;
} else {
if (!IS_RANDO) {
func_8002F434(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f);
} else {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER);
GiveItemEntryFromActor(&this->actor, play, getItemEntry, 90.0f, 10.0f);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, true, &this->actor)) {
Actor_OfferGetItem(&this->actor, play, GI_SCALE_SILVER, 90.0f, 10.0f);
}
}
}
@ -482,7 +477,8 @@ void func_809EEA90(EnDivingGame* this, PlayState* play) {
// Award the scale?
void func_809EEAF8(EnDivingGame* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
if (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE && Message_ShouldAdvance(play)) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE && Message_ShouldAdvance(play)) ||
!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME, true, &this->actor)) {
// "Successful completion"
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST);
this->allRupeesThrown = this->state = this->phase = this->unk_2A2 = this->grabbedRupeesCounter = 0;

View File

@ -16,7 +16,6 @@ void EnDns_Destroy(Actor* thisx, PlayState* play);
void EnDns_Update(Actor* thisx, PlayState* play);
void EnDns_Draw(Actor* thisx, PlayState* play);
u32 EnDns_RandomizerPurchaseableCheck(EnDns* this);
u32 func_809EF5A4(EnDns* this);
u32 func_809EF658(EnDns* this);
u32 func_809EF70C(EnDns* this);
@ -26,7 +25,6 @@ u32 func_809EF854(EnDns* this);
u32 func_809EF8F4(EnDns* this);
u32 func_809EF9A4(EnDns* this);
void EnDns_RandomizerPurchase(EnDns* this);
void func_809EF9F8(EnDns* this);
void func_809EFA28(EnDns* this);
void func_809EFA58(EnDns* this);
@ -168,32 +166,6 @@ void EnDns_Init(Actor* thisx, PlayState* play) {
this->actor.gravity = -1.0f;
this->actor.textId = D_809F040C[this->actor.params];
this->dnsItemEntry = sItemEntries[this->actor.params];
if (IS_RANDO) {
// Ugly, but the best way we can identify which grotto we are in, same method 3DRando uses, but we'll need to account for entrance rando
s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1);
this->scrubIdentity = Randomizer_IdentifyScrub(play->sceneNum, this->actor.params, respawnData);
if ((Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_AFFORDABLE ||
Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_RANDOM) &&
this->scrubIdentity.itemPrice != -1) {
this->dnsItemEntry->itemPrice = this->scrubIdentity.itemPrice;
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_EXPENSIVE) {
// temporary workaround: always use 40 rupees as price instead of 70
if (this->actor.params == 0x0006) {
this->dnsItemEntry->itemPrice = 40;
}
}
if (this->scrubIdentity.isShuffled) {
this->dnsItemEntry->getItemId = this->scrubIdentity.getItemId;
this->dnsItemEntry->purchaseableCheck = EnDns_RandomizerPurchaseableCheck;
this->dnsItemEntry->setRupeesAndFlags = EnDns_RandomizerPurchase;
this->dnsItemEntry->itemAmount = 1;
this->actor.textId = 0x9000 + (this->scrubIdentity.randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT);
}
}
this->actionFunc = EnDns_SetupWait;
}
@ -216,13 +188,6 @@ void EnDns_ChangeAnim(EnDns* this, u8 index) {
/* Item give checking functions */
u32 EnDns_RandomizerPurchaseableCheck(EnDns* this) {
if (gSaveContext.rupees < this->dnsItemEntry->itemPrice || Flags_GetRandomizerInf(this->scrubIdentity.randomizerInf)) {
return 0;
}
return 4;
}
u32 func_809EF5A4(EnDns* this) {
if ((CUR_CAPACITY(UPG_NUTS) != 0) && (AMMO(ITEM_NUT) >= CUR_CAPACITY(UPG_NUTS))) {
return 1;
@ -319,10 +284,6 @@ u32 func_809EF9A4(EnDns* this) {
}
/* Paying and flagging functions */
void EnDns_RandomizerPurchase(EnDns* this) {
Rupees_ChangeBy(-this->dnsItemEntry->itemPrice);
Flags_SetRandomizerInf(this->scrubIdentity.randomizerInf);
}
void func_809EF9F8(EnDns* this) {
Rupees_ChangeBy(-this->dnsItemEntry->itemPrice);
@ -412,44 +373,39 @@ void EnDns_Talk(EnDns* this, PlayState* play) {
void func_809EFDD0(EnDns* this, PlayState* play) {
u16 pendingGetItemId;
if (!IS_RANDO || !this->scrubIdentity.isShuffled) {
if (this->actor.params == 0x9) {
if (CUR_UPG_VALUE(UPG_STICKS) < 2) {
pendingGetItemId = GI_STICK_UPGRADE_20;
} else {
pendingGetItemId = GI_STICK_UPGRADE_30;
}
} else if (this->actor.params == 0xA) {
if (CUR_UPG_VALUE(UPG_NUTS) < 2) {
pendingGetItemId = GI_NUT_UPGRADE_30;
} else {
pendingGetItemId = GI_NUT_UPGRADE_40;
}
if (this->actor.params == 0x9) {
if (CUR_UPG_VALUE(UPG_STICKS) < 2) {
pendingGetItemId = GI_STICK_UPGRADE_20;
} else {
pendingGetItemId = this->dnsItemEntry->getItemId;
pendingGetItemId = GI_STICK_UPGRADE_30;
}
} else if (this->actor.params == 0xA) {
if (CUR_UPG_VALUE(UPG_NUTS) < 2) {
pendingGetItemId = GI_NUT_UPGRADE_30;
} else {
pendingGetItemId = GI_NUT_UPGRADE_40;
}
GetItemEntry itemEntry = ItemTable_Retrieve(pendingGetItemId);
gSaveContext.pendingSale = itemEntry.itemId;
gSaveContext.pendingSaleMod = itemEntry.modIndex;
func_8002F434(&this->actor, play, pendingGetItemId, 130.0f, 100.0f);
} else {
GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(this->scrubIdentity.randomizerCheck, this->scrubIdentity.getItemId);
gSaveContext.pendingSale = itemEntry.itemId;
gSaveContext.pendingSaleMod = itemEntry.modIndex;
GiveItemEntryFromActor(&this->actor, play, itemEntry, 130.0f, 100.0f);
pendingGetItemId = this->dnsItemEntry->getItemId;
}
GetItemEntry itemEntry = ItemTable_Retrieve(pendingGetItemId);
gSaveContext.pendingSale = itemEntry.itemId;
gSaveContext.pendingSaleMod = itemEntry.modIndex;
Actor_OfferGetItem(&this->actor, play, pendingGetItemId, 130.0f, 100.0f);
}
void func_809EFEE8(EnDns* this, PlayState* play) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) {
Message_CloseTextbox(play);
func_809EFDD0(this, play);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB, true, this)) {
func_809EFDD0(this, play);
}
this->actionFunc = func_809EFF50;
}
}
void func_809EFF50(EnDns* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB, true, this)) {
this->actor.parent = NULL;
this->actionFunc = func_809EFF98;
} else {
@ -533,9 +489,6 @@ void EnDns_Update(Actor* thisx, PlayState* play) {
this->dustTimer++;
this->actor.textId = D_809F040C[this->actor.params];
if (IS_RANDO && this->scrubIdentity.isShuffled) {
this->actor.textId = 0x9000 + (this->scrubIdentity.randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT);
}
Actor_SetFocus(&this->actor, 60.0f);
Actor_SetScale(&this->actor, 0.01f);
SkelAnime_Update(&this->skelAnime);

View File

@ -32,7 +32,10 @@ typedef struct EnDns {
/* 0x02BD */ u8 dropCollectible;
/* 0x02C0 */ DnsItemEntry* dnsItemEntry;
/* 0x02C4 */ f32 yInitPos;
/* */ ScrubIdentity scrubIdentity;
// #region SOH [Randomizer]
/* */ DnsItemEntry sohDnsItemEntry;
/* */ ScrubIdentity sohScrubIdentity;
// #endregion
} EnDns; // size = 0x02C8
#endif

View File

@ -135,29 +135,6 @@ void EnDntDemo_Judge(EnDntDemo* this, PlayState* play) {
this->judgeTimer = 0;
}
} else {
if (IS_RANDO) {
Player* player = GET_PLAYER(play);
switch (Player_GetMask(play)) {
case PLAYER_MASK_SKULL:
if (!Flags_GetTreasure(play, 0x1F) && !Player_InBlockingCsMode(play, player)) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DEKU_THEATER_SKULL_MASK, GI_STICK_UPGRADE_30);
GiveItemEntryWithoutActor(play, getItemEntry);
player->pendingFlag.flagID = 0x1F;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
break;
case PLAYER_MASK_TRUTH:
if (!Flags_GetTreasure(play, 0x1E) && !Player_InBlockingCsMode(play, player)) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DEKU_THEATER_MASK_OF_TRUTH, GI_NUT_UPGRADE_40);
GiveItemEntryWithoutActor(play, getItemEntry);
player->pendingFlag.flagID = 0x1E;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
break;
}
return;
}
if ((Player_GetMask(play) != 0) && (this->subCamera == SUBCAM_FREE)) {
this->subCamera = OnePointCutscene_Init(play, 2220, -99, &this->scrubs[3]->actor, MAIN_CAM);
}

View File

@ -64,4 +64,6 @@ typedef enum {
/* 5 */ DNT_ACTION_PRIZE
} EnDntAction;
void EnDntDemo_Judge(EnDntDemo* enDntDemo, PlayState* play);
#endif

View File

@ -126,7 +126,7 @@ void EnDntJiji_Wait(EnDntJiji* this, PlayState* play) {
!(player->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
OnePointCutscene_Init(play, 2230, -99, &this->actor, MAIN_CAM);
this->timer = 0;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = EnDntJiji_SetupUnburrow;
}
}
@ -260,9 +260,9 @@ void EnDntJiji_Talk(EnDntJiji* this, PlayState* play) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) {
func_8005B1A4(GET_ACTIVE_CAM(play));
Message_CloseTextbox(play);
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
this->actor.parent = NULL;
func_8002F434(&this->actor, play, this->getItemId, 400.0f, 200.0f);
Actor_OfferGetItem(&this->actor, play, this->getItemId, 400.0f, 200.0f);
this->actionFunc = EnDntJiji_SetupGivePrize;
}
}
@ -272,7 +272,7 @@ void EnDntJiji_SetupGivePrize(EnDntJiji* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
this->actionFunc = EnDntJiji_GivePrize;
} else {
func_8002F434(&this->actor, play, this->getItemId, 400.0f, 200.0f);
Actor_OfferGetItem(&this->actor, play, this->getItemId, 400.0f, 200.0f);
}
}

View File

@ -12,6 +12,7 @@
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#include "objects/object_hintnuts/object_hintnuts.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
@ -252,11 +253,11 @@ void EnDntNomal_TargetWait(EnDntNomal* this, PlayState* play) {
if (!LINK_IS_ADULT && !Flags_GetItemGetInf(ITEMGETINF_1D)) {
this->hitCounter++;
if (this->hitCounter >= 3) {
if(IS_RANDO) {
if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, &this->actor)) {
this->actionFunc = EnDntNomal_TargetGivePrize;
} else {
OnePointCutscene_Init(play, 4140, -99, &this->actor, MAIN_CAM);
func_8002DF54(play, &this->actor, 1);
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
this->timer4 = 50;
this->actionFunc = EnDntNomal_SetupTargetUnburrow;
}
@ -346,7 +347,7 @@ void EnDntNomal_TargetTalk(EnDntNomal* this, PlayState* play) {
Message_CloseTextbox(play);
func_8005B1A4(GET_ACTIVE_CAM(play));
GET_ACTIVE_CAM(play)->csId = 0;
func_8002DF54(play, NULL, 8);
Player_SetCsActionWithHaltedActors(play, NULL, 8);
this->actionFunc = EnDntNomal_SetupTargetGivePrize;
}
}
@ -368,7 +369,7 @@ void EnDntNomal_TargetGivePrize(EnDntNomal* this, PlayState* play) {
if (Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_EX_ITEM, itemX, itemY, itemZ, 0,
0, 0, EXITEM_BULLET_BAG) == NULL) {
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
Actor_Kill(&this->actor);
}
this->spawnedItem = true;

View File

@ -6,7 +6,7 @@
#include "z_en_ds.h"
#include "objects/object_ds/object_ds.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@ -90,19 +90,12 @@ void EnDs_DisplayOddPotionText(EnDs* this, PlayState* play) {
}
void EnDs_GiveOddPotion(EnDs* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_TRADE_ODD_MUSHROOM, true, this)) {
this->actor.parent = NULL;
this->actionFunc = EnDs_DisplayOddPotionText;
gSaveContext.timer2State = 0;
} else {
u32 itemId = GI_ODD_POTION;
if (IS_RANDO) {
GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION);
GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f);
Randomizer_ConsumeAdultTradeItem(play, ITEM_ODD_MUSHROOM);
return;
}
func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f);
Actor_OfferGetItem(&this->actor, play, GI_ODD_POTION, 10000.0f, 50.0f);
}
}
@ -111,13 +104,9 @@ void EnDs_TalkAfterBrewOddPotion(EnDs* this, PlayState* play) {
Message_CloseTextbox(play);
this->actionFunc = EnDs_GiveOddPotion;
u32 itemId = GI_ODD_POTION;
if (IS_RANDO) {
GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION);
GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f);
Randomizer_ConsumeAdultTradeItem(play, ITEM_ODD_MUSHROOM);
return;
if (GameInteractor_Should(GI_VB_TRADE_ODD_MUSHROOM, true, this)) {
Actor_OfferGetItem(&this->actor, play, itemId, 10000.0f, 50.0f);
}
func_8002F434(&this->actor, play, itemId, 10000.0f, 50.0f);
}
}
@ -138,7 +127,7 @@ void EnDs_BrewOddPotion2(EnDs* this, PlayState* play) {
this->brewTimer -= 1;
} else {
this->actionFunc = EnDs_BrewOddPotion3;
this->brewTimer = IS_RANDO ? 0 : 60;
this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 60 : 0;
Flags_UnsetSwitch(play, 0x3F);
}
}
@ -148,7 +137,7 @@ void EnDs_BrewOddPotion1(EnDs* this, PlayState* play) {
this->brewTimer -= 1;
} else {
this->actionFunc = EnDs_BrewOddPotion2;
this->brewTimer = IS_RANDO ? 0 : 20;
this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 20 : 0;
}
Math_StepToF(&this->unk_1E4, 1.0f, 0.01f);
@ -162,7 +151,7 @@ void EnDs_OfferOddPotion(EnDs* this, PlayState* play) {
switch (play->msgCtx.choiceIndex) {
case 0: // yes
this->actionFunc = EnDs_BrewOddPotion1;
this->brewTimer = IS_RANDO ? 0 : 60;
this->brewTimer = GameInteractor_Should(GI_VB_PLAY_EYEDROP_CREATION_ANIM, true, this) ? 60 : 0;
Flags_SetSwitch(play, 0x3F);
play->msgCtx.msgMode = MSGMODE_PAUSED;
player->exchangeItemId = EXCH_ITEM_NONE;
@ -174,22 +163,10 @@ void EnDs_OfferOddPotion(EnDs* this, PlayState* play) {
}
}
u8 EnDs_RandoCanGetGrannyItem() {
return IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) &&
// Traded odd mushroom when adult trade is on
((Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) && Flags_GetItemGetInf(ITEMGETINF_30)) ||
// Found claim check when adult trade is off
(!Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) &&
INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK));
}
s32 EnDs_CheckRupeesAndBottle() {
if (gSaveContext.rupees < 100) {
return 0;
} else if (EnDs_RandoCanGetGrannyItem()) { // Allow buying the rando item regardless of having a bottle
return 2;
} else if (Inventory_HasEmptyBottle() == 0) {
} else if (GameInteractor_Should(GI_VB_NEED_BOTTLE_FOR_GRANNYS_ITEM, Inventory_HasEmptyBottle() == 0, NULL)) {
return 1;
} else {
return 2;
@ -197,20 +174,11 @@ s32 EnDs_CheckRupeesAndBottle() {
}
void EnDs_GiveBluePotion(EnDs* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (EnDs_RandoCanGetGrannyItem()) {
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP);
}
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) {
this->actor.parent = NULL;
this->actionFunc = EnDs_Talk;
} else {
if (EnDs_RandoCanGetGrannyItem()) {
GetItemEntry entry = Randomizer_GetItemFromKnownCheck(RC_KAK_GRANNYS_SHOP, GI_POTION_BLUE);
GiveItemEntryFromActor(&this->actor, play, entry, 10000.0f, 50.0f);
} else {
func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
}
Actor_OfferGetItem(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
}
}
@ -229,18 +197,14 @@ void EnDs_OfferBluePotion(EnDs* this, PlayState* play) {
case 2: // have 100 rupees and empty bottle
Rupees_ChangeBy(-100);
this->actor.flags &= ~ACTOR_FLAG_WILL_TALK;
GetItemEntry itemEntry;
if (EnDs_RandoCanGetGrannyItem()) {
itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_GRANNYS_SHOP, GI_POTION_BLUE);
GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f);
} else {
itemEntry = ItemTable_Retrieve(GI_POTION_BLUE);
func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) {
GetItemEntry itemEntry = ItemTable_Retrieve(GI_POTION_BLUE);
Actor_OfferGetItem(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
gSaveContext.pendingSale = itemEntry.itemId;
gSaveContext.pendingSaleMod = itemEntry.modIndex;
}
gSaveContext.pendingSale = itemEntry.itemId;
gSaveContext.pendingSaleMod = itemEntry.modIndex;
this->actionFunc = EnDs_GiveBluePotion;
return;
}
@ -261,10 +225,7 @@ void EnDs_Wait(EnDs* this, PlayState* play) {
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
player->actor.textId = 0x504A;
this->actionFunc = EnDs_OfferOddPotion;
} else if (
// Always offer blue potion when adult trade is off
(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF) ||
Flags_GetItemGetInf(ITEMGETINF_30)) { // Traded odd mushroom
} else if (GameInteractor_Should(GI_VB_OFFER_BLUE_POTION, Flags_GetItemGetInf(ITEMGETINF_30), this)) { // Traded odd mushroom
player->actor.textId = 0x500C;
this->actionFunc = EnDs_OfferBluePotion;
} else {

View File

@ -1,6 +1,7 @@
#include "z_en_du.h"
#include "objects/object_du/object_du.h"
#include "scenes/overworld/spot18/spot18_scene.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_FREEZE_OCARINA)
@ -361,7 +362,7 @@ void func_809FE3C0(EnDu* this, PlayState* play) {
return;
}
if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) {
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
this->interactInfo.talkState = NPC_TALK_STATE_IDLE;
}
if (this->actor.xzDistToPlayer < 116.0f + this->collider.dim.radius) {
@ -376,7 +377,7 @@ void func_809FE4A4(EnDu* this, PlayState* play) {
play->msgCtx.ocarinaMode = OCARINA_MODE_00;
EnDu_SetupAction(this, func_809FE3C0);
} else if (play->msgCtx.ocarinaMode >= OCARINA_MODE_06) {
if (!IS_RANDO) {
if (GameInteractor_Should(GI_VB_PLAY_DARUNIAS_JOY_CS, true, NULL)) {
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gGoronCityDaruniaWrongCs);
gSaveContext.cutsceneTrigger = 1;
}
@ -385,7 +386,7 @@ void func_809FE4A4(EnDu* this, PlayState* play) {
play->msgCtx.ocarinaMode = OCARINA_MODE_04;
} else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) {
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
if (!IS_RANDO) {
if (GameInteractor_Should(GI_VB_PLAY_DARUNIAS_JOY_CS, true, NULL)) {
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gGoronCityDaruniaCorrectCs);
gSaveContext.cutsceneTrigger = 1;
}
@ -474,11 +475,8 @@ void func_809FE890(EnDu* this, PlayState* play) {
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
CsCmdActorAction* csAction;
if (play->csCtx.state == CS_STATE_IDLE || IS_RANDO) {
if (IS_RANDO) {
play->csCtx.state = CS_STATE_IDLE;
}
func_8002DF54(play, &this->actor, 1);
if (play->csCtx.state == CS_STATE_IDLE) {
Player_SetCsActionWithHaltedActors(play, &this->actor, 1);
EnDu_SetupAction(this, func_809FEB08);
return;
}
@ -551,16 +549,13 @@ void func_809FEB08(EnDu* this, PlayState* play) {
this->unk_1EE = 0;
if (this->unk_1E8 == 1) {
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENDU_ANIM_1);
EnDu_SetupAction(this, func_809FE3C0);
return;
}
if ((!IS_RANDO && CUR_UPG_VALUE(UPG_STRENGTH) <= 0) ||
(IS_RANDO && !Flags_GetTreasure(play, 0x1E))) {
if (IS_RANDO) {
Flags_SetTreasure(play, 0x1E);
}
if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD, CUR_UPG_VALUE(UPG_STRENGTH) <= 0, NULL)) {
Flags_SetRandomizerInf(RAND_INF_DARUNIAS_JOY);
this->actor.textId = 0x301C;
EnDu_SetupAction(this, func_809FEC14);
} else {
@ -574,24 +569,20 @@ void func_809FEB08(EnDu* this, PlayState* play) {
void func_809FEC14(EnDu* this, PlayState* play) {
if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) {
func_8002DF54(play, &this->actor, 7);
Player_SetCsActionWithHaltedActors(play, &this->actor, 7);
EnDu_SetupAction(this, func_809FEC70);
func_809FEC70(this, play);
}
}
void func_809FEC70(EnDu* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_STRENGTH_1, true, NULL)) {
this->actor.parent = NULL;
EnDu_SetupAction(this, func_809FECE4);
} else {
f32 xzRange = this->actor.xzDistToPlayer + 1.0f;
if (!IS_RANDO) {
func_8002F434(&this->actor, play, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f);
} else {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET);
GiveItemEntryFromActor(&this->actor, play, getItemEntry, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f);
}
Actor_OfferGetItem(&this->actor, play, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f);
}
}

View File

@ -677,7 +677,7 @@ void func_80A0329C(EnElf* this, PlayState* play) {
if (!(this->fairyFlags & FAIRY_FLAG_BIG)) {
// GI_MAX in this case allows the player to catch the actor in a bottle
func_8002F434(&this->actor, play, GI_MAX, 80.0f, 60.0f);
Actor_OfferGetItem(&this->actor, play, GI_MAX, 80.0f, 60.0f);
}
}
}

View File

@ -8,6 +8,7 @@
#include "overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
@ -228,25 +229,19 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) {
this->scale = 0.5f;
this->unkFloat = 0.5f;
this->actor.velocity.y = 10.0f;
if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
switch (this->type) {
case EXITEM_GREEN_RUPEE_CHEST:
this->giDrawId = GID_RUPEE_GREEN;
break;
case EXITEM_BLUE_RUPEE_CHEST:
this->giDrawId = GID_RUPEE_BLUE;
break;
case EXITEM_RED_RUPEE_CHEST:
this->giDrawId = GID_RUPEE_RED;
break;
case EXITEM_14:
this->giDrawId = GID_RUPEE_PURPLE;
break;
}
} else {
if (play->sceneNum == SCENE_TREASURE_BOX_SHOP) {
this->giDrawId = GetChestGameRandoGiDrawId(play->roomCtx.curRoom.num, GID_RUPEE_GREEN, play);
}
switch (this->type) {
case EXITEM_GREEN_RUPEE_CHEST:
this->giDrawId = GID_RUPEE_GREEN;
break;
case EXITEM_BLUE_RUPEE_CHEST:
this->giDrawId = GID_RUPEE_BLUE;
break;
case EXITEM_RED_RUPEE_CHEST:
this->giDrawId = GID_RUPEE_RED;
break;
case EXITEM_14:
this->giDrawId = GID_RUPEE_PURPLE;
break;
}
this->actionFunc = EnExItem_ExitChest;
break;
@ -376,7 +371,7 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, PlayState* play) {
Math_SmoothStepToS(&this->actor.shape.rot.y, -0x4000, 5, 0x1000, 0);
}
if (!IS_RANDO && this->timer != 0) {
if (GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, &this->actor) && this->timer != 0) {
if (this->prizeRotateTimer != 0) {
tmpf1 = play->view.lookAt.x - play->view.eye.x;
tmpf2 = play->view.lookAt.y - 10.0f - play->view.eye.y;
@ -396,50 +391,41 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, PlayState* play) {
this->actor.world.pos.z += (tmpf3 / tmpf4) * 5.0f;
}
} else {
GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE;
s32 getItemId;
this->actor.draw = NULL;
func_8002DF54(play, NULL, 7);
Player_SetCsActionWithHaltedActors(play, NULL, 7);
this->actor.parent = NULL;
if (IS_RANDO) {
if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, &this->actor)) {
GET_PLAYER(play)->stateFlags1 &= ~(PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD);
getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50);
getItemId = getItemEntry.getItemId;
} else {
if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) {
getItemId = GI_BULLET_BAG_40;
} else {
getItemId = GI_BULLET_BAG_50;
}
}
if (!IS_RANDO || getItemEntry.getItemId == GI_NONE) {
func_8002F434(&this->actor, play, getItemId, 2000.0f, 1000.0f);
if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) {
getItemId = GI_BULLET_BAG_40;
} else {
GiveItemEntryFromActor(&this->actor, play, getItemEntry, 2000.0f, 1000.0f);
getItemId = GI_BULLET_BAG_50;
}
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, true, &this->actor)) {
Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f);
}
this->actionFunc = EnExItem_TargetPrizeGive;
}
}
void EnExItem_TargetPrizeGive(EnExItem* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, true, &this->actor)) {
this->actionFunc = EnExItem_TargetPrizeFinish;
} else {
if (!IS_RANDO) {
s32 getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40;
func_8002F434(&this->actor, play, getItemId, 2000.0f, 1000.0f);
} else {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50);
GiveItemEntryFromActor(&this->actor, play, getItemEntry, 2000.0f, 1000.0f);
}
s32 getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40;
Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f);
}
}
void EnExItem_TargetPrizeFinish(EnExItem* this, PlayState* play) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) {
if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, true, &this->actor) || (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) {
// "Successful completion"
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST);
Flags_SetItemGetInf(ITEMGETINF_1D);

View File

@ -6,7 +6,7 @@
struct EnExItem;
typedef void (*EnExItemActionFunc)(struct EnExItem* this, PlayState* play);
typedef void (*EnExItemActionFunc)(struct EnExItem* enExItem, PlayState* play);
typedef void (*EnExItemLightFunc)(Actor*, PlayState*, s32);
typedef struct EnExItem {

View File

@ -716,7 +716,7 @@ void EnFish_OrdinaryUpdate(EnFish* this, PlayState* play) {
EnFish_BeginRespawn(this);
} else if (EnFish_InBottleRange(this, play)) {
// GI_MAX in this case allows the player to catch the actor in a bottle
func_8002F434(&this->actor, play, GI_MAX, 80.0f, 20.0f);
Actor_OfferGetItem(&this->actor, play, GI_MAX, 80.0f, 20.0f);
}
}
}

View File

@ -45,7 +45,6 @@ void EnFr_OcarinaMistake(EnFr* this, PlayState* play);
void EnFr_SetupReward(EnFr* this, PlayState* play, u8 unkCondition);
void EnFr_PrintTextBox(EnFr* this, PlayState* play);
void EnFr_TalkBeforeReward(EnFr* this, PlayState* play);
RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex);
void EnFr_SetReward(EnFr* this, PlayState* play);
// Deactivate
@ -618,7 +617,6 @@ void EnFr_Idle(EnFr* this, PlayState* play) {
player->actor.world.pos.z = this->actor.world.pos.z; // z = -1220.0f
player->yaw = player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y;
this->reward = GI_NONE;
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
this->actionFunc = EnFr_Activate;
} else if (EnFr_IsAboveAndWithin30DistXZ(player, this)) {
player->unk_6A8 = &this->actor;
@ -854,7 +852,6 @@ s32 EnFr_IsFrogSongComplete(EnFr* this, PlayState* play) {
void EnFr_OcarinaMistake(EnFr* this, PlayState* play) {
Message_CloseTextbox(play);
this->reward = GI_NONE;
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
func_80078884(NA_SE_SY_OCARINA_ERROR);
Audio_OcaSetInstrument(0);
sEnFrPointers.flags = 12;
@ -939,23 +936,6 @@ void EnFr_TalkBeforeReward(EnFr* this, PlayState* play) {
}
}
RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex) {
switch (songIndex) {
case FROG_ZL:
return RC_ZR_FROGS_ZELDAS_LULLABY;
case FROG_EPONA:
return RC_ZR_FROGS_EPONAS_SONG;
case FROG_SARIA:
return RC_ZR_FROGS_SARIAS_SONG;
case FROG_SUNS:
return RC_ZR_FROGS_SUNS_SONG;
case FROG_SOT:
return RC_ZR_FROGS_SONG_OF_TIME;
default:
return RC_UNKNOWN_CHECK;
}
}
void EnFr_SetReward(EnFr* this, PlayState* play) {
u16 songIndex;
@ -963,16 +943,12 @@ void EnFr_SetReward(EnFr* this, PlayState* play) {
songIndex = this->songIndex;
this->actionFunc = EnFr_Deactivate;
this->reward = GI_NONE;
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
if ((songIndex >= FROG_ZL) && (songIndex <= FROG_SOT)) {
if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) {
gSaveContext.eventChkInf[13] |= sSongIndex[songIndex];
GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]);
if (!IS_RANDO) {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) {
this->reward = GI_RUPEE_PURPLE;
} else {
this->getItemEntry = Randomizer_GetItemFromKnownCheck(EnFr_RandomizerCheckFromSongIndex(songIndex), GI_RUPEE_PURPLE);
this->reward = this->getItemEntry.getItemId;
}
} else {
this->reward = GI_RUPEE_BLUE;
@ -981,11 +957,8 @@ void EnFr_SetReward(EnFr* this, PlayState* play) {
if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) {
gSaveContext.eventChkInf[13] |= sSongIndex[songIndex];
GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]);
if (!IS_RANDO) {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) {
this->reward = GI_HEART_PIECE;
} else {
this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_FROGS_IN_THE_RAIN, GI_HEART_PIECE);
this->reward = this->getItemEntry.getItemId;
}
} else {
this->reward = GI_RUPEE_BLUE;
@ -994,11 +967,8 @@ void EnFr_SetReward(EnFr* this, PlayState* play) {
if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) {
gSaveContext.eventChkInf[13] |= sSongIndex[songIndex];
GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]);
if (!IS_RANDO) {
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) {
this->reward = GI_HEART_PIECE;
} else {
this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_FROGS_OCARINA_GAME, GI_HEART_PIECE);
this->reward = this->getItemEntry.getItemId;
}
} else {
this->reward = GI_RUPEE_PURPLE;
@ -1049,29 +1019,23 @@ void EnFr_Deactivate(EnFr* this, PlayState* play) {
this->actionFunc = EnFr_Idle;
} else {
this->actionFunc = EnFr_GiveReward;
if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) {
func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f);
} else {
GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 30.0f, 100.0f);
if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) {
Actor_OfferGetItem(&this->actor, play, this->reward, 30.0f, 100.0f);
}
}
}
void EnFr_GiveReward(EnFr* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_FROGS, true, this)) {
this->actor.parent = NULL;
this->actionFunc = EnFr_SetIdle;
} else {
if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) {
func_8002F434(&this->actor, play, this->reward, 30.0f, 100.0f);
} else {
GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 30.0f, 100.0f);
}
Actor_OfferGetItem(&this->actor, play, this->reward, 30.0f, 100.0f);
}
}
void EnFr_SetIdle(EnFr* this, PlayState* play) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play) || (IS_RANDO && this->reward == RG_ICE_TRAP)) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) {
this->actionFunc = EnFr_Idle;
}
}

View File

@ -73,7 +73,6 @@ typedef struct EnFr {
/* 0x03AA */ s16 xyAngleButterfly; // Butterfly Travels along random angles in the x-y plane
/* 0x03AC */ Vec3f posButterfly; // Position/Coordinates of the Butterfly
/* 0x03B8 */ Vec3f posButterflyLight; // Used in Lights_PointNoGlowSetInfo()
/* */ GetItemEntry getItemEntry;
} EnFr; // size = 0x03C4
typedef struct {
@ -81,4 +80,7 @@ typedef struct {
EnFr* frogs[5];
} EnFrPointers;
void EnFr_Idle(EnFr* enFr, PlayState* play);
void EnFr_GiveReward(EnFr* enFr, PlayState* play);
#endif

Some files were not shown because too many files have changed in this diff Show More