mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-22 09:22:18 -05:00
Merge pull request #3755 from garrettjoecox/develop-rando-changes
Vanilla Behavior Overhaul
This commit is contained in:
commit
04f9ec1b78
@ -1 +1 @@
|
||||
Subproject commit b135db823aaabf6e848fcbd2796933b0771f9968
|
||||
Subproject commit 493639d5daf75c8fa5d374f96fc95b652714299f
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -129,15 +129,15 @@ void BossRush_SpawnBlueWarps(PlayState* play) {
|
||||
// Spawn blue warps in Chamber of Sages based on what bosses have been defeated.
|
||||
if (gSaveContext.linkAge == LINK_AGE_CHILD) {
|
||||
// Forest Medallion (Gohma)
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE)) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP)) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -100, 6, -170, 0, 0, 0, -1, false);
|
||||
}
|
||||
// Fire Medallion (King Dodongo)
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN)) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 100, 6, -170, 0, 0, 0, -1, false);
|
||||
}
|
||||
// Water Medallion (Barinade)
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY)) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 199, 6, 0, 0, 0, 0, -1, false);
|
||||
}
|
||||
} else {
|
||||
@ -146,15 +146,15 @@ void BossRush_SpawnBlueWarps(PlayState* play) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -199, 6, 0, 0, 0, 0, -1, false);
|
||||
}
|
||||
// Forest Medallion (Phantom Ganondorf)
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE)) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -100, 6, -170, 0, 0, 0, -1, false);
|
||||
}
|
||||
// Fire Medallion (Volvagia)
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE)) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 100, 6, -170, 0, 0, 0, -1, false);
|
||||
}
|
||||
// Water Medallion (Morpha)
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 199, 6, 0, 0, 0, 0, -1, false);
|
||||
}
|
||||
// Spirit Medallion (Twinrova)
|
||||
@ -242,22 +242,22 @@ void BossRush_HandleCompleteBoss(PlayState* play) {
|
||||
gSaveContext.isBossRushPaused = 1;
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP);
|
||||
break;
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP);
|
||||
break;
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP);
|
||||
break;
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
|
||||
break;
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP);
|
||||
break;
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP);
|
||||
break;
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE);
|
||||
@ -432,13 +432,13 @@ void BossRush_InitSave() {
|
||||
// Set flags and Link's age based on chosen settings.
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ADULT ||
|
||||
gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) {
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE);
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN);
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP);
|
||||
if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) {
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE);
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE);
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP);
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE);
|
||||
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE);
|
||||
}
|
||||
|
56
soh/soh/Enhancements/cheat_hook_handlers.cpp
Normal file
56
soh/soh/Enhancements/cheat_hook_handlers.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include <libultraship/bridge.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "variables.h"
|
||||
|
||||
extern SaveContext gSaveContext;
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
void CheatsOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* opt) {
|
||||
switch (id) {
|
||||
case GI_VB_DEKU_STICK_BREAK: {
|
||||
if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GI_VB_DEKU_STICK_BE_ON_FIRE: {
|
||||
if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE) {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
player->unk_860 = 200; // Keeps the stick's flame lit
|
||||
player->unk_85C = 1.0f; // Ensures the stick is the proper length
|
||||
*should = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GI_VB_DEKU_STICK_BURN_OUT: {
|
||||
if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GI_VB_DEKU_STICK_BURN_DOWN: {
|
||||
if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t onVanillaBehaviorHook = 0;
|
||||
void CheatsRegisterHooks() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) mutable {
|
||||
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(onVanillaBehaviorHook);
|
||||
onVanillaBehaviorHook = 0;
|
||||
onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(CheatsOnVanillaBehaviorHandler);
|
||||
|
||||
});
|
||||
}
|
6
soh/soh/Enhancements/cheat_hook_handlers.h
Normal file
6
soh/soh/Enhancements/cheat_hook_handlers.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef CHEAT_HOOK_HANDLERS_H
|
||||
#define CHEAT_HOOK_HANDLERS_H
|
||||
|
||||
void CheatsRegisterHooks();
|
||||
|
||||
#endif // CHEAT_HOOK_HANDLERS_H
|
@ -349,22 +349,9 @@ const std::vector<FlagTable> flagTables = {
|
||||
{ 0x30, "Entered the Market" },
|
||||
} },
|
||||
{ "Randomizer Inf Flags", RANDOMIZER_INF, 16, {
|
||||
{ RAND_INF_DUNGEONS_DONE_DEKU_TREE, "DUNGEONS_DONE_DEKU_TREE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN, "DUNGEONS_DONE_DODONGOS_CAVERN" },
|
||||
{ RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY, "DUNGEONS_DONE_JABU_JABUS_BELLY" },
|
||||
{ RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE, "DUNGEONS_DONE_FOREST_TEMPLE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE, "DUNGEONS_DONE_FIRE_TEMPLE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_WATER_TEMPLE, "DUNGEONS_DONE_WATER_TEMPLE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" },
|
||||
|
||||
{ RAND_INF_TRIALS_DONE_LIGHT_TRIAL, "TRIALS_DONE_LIGHT_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_FOREST_TRIAL, "TRIALS_DONE_FOREST_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_FIRE_TRIAL, "TRIALS_DONE_FIRE_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_WATER_TRIAL, "TRIALS_DONE_WATER_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_SPIRIT_TRIAL, "TRIALS_DONE_SPIRIT_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_SHADOW_TRIAL, "TRIALS_DONE_SHADOW_TRIAL" },
|
||||
|
||||
{ RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, "COWS_MILKED_KF_LINKS_HOUSE_COW" },
|
||||
{ RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" },
|
||||
{ RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" },
|
||||
@ -505,6 +492,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 +503,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 +594,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" },
|
||||
} },
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,328 @@ 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: *ObjDekujr
|
||||
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST)
|
||||
GI_VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED,
|
||||
// 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,
|
||||
GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE,
|
||||
/* 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,
|
||||
// Vanilla condition: see CheckCarpentersFreed in z_en_ge1 and z_en_ge2
|
||||
GI_VB_GERUDOS_BE_FRIENDLY,
|
||||
// Vanilla condition: switch
|
||||
GI_VB_GTG_GATE_BE_OPEN,
|
||||
|
||||
/*** 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,
|
||||
GI_VB_PLAY_RAINBOW_BRIDGE_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_OCARINA_MEMORY_GAME,
|
||||
// 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,
|
||||
// Opt: *EnHy
|
||||
GI_VB_GIVE_ITEM_FROM_LOST_DOG,
|
||||
// Opt: *EnBomBowlPit
|
||||
GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING,
|
||||
|
||||
GI_VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD,
|
||||
|
||||
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,
|
||||
|
||||
/*** Cheats? ***/
|
||||
GI_VB_DEKU_STICK_BE_ON_FIRE,
|
||||
GI_VB_DEKU_STICK_BREAK,
|
||||
GI_VB_DEKU_STICK_BURN_DOWN,
|
||||
GI_VB_DEKU_STICK_BURN_OUT,
|
||||
GI_VB_DEKU_UPDATE_BURNING_DEKU_STICK,
|
||||
|
||||
/*** Quick Boss Deaths ***/
|
||||
// Vanilla condition: true
|
||||
GI_VB_PHANTOM_GANON_DEATH_SCENE,
|
||||
GI_VB_NABOORU_KNUCKLE_DEATH_SCENE,
|
||||
} GIVanillaBehavior;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -98,6 +421,7 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
@ -213,6 +537,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));
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -10,6 +10,9 @@
|
||||
#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/cheat_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"
|
||||
@ -1709,6 +1712,9 @@ void RegisterRandomizerCompasses() {
|
||||
}
|
||||
|
||||
void InitMods() {
|
||||
RandomizerRegisterHooks();
|
||||
TimeSaverRegisterHooks();
|
||||
CheatsRegisterHooks();
|
||||
RegisterTTS();
|
||||
RegisterInfiniteMoney();
|
||||
RegisterInfiniteHealth();
|
||||
|
@ -280,6 +280,20 @@ 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",
|
||||
"gTimeSavers.SkipChildStealth",
|
||||
"gTimeSavers.SkipTowerEscape",
|
||||
};
|
||||
|
||||
const std::vector<const char*> cheatCvars = {
|
||||
|
@ -1121,7 +1121,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);
|
||||
|
@ -389,6 +389,76 @@ void StaticData::HintTable_Init() {
|
||||
/*french*/ "Selon moi, le #neuvième ou dixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/#el noveno o décimo cofre del azar# revela #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_1] = HintText(CustomMessage("They say that the #first locked room# in the chest game contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, la #première salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#en la primera sala del Cofre del Tesoro# aguarda #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("They say that #gambling once# grants #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, #parier une fois# donne #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#apostar solo una vez# revelará #[[1]]#.
|
||||
CustomMessage("They say that the #first or second game chest# contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, le #premier ou deuxième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/#el primer o segundo cofre del azar# revela #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_2] = HintText(CustomMessage("They say that the #second locked room# in the chest game contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, la #deuxième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#en la segunda sala del Cofre del Tesoro# aguarda #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("They say that #gambling twice# grants #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, #parier deux fois# donne #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#apostar dos veces# revelará #[[1]]#.
|
||||
CustomMessage("They say that the #third or fourth game chest# contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, le #troisième ou quatrième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/#el tercer o cuarto cofre del azar# revela #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_3] = HintText(CustomMessage("They say that the #third locked room# in the chest game contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, la #troisième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#en la tercera sala del Cofre del Tesoro# aguarda #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("They say that #gambling 3 times# grants #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, #parier trois fois# donne #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#apostar tres veces# revelará #[[1]]#.
|
||||
CustomMessage("They say that the #fifth or sixth game chest# contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, le #cinquième ou sixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/#el quinto o sexto cofre del azar# revela #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_4] = HintText(CustomMessage("They say that the #fourth locked room# in the chest game contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, la #quatrième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#en la cuarta sala del Cofre del Tesoro# aguarda #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("They say that #gambling 4 times# grants #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, #parier quatre fois# donne #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#apostar cuatro veces# revelará #[[1]]#.
|
||||
CustomMessage("They say that the #seventh or eighth game chest# contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, le #septième ou huitième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/#el séptimo u octavo cofre del azar# revela #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_5] = HintText(CustomMessage("They say that the #fifth locked room# in the chest game contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, la #cinquième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#en la quinta sala del Cofre del Tesoro# aguarda #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("They say that #gambling 5 times# grants #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, #parier cinq fois# donne #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#apostar cinco veces# revelará #[[1]]#.
|
||||
CustomMessage("They say that the #ninth or tenth game chest# contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, le #neuvième ou dixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/#el noveno o décimo cofre del azar# revela #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_GF_HBA_1500_POINTS] = HintText(CustomMessage("They say that scoring 1500 in #horseback archery# grants #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, obtenir 1500 points dans l'#archerie équestre# donne #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
|
@ -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)) {
|
||||
|
@ -65,6 +65,7 @@ void AreaTable_Init_CastleTown() {
|
||||
}, {
|
||||
//Locations
|
||||
LocationAccess(RC_TOT_MASTER_SWORD, {[]{return logic->IsAdult;}}),
|
||||
LocationAccess(RC_GIFT_FROM_SAGES, {[]{return logic->IsAdult;}}),
|
||||
LocationAccess(RC_SHEIK_AT_TEMPLE, {[]{return logic->ForestMedallion && logic->IsAdult;}}),
|
||||
}, {
|
||||
//Exits
|
||||
@ -234,10 +235,15 @@ 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_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_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_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_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_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_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_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_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_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)));}}),
|
||||
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)));}}),
|
||||
}, {
|
||||
//Exits
|
||||
|
@ -18,16 +18,11 @@ 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;
|
||||
|
1440
soh/soh/Enhancements/randomizer/hook_handlers.cpp
Normal file
1440
soh/soh/Enhancements/randomizer/hook_handlers.cpp
Normal file
File diff suppressed because it is too large
Load Diff
6
soh/soh/Enhancements/randomizer/hook_handlers.h
Normal file
6
soh/soh/Enhancements/randomizer/hook_handlers.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef RANDOMIZER_HOOK_HANDLERS_H
|
||||
#define RANDOMIZER_HOOK_HANDLERS_H
|
||||
|
||||
void RandomizerRegisterHooks();
|
||||
|
||||
#endif // RANDOMIZER_HOOK_HANDLERS_H
|
@ -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;
|
||||
}
|
||||
}
|
@ -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 IsAHintAccessible() const;
|
||||
@ -67,5 +70,6 @@ class ItemLocation {
|
||||
bool visibleInImGui = false;
|
||||
bool wothCandidate = false;
|
||||
bool barrenCandidate = false;
|
||||
bool obtained = false;
|
||||
};
|
||||
} // namespace Rando
|
@ -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,14 +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);
|
||||
}
|
||||
|
||||
static auto BigPoePoints() {
|
||||
return SpoilerCollectionCheck(SPOILER_CHK_POE_POINTS, 0x00, 0x00);
|
||||
}
|
||||
@ -83,20 +71,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
@ -438,8 +438,6 @@ void Settings::CreateOptionDescriptions() {
|
||||
"Start with Zelda's Letter and the item Impa would normally give you and skip the sequence up "
|
||||
"until after meeting Zelda. Disables the ability to shuffle Weird Egg.";
|
||||
mOptionDescriptions[RSK_SKIP_EPONA_RACE] = "Epona can be summoned with Epona's Song without needing to race Ingo.";
|
||||
mOptionDescriptions[RSK_SKIP_TOWER_ESCAPE] =
|
||||
"The tower escape sequence between Ganondorf and Ganon will be skipped.";
|
||||
mOptionDescriptions[RSK_COMPLETE_MASK_QUEST] =
|
||||
"Once the happy mask shop is opened, all masks will be available to be borrowed.";
|
||||
mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG] =
|
||||
|
@ -145,21 +145,6 @@ Randomizer::Randomizer() {
|
||||
Randomizer::~Randomizer() {
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, RandomizerInf> spoilerFileTrialToEnum = {
|
||||
{ "the Forest Trial", RAND_INF_TRIALS_DONE_FOREST_TRIAL },
|
||||
{ "l'épreuve de la Forêt", RAND_INF_TRIALS_DONE_FOREST_TRIAL },
|
||||
{ "the Fire Trial", RAND_INF_TRIALS_DONE_FIRE_TRIAL },
|
||||
{ "l'épreuve du Feu", RAND_INF_TRIALS_DONE_FIRE_TRIAL },
|
||||
{ "the Water Trial", RAND_INF_TRIALS_DONE_WATER_TRIAL },
|
||||
{ "l'épreuve de l'Eau", RAND_INF_TRIALS_DONE_WATER_TRIAL },
|
||||
{ "the Spirit Trial", RAND_INF_TRIALS_DONE_SPIRIT_TRIAL },
|
||||
{ "l'épreuve de l'Esprit", RAND_INF_TRIALS_DONE_SPIRIT_TRIAL },
|
||||
{ "the Shadow Trial", RAND_INF_TRIALS_DONE_SHADOW_TRIAL },
|
||||
{ "l'épreuve de l'Ombre", RAND_INF_TRIALS_DONE_SHADOW_TRIAL },
|
||||
{ "the Light Trial", RAND_INF_TRIALS_DONE_LIGHT_TRIAL },
|
||||
{ "l'épreuve de la Lumière", RAND_INF_TRIALS_DONE_LIGHT_TRIAL }
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, SceneID> spoilerFileDungeonToScene = {
|
||||
{ "Deku Tree", SCENE_DEKU_TREE },
|
||||
{ "Dodongo's Cavern", SCENE_DODONGOS_CAVERN },
|
||||
@ -344,8 +329,17 @@ void Randomizer::LoadMerchantMessages() {
|
||||
"Je te vends mon dernier %rHaricot&magique%w pour %r99 Rubis%w.\x1B&%gAcheter&Ne pas acheter%w"));
|
||||
}
|
||||
|
||||
bool Randomizer::IsTrialRequired(RandomizerInf trial) {
|
||||
return Rando::Context::GetInstance()->GetTrial(trial - RAND_INF_TRIALS_DONE_LIGHT_TRIAL)->IsRequired();
|
||||
std::map<s32, TrialKey> trialFlagToTrialKey = {
|
||||
{ EVENTCHKINF_COMPLETED_LIGHT_TRIAL, TK_LIGHT_TRIAL, },
|
||||
{ EVENTCHKINF_COMPLETED_FOREST_TRIAL, TK_FOREST_TRIAL, },
|
||||
{ EVENTCHKINF_COMPLETED_FIRE_TRIAL, TK_FIRE_TRIAL, },
|
||||
{ EVENTCHKINF_COMPLETED_WATER_TRIAL, TK_WATER_TRIAL, },
|
||||
{ EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, TK_SPIRIT_TRIAL, },
|
||||
{ EVENTCHKINF_COMPLETED_SHADOW_TRIAL, TK_SHADOW_TRIAL, }
|
||||
};
|
||||
|
||||
bool Randomizer::IsTrialRequired(s32 trialFlag) {
|
||||
return Rando::Context::GetInstance()->GetTrial(trialFlagToTrialKey[trialFlag])->IsRequired();
|
||||
}
|
||||
|
||||
GetItemEntry Randomizer::GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId,
|
||||
@ -1417,21 +1411,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;
|
||||
|
@ -43,7 +43,7 @@ class Randomizer {
|
||||
bool SpoilerFileExists(const char* spoilerFileName);
|
||||
void LoadMerchantMessages();
|
||||
void LoadHintMessages();
|
||||
bool IsTrialRequired(RandomizerInf trial);
|
||||
bool IsTrialRequired(s32 trialFlag);
|
||||
u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey);
|
||||
RandomizerCheck GetCheckFromRandomizerInf(RandomizerInf randomizerInf);
|
||||
RandomizerInf GetRandomizerInfFromCheck(RandomizerCheck rc);
|
||||
|
@ -747,6 +747,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,
|
||||
@ -2354,6 +2359,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,
|
||||
@ -3620,7 +3630,6 @@ typedef enum {
|
||||
RSK_CUCCO_COUNT,
|
||||
RSK_BIG_POE_COUNT,
|
||||
RSK_SKIP_EPONA_RACE,
|
||||
RSK_SKIP_TOWER_ESCAPE,
|
||||
RSK_COMPLETE_MASK_QUEST,
|
||||
RSK_SKIP_SCARECROWS_SONG,
|
||||
RSK_ENABLE_GLITCH_CUTSCENES,
|
||||
|
@ -440,26 +440,19 @@ 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));
|
||||
case SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF:
|
||||
return gSaveContext.eventChkInf[flag / 16] & (0x01 << flag % 16);
|
||||
case SpoilerCollectionCheckType::SPOILER_CHK_GERUDO_MEMBERSHIP_CARD:
|
||||
return CHECK_FLAG_ALL(gSaveContext.eventChkInf[0x09], 0x0F);
|
||||
case SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA:
|
||||
return GET_GS_FLAGS(scene) & flag;
|
||||
case SpoilerCollectionCheckType::SPOILER_CHK_INF_TABLE:
|
||||
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:
|
||||
@ -782,11 +775,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())) {
|
||||
@ -1372,6 +1362,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)) {
|
||||
@ -1706,12 +1701,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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
RAND_INF_DUNGEONS_DONE_DEKU_TREE,
|
||||
RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN,
|
||||
RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY,
|
||||
RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE,
|
||||
RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE,
|
||||
RAND_INF_DUNGEONS_DONE_WATER_TEMPLE,
|
||||
RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE,
|
||||
RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE,
|
||||
|
||||
RAND_INF_TRIALS_DONE_LIGHT_TRIAL,
|
||||
RAND_INF_TRIALS_DONE_FOREST_TRIAL,
|
||||
RAND_INF_TRIALS_DONE_FIRE_TRIAL,
|
||||
RAND_INF_TRIALS_DONE_WATER_TRIAL,
|
||||
RAND_INF_TRIALS_DONE_SPIRIT_TRIAL,
|
||||
RAND_INF_TRIALS_DONE_SHADOW_TRIAL,
|
||||
|
||||
RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW,
|
||||
RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW,
|
||||
RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW,
|
||||
@ -143,12 +130,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 +257,31 @@ 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,
|
||||
|
||||
RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS,
|
||||
RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN,
|
||||
// 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,
|
||||
|
@ -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,99 +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
|
||||
|
||||
if (!Randomizer_GetSettingValue(RSK_ENABLE_GLITCH_CUTSCENES)) {
|
||||
Flags_SetInfTable(INFTABLE_SPOKE_TO_DARUNIA_IN_FIRE_TEMPLE); // Darunia in Fire Temple
|
||||
}
|
||||
// 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_SHUFFLE_OCARINA_BUTTONS) == RO_GENERIC_OFF) {
|
||||
Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_A);
|
||||
@ -341,10 +347,15 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
gSaveContext.entranceIndex = -1;
|
||||
}
|
||||
|
||||
// If any trials aren't required, set them as completed
|
||||
for (u16 i = RAND_INF_TRIALS_DONE_LIGHT_TRIAL; i <= RAND_INF_TRIALS_DONE_SHADOW_TRIAL; i++) {
|
||||
if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired((RandomizerInf)i)) {
|
||||
Flags_SetRandomizerInf((RandomizerInf)i);
|
||||
for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_FOREST_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_FIRE_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_WATER_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_SPIRIT_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_SHADOW_TRIAL }
|
||||
) {
|
||||
if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag)) {
|
||||
Flags_SetEventChkInf(trialFlag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,15 +409,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) {
|
||||
|
@ -147,7 +147,6 @@ void Settings::CreateOptions() {
|
||||
mOptions[RSK_KEYRINGS_GANONS_CASTLE] = Option::Bool("Ganon's Castle", "gRandomizeShuffleKeyRingsGanonsCastle");
|
||||
mOptions[RSK_SKIP_CHILD_STEALTH] = Option::Bool("Skip Child Stealth", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipChildStealth", mOptionDescriptions[RSK_SKIP_CHILD_STEALTH], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP);
|
||||
mOptions[RSK_SKIP_CHILD_ZELDA] = Option::Bool("Skip Child Zelda", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipChildZelda", mOptionDescriptions[RSK_SKIP_CHILD_ZELDA], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP);
|
||||
mOptions[RSK_SKIP_TOWER_ESCAPE] = Option::Bool("Skip Tower Escape", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipTowerEscape", mOptionDescriptions[RSK_SKIP_TOWER_ESCAPE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP);
|
||||
mOptions[RSK_SKIP_EPONA_RACE] = Option::Bool("Skip Epona Race", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipEponaRace", mOptionDescriptions[RSK_SKIP_EPONA_RACE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP);
|
||||
mOptions[RSK_SKIP_SCARECROWS_SONG] = Option::Bool("Skip Scarecrow's Song", "gRandomizeSkipScarecrowsSong", mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG]);
|
||||
mOptions[RSK_BIG_POE_COUNT] = Option::U8("Big Poe Target Count", {NumOpts(1, 10)}, OptionCategory::Setting, "gRandomizeBigPoeTargetCount", mOptionDescriptions[RSK_BIG_POE_COUNT], WidgetType::Slider, 9);
|
||||
@ -715,7 +714,6 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_SKIP_CHILD_STEALTH],
|
||||
&mOptions[RSK_SKIP_CHILD_ZELDA],
|
||||
&mOptions[RSK_SKIP_EPONA_RACE],
|
||||
&mOptions[RSK_SKIP_TOWER_ESCAPE],
|
||||
&mOptions[RSK_COMPLETE_MASK_QUEST],
|
||||
&mOptions[RSK_SKIP_SCARECROWS_SONG]
|
||||
}, false, WidgetContainerType::COLUMN);
|
||||
@ -1202,7 +1200,6 @@ void Settings::CreateOptions() {
|
||||
{ "Timesaver Settings:Big Poe Target Count", RSK_BIG_POE_COUNT },
|
||||
{ "Timesaver Settings:Skip Child Stealth", RSK_SKIP_CHILD_STEALTH },
|
||||
{ "Timesaver Settings:Skip Epona Race", RSK_SKIP_EPONA_RACE },
|
||||
{ "Timesaver Settings:Skip Tower Escape", RSK_SKIP_TOWER_ESCAPE },
|
||||
{ "Timesaver Settings:Complete Mask Quest", RSK_COMPLETE_MASK_QUEST },
|
||||
{ "Timesaver Settings:Skip Scarecrow's Song", RSK_SKIP_SCARECROWS_SONG },
|
||||
{ "Timesaver Settings:Enable Glitch-Useful Cutscenes", RSK_ENABLE_GLITCH_CUTSCENES },
|
||||
@ -2526,7 +2523,6 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
|
||||
case RSK_SKIP_CHILD_ZELDA:
|
||||
case RSK_SKIP_CHILD_STEALTH:
|
||||
case RSK_SKIP_EPONA_RACE:
|
||||
case RSK_SKIP_TOWER_ESCAPE:
|
||||
if (it.value() == "Don't Skip") {
|
||||
mOptions[index].SetSelectedIndex(RO_GENERIC_DONT_SKIP);
|
||||
} else if (it.value() == "Skip") {
|
||||
|
1212
soh/soh/Enhancements/timesaver_hook_handlers.cpp
Normal file
1212
soh/soh/Enhancements/timesaver_hook_handlers.cpp
Normal file
File diff suppressed because it is too large
Load Diff
6
soh/soh/Enhancements/timesaver_hook_handlers.h
Normal file
6
soh/soh/Enhancements/timesaver_hook_handlers.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef TIMESAVER_HOOK_HANDLERS_H
|
||||
#define TIMESAVER_HOOK_HANDLERS_H
|
||||
|
||||
void TimeSaverRegisterHooks();
|
||||
|
||||
#endif // TIMESAVER_HOOK_HANDLERS_H
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <File.h>
|
||||
#include <Json.h>
|
||||
#include <libultraship/classes.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
@ -12,7 +13,6 @@
|
||||
#include "overlays/gamestates/ovl_file_choose/file_choose.h"
|
||||
#include "soh/Enhancements/boss-rush/BossRush.h"
|
||||
#include "soh/resource/type/SohResourceType.h"
|
||||
#include "soh/resource/type/RawJson.h"
|
||||
|
||||
extern "C" {
|
||||
extern MapData* gMapData;
|
||||
@ -1041,19 +1041,19 @@ void InitTTSBank() {
|
||||
|
||||
auto initData = std::make_shared<LUS::ResourceInitData>();
|
||||
initData->Format = RESOURCE_FORMAT_BINARY;
|
||||
initData->Type = static_cast<uint32_t>(SOH::ResourceType::SOH_RawJson);
|
||||
initData->Type = static_cast<uint32_t>(LUS::ResourceType::Json);
|
||||
initData->ResourceVersion = 0;
|
||||
|
||||
sceneMap = std::static_pointer_cast<SOH::RawJson>(
|
||||
sceneMap = std::static_pointer_cast<LUS::Json>(
|
||||
LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/scenes" + languageSuffix, true, initData))->Data;
|
||||
|
||||
miscMap = std::static_pointer_cast<SOH::RawJson>(
|
||||
miscMap = std::static_pointer_cast<LUS::Json>(
|
||||
LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/misc" + languageSuffix, true, initData))->Data;
|
||||
|
||||
kaleidoMap = std::static_pointer_cast<SOH::RawJson>(
|
||||
kaleidoMap = std::static_pointer_cast<LUS::Json>(
|
||||
LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/kaleidoscope" + languageSuffix, true, initData))->Data;
|
||||
|
||||
fileChooseMap = std::static_pointer_cast<SOH::RawJson>(
|
||||
fileChooseMap = std::static_pointer_cast<LUS::Json>(
|
||||
LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/filechoose" + languageSuffix, true, initData))->Data;
|
||||
}
|
||||
|
||||
|
@ -120,10 +120,13 @@ GameInteractorSail* GameInteractorSail::Instance;
|
||||
#include "soh/resource/importer/SkeletonLimbFactory.h"
|
||||
#include "soh/resource/importer/TextFactory.h"
|
||||
#include "soh/resource/importer/BackgroundFactory.h"
|
||||
#include "soh/resource/importer/RawJsonFactory.h"
|
||||
|
||||
#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;
|
||||
@ -345,7 +348,6 @@ OTRGlobals::OTRGlobals() {
|
||||
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryAudioSoundFontV2>(), RESOURCE_FORMAT_BINARY, "AudioSoundFont", static_cast<uint32_t>(SOH::ResourceType::SOH_AudioSoundFont), 2);
|
||||
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryAudioSequenceV2>(), RESOURCE_FORMAT_BINARY, "AudioSequence", static_cast<uint32_t>(SOH::ResourceType::SOH_AudioSequence), 2);
|
||||
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryBackgroundV0>(), RESOURCE_FORMAT_BINARY, "Background", static_cast<uint32_t>(SOH::ResourceType::SOH_Background), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryRawJsonV0>(), RESOURCE_FORMAT_BINARY, "RawJson", static_cast<uint32_t>(SOH::ResourceType::SOH_RawJson), 0);
|
||||
|
||||
gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
||||
gRandoContext->InitStaticData();
|
||||
@ -2348,8 +2350,8 @@ extern "C" void Randomizer_LoadMerchantMessages() {
|
||||
OTRGlobals::Instance->gRandomizer->LoadMerchantMessages();
|
||||
}
|
||||
|
||||
extern "C" bool Randomizer_IsTrialRequired(RandomizerInf trial) {
|
||||
return OTRGlobals::Instance->gRandomizer->IsTrialRequired(trial);
|
||||
extern "C" bool Randomizer_IsTrialRequired(s32 trialFlag) {
|
||||
return OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag);
|
||||
}
|
||||
|
||||
extern "C" u32 SpoilerFileExists(const char* spoilerFileName) {
|
||||
@ -2563,9 +2565,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)
|
||||
|
@ -159,7 +159,7 @@ FishIdentity Randomizer_IdentifyFish(s32 sceneNum, s32 actorParams);
|
||||
void Randomizer_ParseSpoiler(const char* fileLoc);
|
||||
void Randomizer_LoadHintMessages();
|
||||
void Randomizer_LoadMerchantMessages();
|
||||
bool Randomizer_IsTrialRequired(RandomizerInf trial);
|
||||
bool Randomizer_IsTrialRequired(s32 trialFlag);
|
||||
GetItemEntry Randomizer_GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId);
|
||||
GetItemEntry Randomizer_GetItemFromActorWithoutObtainabilityCheck(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId);
|
||||
GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
|
||||
|
@ -403,6 +403,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();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -488,6 +495,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());
|
||||
});
|
||||
});
|
||||
|
||||
@ -817,6 +825,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++) {
|
||||
|
@ -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,88 @@ 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.QuickBossDeaths", 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.QuickBossDeaths", 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.QuickBossDeaths", 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.QuickBossDeaths", 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("Quick Boss Deaths", "gTimeSavers.SkipCutscene.QuickBossDeaths", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO);
|
||||
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::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", "gTimeSavers.SkipCutscene.GlitchAiding", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, 0);
|
||||
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 Child Stealth", "gTimeSavers.SkipChildStealth", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false);
|
||||
UIWidgets::Tooltip("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Skip Tower Escape", "gTimeSavers.SkipTowerEscape", false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false);
|
||||
UIWidgets::Tooltip("Skip the tower escape sequence between Ganondorf and Ganon.");
|
||||
|
||||
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 +688,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 +1291,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");
|
||||
|
@ -1,19 +0,0 @@
|
||||
#include "soh/resource/importer/RawJsonFactory.h"
|
||||
#include "soh/resource/type/RawJson.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace SOH {
|
||||
std::shared_ptr<LUS::IResource> ResourceFactoryBinaryRawJsonV0::ReadResource(std::shared_ptr<LUS::File> file) {
|
||||
if (!FileHasValidFormatAndReader(file)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto rawJson = std::make_shared<RawJson>(file->InitData);
|
||||
auto reader = std::get<std::shared_ptr<LUS::BinaryReader>>(file->Reader);
|
||||
|
||||
rawJson->DataSize = file->Buffer->size();
|
||||
rawJson->Data = nlohmann::json::parse(reader->ReadCString(), nullptr, true, true);
|
||||
|
||||
return rawJson;
|
||||
}
|
||||
} // namespace SOH
|
@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "resource/Resource.h"
|
||||
#include "resource/ResourceFactoryBinary.h"
|
||||
|
||||
namespace SOH {
|
||||
class ResourceFactoryBinaryRawJsonV0 : public LUS::ResourceFactoryBinary {
|
||||
public:
|
||||
std::shared_ptr<LUS::IResource> ReadResource(std::shared_ptr<LUS::File> file) override;
|
||||
};
|
||||
}; // namespace SOH
|
@ -1,14 +0,0 @@
|
||||
#include "RawJson.h"
|
||||
|
||||
namespace SOH {
|
||||
RawJson::RawJson() : Resource(std::shared_ptr<LUS::ResourceInitData>()) {
|
||||
}
|
||||
|
||||
void* RawJson::GetPointer() {
|
||||
return &Data;
|
||||
}
|
||||
|
||||
size_t RawJson::GetPointerSize() {
|
||||
return DataSize * sizeof(char);
|
||||
}
|
||||
} // namespace SOH
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "resource/Resource.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace SOH {
|
||||
|
||||
class RawJson : public LUS::Resource<void> {
|
||||
public:
|
||||
using Resource::Resource;
|
||||
|
||||
RawJson();
|
||||
|
||||
void* GetPointer() override;
|
||||
size_t GetPointerSize() override;
|
||||
|
||||
nlohmann::json Data;
|
||||
size_t DataSize;
|
||||
};
|
||||
}; // namespace SOH
|
@ -17,6 +17,5 @@ enum class ResourceType {
|
||||
SOH_AudioSequence = 0x4F534551, // OSEQ
|
||||
SOH_Background = 0x4F424749, // OBGI
|
||||
SOH_SceneCommand = 0x4F52434D, // ORCM
|
||||
SOH_RawJson = 0x4A534F4E, // JSON
|
||||
};
|
||||
} // namespace SOH
|
||||
|
@ -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) {
|
||||
@ -6283,58 +6282,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;
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -395,7 +395,7 @@ void Map_InitData(PlayState* play, s16 room) {
|
||||
} else if (play->sceneNum == SCENE_LAKE_HYLIA) {
|
||||
if ((LINK_AGE_IN_YEARS == YEARS_ADULT) &&
|
||||
((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) ||
|
||||
(IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)))) {
|
||||
(IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)))) {
|
||||
extendedMapIndex = 0x15;
|
||||
}
|
||||
} else if (play->sceneNum == SCENE_GERUDO_VALLEY) {
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
@ -331,27 +277,27 @@ u8 CheckMedallionCount() {
|
||||
u8 CheckDungeonCount() {
|
||||
u8 dungeonCount = 0;
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE)) {
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP)) {
|
||||
dungeonCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN)) {
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) {
|
||||
dungeonCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY)) {
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) {
|
||||
dungeonCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE)) {
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) {
|
||||
dungeonCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE)) {
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) {
|
||||
dungeonCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) {
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
|
||||
dungeonCount++;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -480,18 +363,6 @@ void Play_Init(GameState* thisx) {
|
||||
u8 tempSetupIndex;
|
||||
s32 pad[2];
|
||||
|
||||
// Skip Child Stealth when option is enabled, Zelda's Letter isn't obtained and Impa's reward hasn't been received
|
||||
// eventChkInf[4] & 1 = Got Zelda's Letter
|
||||
// eventChkInf[5] & 0x200 = Got Impa's reward
|
||||
// entranceIndex 0x7A, ENTR_CASTLE_COURTYARD_GUARDS_DAY_0, Castle Courtyard - Day from crawlspace
|
||||
// entranceIndex 0x400, ENTR_CASTLE_COURTYARD_ZELDA_0, Zelda's Courtyard
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_CHILD_STEALTH) &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY)) {
|
||||
if (gSaveContext.entranceIndex == ENTR_CASTLE_COURTYARD_GUARDS_DAY_0) {
|
||||
gSaveContext.entranceIndex = ENTR_CASTLE_COURTYARD_ZELDA_0;
|
||||
}
|
||||
}
|
||||
|
||||
// Properly initialize the frame counter so it doesn't use garbage data
|
||||
if (!firstInit) {
|
||||
play->gameplayFrames = 0;
|
||||
@ -1448,15 +1319,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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "z_bg_gjyo_bridge.h"
|
||||
#include "objects/object_gjyo_objects/object_gjyo_objects.h"
|
||||
#include "scenes/dungeons/ganon_tou/ganon_tou_scene.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
||||
#define FLAGS 0
|
||||
|
||||
@ -50,8 +51,7 @@ void BgGjyoBridge_Init(Actor* thisx, PlayState* play) {
|
||||
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, thisx, colHeader);
|
||||
|
||||
int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE);
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT) || (IS_RANDO && bridge == RO_BRIDGE_ALWAYS_OPEN)) {
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT)) {
|
||||
this->actionFunc = func_808787A4;
|
||||
} else {
|
||||
this->dyna.actor.draw = NULL;
|
||||
@ -70,8 +70,10 @@ void func_808787A4(BgGjyoBridge* this, PlayState* play) {
|
||||
}
|
||||
|
||||
void LaunchBridgeCutscene(BgGjyoBridge* this, PlayState* play) {
|
||||
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs);
|
||||
gSaveContext.cutsceneTrigger = 1;
|
||||
if (GameInteractor_Should(GI_VB_PLAY_RAINBOW_BRIDGE_CS, true, NULL)) {
|
||||
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs);
|
||||
gSaveContext.cutsceneTrigger = 1;
|
||||
}
|
||||
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
||||
}
|
||||
|
||||
@ -84,70 +86,24 @@ u8 CheckPlayerPosition(Player* player, PlayState* play) {
|
||||
void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, PlayState* play) {
|
||||
Player* player = GET_PLAYER(play);
|
||||
|
||||
if (!IS_RANDO) {
|
||||
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) && CheckPlayerPosition(player, play)) {
|
||||
LaunchBridgeCutscene(this, play);
|
||||
}
|
||||
} else {
|
||||
int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE);
|
||||
int bridgeStoneCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_STONE_COUNT);
|
||||
int bridgeMedallionCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT);
|
||||
int bridgeRewardCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_REWARD_COUNT);
|
||||
int bridgeDungeonCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT);
|
||||
int bridgeTokenCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_TOKEN_COUNT);
|
||||
u8 vanillaBridgeCondition =
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) &&
|
||||
CheckPlayerPosition(player, play);
|
||||
|
||||
switch (bridge) {
|
||||
case RO_BRIDGE_VANILLA:
|
||||
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT)) {
|
||||
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
||||
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
|
||||
}
|
||||
break;
|
||||
case RO_BRIDGE_STONES:
|
||||
if ((CheckStoneCount() + CheckBridgeRewardCount()) >= bridgeStoneCount) {
|
||||
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
||||
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
|
||||
}
|
||||
break;
|
||||
case RO_BRIDGE_MEDALLIONS:
|
||||
if ((CheckMedallionCount() + CheckBridgeRewardCount()) >= bridgeMedallionCount) {
|
||||
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
||||
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
|
||||
}
|
||||
break;
|
||||
case RO_BRIDGE_DUNGEON_REWARDS:
|
||||
if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >= bridgeRewardCount) {
|
||||
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
||||
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
|
||||
}
|
||||
break;
|
||||
case RO_BRIDGE_DUNGEONS:
|
||||
if ((CheckDungeonCount() + CheckBridgeRewardCount()) >= bridgeDungeonCount) {
|
||||
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
||||
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
|
||||
}
|
||||
break;
|
||||
case RO_BRIDGE_TOKENS:
|
||||
if (gSaveContext.inventory.gsTokens >= bridgeTokenCount) {
|
||||
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
||||
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
|
||||
}
|
||||
break;
|
||||
case RO_BRIDGE_GREG:
|
||||
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
|
||||
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
||||
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE, vanillaBridgeCondition, NULL)) {
|
||||
LaunchBridgeCutscene(this, play);
|
||||
}
|
||||
}
|
||||
|
||||
void BgGjyoBridge_SpawnBridge(BgGjyoBridge* this, PlayState* play) {
|
||||
if (IS_RANDO || (play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.npcActions[2] != NULL) &&
|
||||
(play->csCtx.npcActions[2]->action == 2)) {
|
||||
u8 vanillaBridgeCondition =
|
||||
(play->csCtx.state != CS_STATE_IDLE) &&
|
||||
(play->csCtx.npcActions[2] != NULL) &&
|
||||
(play->csCtx.npcActions[2]->action == 2);
|
||||
|
||||
if (!GameInteractor_Should(GI_VB_PLAY_RAINBOW_BRIDGE_CS, true, NULL) || vanillaBridgeCondition) {
|
||||
this->dyna.actor.draw = BgGjyoBridge_Draw;
|
||||
func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -217,7 +217,7 @@ void BgSpot06Objects_Destroy(Actor* thisx, PlayState* play) {
|
||||
// Due to Ships resource caching, the water box collisions for the river have to be manually reset
|
||||
play->colCtx.colHeader->waterBoxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].zMin = WATER_LEVEL_RIVER_LOWER_Z;
|
||||
|
||||
if (IS_RANDO && Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) {
|
||||
if (IS_RANDO && Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
|
||||
// For randomizer when leaving lake hylia while the water level is lowered,
|
||||
// reset the "raise lake hylia water" flag back to on if the water temple is cleared
|
||||
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
|
||||
@ -461,7 +461,7 @@ void BgSpot06Objects_Update(Actor* thisx, PlayState* play) {
|
||||
Object_Spawn(&play->objectCtx, OBJECT_GAMEPLAY_DANGEON_KEEP);
|
||||
|
||||
s16 switchParams;
|
||||
if (Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) {
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
|
||||
// Toggle-able floor switch,
|
||||
// linked to temp_switch 0x1E (room temporary, cleared when room unloads)
|
||||
switchParams = 0x3E10;
|
||||
@ -477,7 +477,7 @@ void BgSpot06Objects_Update(Actor* thisx, PlayState* play) {
|
||||
0x0000 | (TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN & 0xFF), false);
|
||||
|
||||
// Spawn a Navi check spot when Water Temple isn't cleared
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, -896.0f, -1243.0f, 6953.0f, 0, 0, 0,
|
||||
0x3D00 | (TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI & 0xFF), false);
|
||||
}
|
||||
@ -485,7 +485,7 @@ void BgSpot06Objects_Update(Actor* thisx, PlayState* play) {
|
||||
actionCounter++;
|
||||
return;
|
||||
} else if (actionCounter == 1) {
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
|
||||
// Remove the link to ice block so melting it doesn't set the flag
|
||||
lakeControlFloorSwitch->params = 0x3E01;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "z_bg_spot12_saku.h"
|
||||
#include "objects/object_spot12_obj/object_spot12_obj.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
||||
#define FLAGS 0
|
||||
|
||||
@ -58,15 +59,9 @@ void func_808B3420(BgSpot12Saku* this, PlayState* play, CollisionHeader* collisi
|
||||
void BgSpot12Saku_Init(Actor* thisx, PlayState* play) {
|
||||
BgSpot12Saku* this = (BgSpot12Saku*)thisx;
|
||||
|
||||
// If ER is on, force the gate to always use its permanent flag
|
||||
// (which it only uses in Child Gerudo Fortress in the vanilla game)
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) {
|
||||
thisx->params = 0x0002;
|
||||
}
|
||||
|
||||
func_808B3420(this, play, &gGerudoFortressGTGShutterCol, DPM_UNK);
|
||||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||
if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) {
|
||||
if (GameInteractor_Should(GI_VB_GTG_GATE_BE_OPEN, Flags_GetSwitch(play, this->dyna.actor.params & 0x3F), NULL)) {
|
||||
func_808B3714(this);
|
||||
} else {
|
||||
func_808B3550(this);
|
||||
@ -87,7 +82,7 @@ void func_808B3550(BgSpot12Saku* this) {
|
||||
}
|
||||
|
||||
void func_808B357C(BgSpot12Saku* this, PlayState* play) {
|
||||
if (Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) {
|
||||
if (GameInteractor_Should(GI_VB_GTG_GATE_BE_OPEN, Flags_GetSwitch(play, this->dyna.actor.params & 0x3F), NULL)) {
|
||||
func_808B35E4(this);
|
||||
this->timer = 20;
|
||||
OnePointCutscene_Init(play, 4170, -99, &this->dyna.actor, MAIN_CAM);
|
||||
@ -131,12 +126,6 @@ void func_808B37AC(BgSpot12Saku* this, PlayState* play) {
|
||||
void BgSpot12Saku_Update(Actor* thisx, PlayState* play) {
|
||||
BgSpot12Saku* this = (BgSpot12Saku*)thisx;
|
||||
|
||||
// If ER is on, when the guard opens the GtG gate its permanent flag will be set.
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF &&
|
||||
Flags_GetSwitch(play, 0x3A)) {
|
||||
Flags_SetSwitch(play, 0x2);
|
||||
}
|
||||
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 };
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
@ -1539,20 +1539,14 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) {
|
||||
|
||||
if (this->csTimer == 180) {
|
||||
play->transitionTrigger = TRANS_TRIGGER_START;
|
||||
if ((IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE) || IS_BOSS_RUSH)) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO);
|
||||
play->nextEntranceIndex = ENTR_GANON_BOSS_0;
|
||||
}
|
||||
else {
|
||||
play->nextEntranceIndex = ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0;
|
||||
}
|
||||
play->nextEntranceIndex = ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0;
|
||||
play->transitionType = TRANS_TYPE_FADE_WHITE_FAST;
|
||||
}
|
||||
break;
|
||||
|
||||
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 +1645,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 +1748,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 +1815,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 +1857,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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -12,19 +12,10 @@
|
||||
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
|
||||
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
|
||||
#include "soh/Enhancements/boss-rush/BossRush.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ NOT_DEAD,
|
||||
/* 1 */ DEATH_START,
|
||||
/* 2 */ DEATH_THROES,
|
||||
/* 3 */ DEATH_WARP,
|
||||
/* 4 */ DEATH_SCREAM,
|
||||
/* 5 */ DEATH_DISINTEGRATE,
|
||||
/* 6 */ DEATH_FINISH
|
||||
} BossGanondrofDeathState;
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ THROW_NORMAL,
|
||||
/* 1 */ THROW_SLOW
|
||||
@ -42,12 +33,6 @@ typedef enum {
|
||||
/* 3 */ CHARGE_FINISH
|
||||
} BossGanondrofChargeAction;
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ DEATH_SPASM,
|
||||
/* 1 */ DEATH_LIMP,
|
||||
/* 2 */ DEATH_HUNCHED
|
||||
} BossGanondrofDeathAction;
|
||||
|
||||
void BossGanondrof_Init(Actor* thisx, PlayState* play);
|
||||
void BossGanondrof_Destroy(Actor* thisx, PlayState* play);
|
||||
void BossGanondrof_Update(Actor* thisx, PlayState* play);
|
||||
@ -926,7 +911,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");
|
||||
@ -959,26 +944,13 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) {
|
||||
case DEATH_THROES:
|
||||
switch (this->work[GND_ACTION_STATE]) {
|
||||
case DEATH_SPASM:
|
||||
if (Animation_OnFrame(&this->skelAnime, this->fwork[GND_END_FRAME]) && !IS_RANDO && !IS_BOSS_RUSH) {
|
||||
this->fwork[GND_END_FRAME] = Animation_GetLastFrame(&gPhantomGanonAirDamageAnim);
|
||||
Animation_Change(&this->skelAnime, &gPhantomGanonAirDamageAnim, 0.5f, 0.0f,
|
||||
this->fwork[GND_END_FRAME], ANIMMODE_ONCE_INTERP, 0.0f);
|
||||
this->work[GND_ACTION_STATE] = DEATH_LIMP;
|
||||
} else if (IS_RANDO || IS_BOSS_RUSH) {
|
||||
// Skip to death scream animation and move ganondrof to middle
|
||||
this->deathState = DEATH_SCREAM;
|
||||
this->timers[0] = 50;
|
||||
Animation_MorphToLoop(&this->skelAnime, &gPhantomGanonScreamAnim, -10.0f);
|
||||
this->actor.world.pos.x = GND_BOSSROOM_CENTER_X;
|
||||
this->actor.world.pos.y = GND_BOSSROOM_CENTER_Y + 83.0f;
|
||||
this->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
|
||||
this->actor.shape.rot.y = 0;
|
||||
this->work[GND_BODY_DECAY_INDEX] = 0;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_LAST);
|
||||
|
||||
// Move Player out of the center of the room
|
||||
player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f;
|
||||
player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
|
||||
if (GameInteractor_Should(GI_VB_PHANTOM_GANON_DEATH_SCENE, true, this)) {
|
||||
if (Animation_OnFrame(&this->skelAnime, this->fwork[GND_END_FRAME])) {
|
||||
this->fwork[GND_END_FRAME] = Animation_GetLastFrame(&gPhantomGanonAirDamageAnim);
|
||||
Animation_Change(&this->skelAnime, &gPhantomGanonAirDamageAnim, 0.5f, 0.0f,
|
||||
this->fwork[GND_END_FRAME], ANIMMODE_ONCE_INTERP, 0.0f);
|
||||
this->work[GND_ACTION_STATE] = DEATH_LIMP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DEATH_LIMP:
|
||||
@ -991,26 +963,25 @@ void BossGanondrof_Death(BossGanondrof* this, PlayState* play) {
|
||||
bodyDecayLevel = 1;
|
||||
break;
|
||||
}
|
||||
if (IS_RANDO || IS_BOSS_RUSH) {
|
||||
break;
|
||||
}
|
||||
Math_ApproachS(&this->actor.shape.rot.y, this->work[GND_VARIANCE_TIMER] * -100, 5, 0xBB8);
|
||||
Math_ApproachF(&this->cameraNextEye.z, this->targetPos.z + 60.0f, 0.02f, 0.5f);
|
||||
Math_ApproachF(&this->actor.world.pos.y, GND_BOSSROOM_CENTER_Y + 133.0f, 0.05f, 100.0f);
|
||||
this->actor.world.pos.y += Math_SinS(this->work[GND_VARIANCE_TIMER] * 1500);
|
||||
this->cameraNextAt.x = this->targetPos.x;
|
||||
this->cameraNextAt.y = this->targetPos.y - 10.0f;
|
||||
this->cameraNextAt.z = this->targetPos.z;
|
||||
if (this->timers[0] == 0) {
|
||||
this->deathState = DEATH_WARP;
|
||||
this->timers[0] = 350;
|
||||
this->timers[1] = 50;
|
||||
this->fwork[GND_CAMERA_ZOOM] = 300.0f;
|
||||
this->cameraNextEye.y = GND_BOSSROOM_CENTER_Y + 233.0f;
|
||||
player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f;
|
||||
player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
|
||||
holdCamera = true;
|
||||
bodyDecayLevel = 1;
|
||||
if (GameInteractor_Should(GI_VB_PHANTOM_GANON_DEATH_SCENE, true, NULL)) {
|
||||
Math_ApproachS(&this->actor.shape.rot.y, this->work[GND_VARIANCE_TIMER] * -100, 5, 0xBB8);
|
||||
Math_ApproachF(&this->cameraNextEye.z, this->targetPos.z + 60.0f, 0.02f, 0.5f);
|
||||
Math_ApproachF(&this->actor.world.pos.y, GND_BOSSROOM_CENTER_Y + 133.0f, 0.05f, 100.0f);
|
||||
this->actor.world.pos.y += Math_SinS(this->work[GND_VARIANCE_TIMER] * 1500);
|
||||
this->cameraNextAt.x = this->targetPos.x;
|
||||
this->cameraNextAt.y = this->targetPos.y - 10.0f;
|
||||
this->cameraNextAt.z = this->targetPos.z;
|
||||
if (this->timers[0] == 0) {
|
||||
this->deathState = DEATH_WARP;
|
||||
this->timers[0] = 350;
|
||||
this->timers[1] = 50;
|
||||
this->fwork[GND_CAMERA_ZOOM] = 300.0f;
|
||||
this->cameraNextEye.y = GND_BOSSROOM_CENTER_Y + 233.0f;
|
||||
player->actor.world.pos.x = GND_BOSSROOM_CENTER_X - 200.0f;
|
||||
player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
|
||||
holdCamera = true;
|
||||
bodyDecayLevel = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DEATH_WARP:
|
||||
@ -1104,7 +1075,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);
|
||||
|
@ -61,6 +61,23 @@ typedef enum {
|
||||
/* 13 */ GND_FLOAT_COUNT = 13
|
||||
} BossGanondrofF32Var;
|
||||
|
||||
// SOH [Enhancements] Relocated from z_boss_ganondrof.c to use in time saver.
|
||||
typedef enum {
|
||||
/* 0 */ NOT_DEAD,
|
||||
/* 1 */ DEATH_START,
|
||||
/* 2 */ DEATH_THROES,
|
||||
/* 3 */ DEATH_WARP,
|
||||
/* 4 */ DEATH_SCREAM,
|
||||
/* 5 */ DEATH_DISINTEGRATE,
|
||||
/* 6 */ DEATH_FINISH
|
||||
} BossGanondrofDeathState;
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ DEATH_SPASM,
|
||||
/* 1 */ DEATH_LIMP,
|
||||
/* 2 */ DEATH_HUNCHED
|
||||
} BossGanondrofDeathAction;
|
||||
|
||||
typedef struct BossGanondrof {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ SkelAnime skelAnime;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -51,4 +51,6 @@ typedef struct DemoIm {
|
||||
/* 0x02D4 */ NpcInteractInfo interactInfo;
|
||||
} DemoIm; // size = 0x02FC
|
||||
|
||||
void func_80986794(DemoIm* demoIm);
|
||||
|
||||
#endif
|
||||
|
@ -64,66 +64,23 @@ static u8 sEnergyColors[] = {
|
||||
/* Forest prim */ 255, 255, 170, /* env */ 0, 200, 0,
|
||||
};
|
||||
|
||||
// Translates from the barrier's actor params to their corresponding randInf flags.
|
||||
RandomizerInf trialParamToRandInf(u16 params) {
|
||||
switch (params) {
|
||||
case KEKKAI_LIGHT:
|
||||
return RAND_INF_TRIALS_DONE_LIGHT_TRIAL;
|
||||
case KEKKAI_FOREST:
|
||||
return RAND_INF_TRIALS_DONE_FOREST_TRIAL;
|
||||
case KEKKAI_FIRE:
|
||||
return RAND_INF_TRIALS_DONE_FIRE_TRIAL;
|
||||
case KEKKAI_WATER:
|
||||
return RAND_INF_TRIALS_DONE_WATER_TRIAL;
|
||||
case KEKKAI_SPIRIT:
|
||||
return RAND_INF_TRIALS_DONE_SPIRIT_TRIAL;
|
||||
case KEKKAI_SHADOW:
|
||||
return RAND_INF_TRIALS_DONE_SHADOW_TRIAL;
|
||||
}
|
||||
}
|
||||
|
||||
s32 DemoKekkai_CheckEventFlag(s32 params) {
|
||||
static s32 eventFlags[] = { 0xC3, 0xBC, 0xBF, 0xBE, 0xBD, 0xAD, 0xBB };
|
||||
static s32 eventFlags[] = {
|
||||
EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER,
|
||||
EVENTCHKINF_COMPLETED_WATER_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_LIGHT_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_FIRE_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_SHADOW_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_SPIRIT_TRIAL,
|
||||
EVENTCHKINF_COMPLETED_FOREST_TRIAL,
|
||||
};
|
||||
|
||||
if ((params < KEKKAI_TOWER) || (params > KEKKAI_FOREST)) {
|
||||
return true;
|
||||
}
|
||||
if (IS_RANDO && params > KEKKAI_TOWER) {
|
||||
return Flags_GetRandomizerInf(trialParamToRandInf(params));
|
||||
}
|
||||
return Flags_GetEventChkInf(eventFlags[params]);
|
||||
}
|
||||
|
||||
u32 TrialsDoneCount() {
|
||||
u8 trialCount = 0;
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_LIGHT_TRIAL)) {
|
||||
trialCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FOREST_TRIAL)) {
|
||||
trialCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FIRE_TRIAL)) {
|
||||
trialCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_WATER_TRIAL)) {
|
||||
trialCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SPIRIT_TRIAL)) {
|
||||
trialCount++;
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SHADOW_TRIAL)) {
|
||||
trialCount++;
|
||||
}
|
||||
|
||||
return trialCount;
|
||||
}
|
||||
|
||||
void DemoKekkai_Init(Actor* thisx, PlayState* play) {
|
||||
s32 pad;
|
||||
DemoKekkai* this = (DemoKekkai*)thisx;
|
||||
@ -147,13 +104,6 @@ void DemoKekkai_Init(Actor* thisx, PlayState* play) {
|
||||
this->collider2.dim.radius = thisx->scale.x * 6100.0f;
|
||||
this->collider2.dim.height = thisx->scale.y * 5000.0f;
|
||||
this->collider2.dim.yShift = 300;
|
||||
|
||||
if (IS_RANDO) {
|
||||
if (TrialsDoneCount() == NUM_TRIALS) {
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEKKAI_WATER:
|
||||
case KEKKAI_LIGHT:
|
||||
@ -161,10 +111,6 @@ void DemoKekkai_Init(Actor* thisx, PlayState* play) {
|
||||
case KEKKAI_SHADOW:
|
||||
case KEKKAI_SPIRIT:
|
||||
case KEKKAI_FOREST:
|
||||
if (IS_RANDO && Flags_GetRandomizerInf(trialParamToRandInf(thisx->params))) {
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
this->energyAlpha = 1.0f;
|
||||
this->orbScale = 1.0f;
|
||||
Actor_SetScale(thisx, 0.1f);
|
||||
@ -265,18 +211,10 @@ void DemoKekkai_Update(Actor* thisx, PlayState* play2) {
|
||||
}
|
||||
|
||||
void DemoKekkai_TrialBarrierDispel(Actor* thisx, PlayState* play) {
|
||||
static s32 eventFlags[] = { 0xC3, 0xBC, 0xBF, 0xBE, 0xBD, 0xAD, 0xBB };
|
||||
static u16 csFrames[] = { 0, 280, 280, 280, 280, 280, 280 };
|
||||
s32 pad;
|
||||
DemoKekkai* this = (DemoKekkai*)thisx;
|
||||
|
||||
if (IS_RANDO) {
|
||||
Flags_SetRandomizerInf(trialParamToRandInf(thisx->params));
|
||||
// May or may not be needed. Not sure if needed for anything
|
||||
// that randoInf isn't already covering. Leaving it for safety.
|
||||
Flags_SetEventChkInf(eventFlags[thisx->params]);
|
||||
}
|
||||
|
||||
if (play->csCtx.frames == csFrames[this->actor.params]) {
|
||||
func_800F3F3C(0xA);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user