mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 13:23:45 -07:00
Merge remote-tracking branch 'origin/develop' into actor-accessibility-experiments
This commit is contained in:
commit
37c03f4453
26 changed files with 599 additions and 443 deletions
|
@ -1522,7 +1522,7 @@ typedef struct {
|
||||||
/* 0x34 */ s32 isEnabled;
|
/* 0x34 */ s32 isEnabled;
|
||||||
} StickDirectionPrompt;
|
} StickDirectionPrompt;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct FileChooseContext {
|
||||||
/* 0x00000 */ GameState state;
|
/* 0x00000 */ GameState state;
|
||||||
/* 0x000A4 */ Vtx* windowVtx;
|
/* 0x000A4 */ Vtx* windowVtx;
|
||||||
/* 0x000A8 */ u8* staticSegment;
|
/* 0x000A8 */ u8* staticSegment;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||||
#include "soh/Enhancements/gameplaystats.h"
|
#include "soh/Enhancements/gameplaystats.h"
|
||||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||||
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
|
#include "soh/Enhancements/boss-rush/BossRush.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* 0x0 */ MAGIC_STATE_IDLE, // Regular gameplay
|
/* 0x0 */ MAGIC_STATE_IDLE, // Regular gameplay
|
||||||
|
|
|
@ -19,7 +19,7 @@ static std::array<const char*, ACTORCAT_MAX> sCatToStrArray{
|
||||||
"SWITCH", "BG", "PLAYER", "EXPLOSIVE", "NPC", "ENEMY", "PROP", "ITEMACTION", "MISC", "BOSS", "DOOR", "CHEST",
|
"SWITCH", "BG", "PLAYER", "EXPLOSIVE", "NPC", "ENEMY", "PROP", "ITEMACTION", "MISC", "BOSS", "DOOR", "CHEST",
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFINE_SCENE(_1, _2, enumName, _4, _5, _6) #enumName
|
#define DEFINE_SCENE(_1, _2, enumName, _4, _5, _6) #enumName,
|
||||||
|
|
||||||
static std::array<const char*, SCENE_ID_MAX> sSceneIdToStrArray{
|
static std::array<const char*, SCENE_ID_MAX> sSceneIdToStrArray{
|
||||||
#include "tables/scene_table.h"
|
#include "tables/scene_table.h"
|
||||||
|
|
51
soh/soh/Enhancements/BonkDamage.cpp
Normal file
51
soh/soh/Enhancements/BonkDamage.cpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
#include "soh/ShipInit.hpp"
|
||||||
|
#include "./enhancementTypes.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "functions.h"
|
||||||
|
#include "macros.h"
|
||||||
|
extern PlayState* gPlayState;
|
||||||
|
extern SaveContext gSaveContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterBonkDamage() {
|
||||||
|
COND_HOOK(OnPlayerBonk, CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE) != BONK_DAMAGE_NONE,
|
||||||
|
[] {
|
||||||
|
uint16_t bonkDamage = 0;
|
||||||
|
switch (CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE)) {
|
||||||
|
case BONK_DAMAGE_NONE:
|
||||||
|
return;
|
||||||
|
case BONK_DAMAGE_OHKO:
|
||||||
|
gSaveContext.health = 0;
|
||||||
|
return;
|
||||||
|
case BONK_DAMAGE_QUARTER_HEART:
|
||||||
|
bonkDamage = 4;
|
||||||
|
break;
|
||||||
|
case BONK_DAMAGE_HALF_HEART:
|
||||||
|
bonkDamage = 8;
|
||||||
|
break;
|
||||||
|
case BONK_DAMAGE_1_HEART:
|
||||||
|
bonkDamage = 16;
|
||||||
|
break;
|
||||||
|
case BONK_DAMAGE_2_HEARTS:
|
||||||
|
bonkDamage = 32;
|
||||||
|
break;
|
||||||
|
case BONK_DAMAGE_4_HEARTS:
|
||||||
|
bonkDamage = 64;
|
||||||
|
break;
|
||||||
|
case BONK_DAMAGE_8_HEARTS:
|
||||||
|
bonkDamage = 128;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Health_ChangeBy(gPlayState, -bonkDamage);
|
||||||
|
// Set invincibility to make Link flash red as a visual damage indicator.
|
||||||
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
|
player->invincibilityTimer = 28;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc registerBonkDamage(RegisterBonkDamage, { CVAR_ENHANCEMENT("BonkDamageMult") });
|
|
@ -2,6 +2,7 @@
|
||||||
#include "sequence.h"
|
#include "sequence.h"
|
||||||
#include "sfx.h"
|
#include "sfx.h"
|
||||||
#include "soh/cvar_prefixes.h"
|
#include "soh/cvar_prefixes.h"
|
||||||
|
#include "soh/Notification/Notification.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utils/StringHelper.h>
|
#include <utils/StringHelper.h>
|
||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
|
@ -458,3 +459,11 @@ extern "C" bool AudioCollection_HasSequenceNum(uint16_t seqId) {
|
||||||
extern "C" size_t AudioCollection_SequenceMapSize() {
|
extern "C" size_t AudioCollection_SequenceMapSize() {
|
||||||
return AudioCollection::Instance->SequenceMapSize();
|
return AudioCollection::Instance->SequenceMapSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void AudioCollection_EmitSongNameNotification(s32 seqId) {
|
||||||
|
const char* sequenceName = AudioCollection_GetSequenceName(seqId);
|
||||||
|
if (sequenceName != NULL) {
|
||||||
|
Notification::Emit({ .message = "Currently playing: " + std::string(sequenceName),
|
||||||
|
.remainingTime = (float)CVarGetInteger(CVAR_AUDIO("SeqNameOverlayDuration"), 5) });
|
||||||
|
}
|
||||||
|
}
|
|
@ -73,4 +73,5 @@ void AudioCollection_AddToCollection(char* otrPath, uint16_t seqNum);
|
||||||
const char* AudioCollection_GetSequenceName(uint16_t seqId);
|
const char* AudioCollection_GetSequenceName(uint16_t seqId);
|
||||||
bool AudioCollection_HasSequenceNum(uint16_t seqId);
|
bool AudioCollection_HasSequenceNum(uint16_t seqId);
|
||||||
size_t AudioCollection_SequenceMapSize();
|
size_t AudioCollection_SequenceMapSize();
|
||||||
|
void AudioCollection_EmitSongNameNotification(s32 seqId);
|
||||||
#endif
|
#endif
|
|
@ -2,6 +2,8 @@
|
||||||
#include "soh/OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
#include "soh_assets.h"
|
||||||
|
#include "soh/frame_interpolation.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -14,14 +16,87 @@ extern "C" {
|
||||||
#include "src/overlays/actors/ovl_Boss_Goma/z_boss_goma.h"
|
#include "src/overlays/actors/ovl_Boss_Goma/z_boss_goma.h"
|
||||||
#include "src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h"
|
#include "src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h"
|
||||||
#include "src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
|
#include "src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
|
||||||
extern PlayState* gPlayState;
|
#include "src/overlays/gamestates/ovl_file_choose/file_choose.h"
|
||||||
|
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||||
Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point);
|
|
||||||
#include "textures/icon_item_nes_static/icon_item_nes_static.h"
|
#include "textures/icon_item_nes_static/icon_item_nes_static.h"
|
||||||
#include "textures/icon_item_ger_static/icon_item_ger_static.h"
|
#include "textures/icon_item_ger_static/icon_item_ger_static.h"
|
||||||
#include "textures/icon_item_fra_static/icon_item_fra_static.h"
|
#include "textures/icon_item_fra_static/icon_item_fra_static.h"
|
||||||
|
|
||||||
|
extern PlayState* gPlayState;
|
||||||
|
|
||||||
|
Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point);
|
||||||
|
void FileChoose_UpdateStickDirectionPromptAnim(GameState* thisx);
|
||||||
|
void FileChoose_DrawTextRec(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a, f32 x, f32 y, f32 z, s32 s, s32 t,
|
||||||
|
f32 dx, f32 dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_BOSSES_ALL,
|
||||||
|
BR_CHOICE_BOSSES_CHILD,
|
||||||
|
BR_CHOICE_BOSSES_ADULT,
|
||||||
|
BR_CHOICE_BOSSES_GANONDORF_GANON
|
||||||
|
} BossRushBossesChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_HEARTS_10,
|
||||||
|
BR_CHOICE_HEARTS_15,
|
||||||
|
BR_CHOICE_HEARTS_20,
|
||||||
|
BR_CHOICE_HEARTS_3,
|
||||||
|
BR_CHOICE_HEARTS_5,
|
||||||
|
BR_CHOICE_HEARTS_7
|
||||||
|
} BossRushHeartsChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_AMMO_LIMITED,
|
||||||
|
BR_CHOICE_AMMO_FULL,
|
||||||
|
BR_CHOICE_AMMO_MAXED,
|
||||||
|
} BossRushAmmoChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_HEAL_GANONDORF,
|
||||||
|
BR_CHOICE_HEAL_EVERYBOSS,
|
||||||
|
BR_CHOICE_HEAL_NEVER,
|
||||||
|
} BossRushHealChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_MAGIC_SINGLE,
|
||||||
|
BR_CHOICE_MAGIC_DOUBLE,
|
||||||
|
} BossRushMagicChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_BGS_NO,
|
||||||
|
BR_CHOICE_BGS_YES,
|
||||||
|
} BossRushBgsChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_BOTTLE_NO,
|
||||||
|
BR_CHOICE_BOTTLE_EMPTY,
|
||||||
|
BR_CHOICE_BOTTLE_FAIRY,
|
||||||
|
BR_CHOICE_BOTTLE_REDPOTION,
|
||||||
|
BR_CHOICE_BOTTLE_GREENPOTION,
|
||||||
|
BR_CHOICE_BOTTLE_BLUEPOTION
|
||||||
|
} BossRushBottleChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_LONGSHOT_NO,
|
||||||
|
BR_CHOICE_LONGSHOT_YES,
|
||||||
|
} BossRushLongshotChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_HOVERBOOTS_NO,
|
||||||
|
BR_CHOICE_HOVERBOOTS_YES,
|
||||||
|
} BossRushHoverBootsChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_BUNNYHOOD_NO,
|
||||||
|
BR_CHOICE_BUNNYHOOD_YES,
|
||||||
|
} BossRushBunnyHoodChoices;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_TIMER_YES,
|
||||||
|
BR_CHOICE_TIMER_NO,
|
||||||
|
} BossRushTimerChoices;
|
||||||
|
|
||||||
typedef struct BossRushSetting {
|
typedef struct BossRushSetting {
|
||||||
std::array<std::string, LANGUAGE_MAX> name;
|
std::array<std::string, LANGUAGE_MAX> name;
|
||||||
std::vector<std::array<std::string, LANGUAGE_MAX>> choices;
|
std::vector<std::array<std::string, LANGUAGE_MAX>> choices;
|
||||||
|
@ -114,6 +189,180 @@ u8 BossRush_GetSettingOptionsAmount(u8 optionIndex) {
|
||||||
return static_cast<u8>(BossRushOptions[optionIndex].choices.size());
|
return static_cast<u8>(BossRushOptions[optionIndex].choices.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileChoose_UpdateBossRushMenu(GameState* gameState) {
|
||||||
|
static s8 sLastBossRushOptionIndex = -1;
|
||||||
|
static s8 sLastBossRushOptionValue = -1;
|
||||||
|
|
||||||
|
FileChoose_UpdateStickDirectionPromptAnim(gameState);
|
||||||
|
FileChooseContext* fileChooseContext = (FileChooseContext*)gameState;
|
||||||
|
Input* input = &fileChooseContext->state.input[0];
|
||||||
|
bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0);
|
||||||
|
|
||||||
|
// Fade in elements after opening Boss Rush options menu
|
||||||
|
fileChooseContext->bossRushUIAlpha += 25;
|
||||||
|
if (fileChooseContext->bossRushUIAlpha > 255) {
|
||||||
|
fileChooseContext->bossRushUIAlpha = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animate up/down arrows.
|
||||||
|
fileChooseContext->bossRushArrowOffset += 1;
|
||||||
|
if (fileChooseContext->bossRushArrowOffset >= 30) {
|
||||||
|
fileChooseContext->bossRushArrowOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move menu selection up or down.
|
||||||
|
if (ABS(fileChooseContext->stickRelY) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) {
|
||||||
|
// Move down
|
||||||
|
if (fileChooseContext->stickRelY < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN))) {
|
||||||
|
// When selecting past the last option, cycle back to the first option.
|
||||||
|
if ((fileChooseContext->bossRushIndex + 1) > BR_OPTIONS_MAX - 1) {
|
||||||
|
fileChooseContext->bossRushIndex = 0;
|
||||||
|
fileChooseContext->bossRushOffset = 0;
|
||||||
|
} else {
|
||||||
|
fileChooseContext->bossRushIndex++;
|
||||||
|
// When last visible option is selected when moving down, offset the list down by one.
|
||||||
|
if (fileChooseContext->bossRushIndex - fileChooseContext->bossRushOffset >
|
||||||
|
BOSSRUSH_MAX_OPTIONS_ON_SCREEN - 1) {
|
||||||
|
fileChooseContext->bossRushOffset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (fileChooseContext->stickRelY > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DUP))) {
|
||||||
|
// When selecting past the first option, cycle back to the last option and offset the list to view it
|
||||||
|
// properly.
|
||||||
|
if ((fileChooseContext->bossRushIndex - 1) < 0) {
|
||||||
|
fileChooseContext->bossRushIndex = BR_OPTIONS_MAX - 1;
|
||||||
|
fileChooseContext->bossRushOffset =
|
||||||
|
fileChooseContext->bossRushIndex - BOSSRUSH_MAX_OPTIONS_ON_SCREEN + 1;
|
||||||
|
} else {
|
||||||
|
// When first visible option is selected when moving up, offset the list up by one.
|
||||||
|
if (fileChooseContext->bossRushIndex - fileChooseContext->bossRushOffset == 0) {
|
||||||
|
fileChooseContext->bossRushOffset--;
|
||||||
|
}
|
||||||
|
fileChooseContext->bossRushIndex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||||
|
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cycle through choices for currently selected option.
|
||||||
|
if (ABS(fileChooseContext->stickRelX) > 30 ||
|
||||||
|
(dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) {
|
||||||
|
if (fileChooseContext->stickRelX > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT))) {
|
||||||
|
// If exceeding the amount of choices for the selected option, cycle back to the first.
|
||||||
|
if ((gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] + 1) ==
|
||||||
|
BossRush_GetSettingOptionsAmount(fileChooseContext->bossRushIndex)) {
|
||||||
|
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] = 0;
|
||||||
|
} else {
|
||||||
|
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]++;
|
||||||
|
}
|
||||||
|
} else if (fileChooseContext->stickRelX < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT))) {
|
||||||
|
// If cycling back when already at the first choice for the selected option, cycle back to the last choice.
|
||||||
|
if ((gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] - 1) < 0) {
|
||||||
|
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] =
|
||||||
|
BossRush_GetSettingOptionsAmount(fileChooseContext->bossRushIndex) - 1;
|
||||||
|
} else {
|
||||||
|
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||||
|
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sLastBossRushOptionIndex != fileChooseContext->bossRushIndex ||
|
||||||
|
sLastBossRushOptionValue != gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]) {
|
||||||
|
GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(
|
||||||
|
fileChooseContext->bossRushIndex,
|
||||||
|
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]);
|
||||||
|
sLastBossRushOptionIndex = fileChooseContext->bossRushIndex;
|
||||||
|
sLastBossRushOptionValue = gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
||||||
|
fileChooseContext->configMode = CM_BOSS_RUSH_TO_QUEST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load into the game.
|
||||||
|
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||||
|
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||||
|
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||||
|
fileChooseContext->buttonIndex = 0xFE;
|
||||||
|
fileChooseContext->menuMode = FS_MENU_MODE_SELECT;
|
||||||
|
fileChooseContext->selectMode = SM_FADE_OUT;
|
||||||
|
fileChooseContext->prevConfigMode = fileChooseContext->configMode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileChoose_DrawBossRushMenuWindowContents(FileChooseContext* fileChooseContext) {
|
||||||
|
OPEN_DISPS(fileChooseContext->state.gfxCtx);
|
||||||
|
|
||||||
|
uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language;
|
||||||
|
uint8_t listOffset = fileChooseContext->bossRushOffset;
|
||||||
|
uint8_t textAlpha = fileChooseContext->bossRushUIAlpha;
|
||||||
|
|
||||||
|
// Draw arrows to indicate that the list can scroll up or down.
|
||||||
|
// Arrow up
|
||||||
|
if (listOffset > 0) {
|
||||||
|
uint16_t arrowUpX = 140;
|
||||||
|
uint16_t arrowUpY = 76 - (fileChooseContext->bossRushArrowOffset / 10);
|
||||||
|
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowUpTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0,
|
||||||
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||||
|
G_TX_NOLOD);
|
||||||
|
gSPWideTextureRectangle(POLY_OPA_DISP++, arrowUpX << 2, arrowUpY << 2, (arrowUpX + 8) << 2, (arrowUpY + 8) << 2,
|
||||||
|
G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11));
|
||||||
|
}
|
||||||
|
// Arrow down
|
||||||
|
if (BR_OPTIONS_MAX - listOffset > BOSSRUSH_MAX_OPTIONS_ON_SCREEN) {
|
||||||
|
uint16_t arrowDownX = 140;
|
||||||
|
uint16_t arrowDownY = 181 + (fileChooseContext->bossRushArrowOffset / 10);
|
||||||
|
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowDownTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0,
|
||||||
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||||
|
G_TX_NOLOD);
|
||||||
|
gSPWideTextureRectangle(POLY_OPA_DISP++, arrowDownX << 2, arrowDownY << 2, (arrowDownX + 8) << 2,
|
||||||
|
(arrowDownY + 8) << 2, G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw options. There's more options than what fits on the screen, so the visible options
|
||||||
|
// depend on the current offset of the list. Currently selected option pulses in
|
||||||
|
// color and has arrows surrounding the option.
|
||||||
|
for (uint8_t i = listOffset; i - listOffset < BOSSRUSH_MAX_OPTIONS_ON_SCREEN; i++) {
|
||||||
|
uint16_t textYOffset = (i - listOffset) * 16;
|
||||||
|
|
||||||
|
// Option name.
|
||||||
|
Interface_DrawTextLine(fileChooseContext->state.gfxCtx, (char*)BossRush_GetSettingName(i, language), 65,
|
||||||
|
(87 + textYOffset), 255, 255, 80, textAlpha, 0.8f, true);
|
||||||
|
|
||||||
|
// Selected choice for option.
|
||||||
|
uint16_t finalKerning = Interface_DrawTextLine(
|
||||||
|
fileChooseContext->state.gfxCtx,
|
||||||
|
(char*)BossRush_GetSettingChoiceName(i, gSaveContext.ship.quest.data.bossRush.options[i], language), 165,
|
||||||
|
(87 + textYOffset), 255, 255, 255, textAlpha, 0.8f, true);
|
||||||
|
|
||||||
|
// Draw arrows around selected option.
|
||||||
|
if (fileChooseContext->bossRushIndex == i) {
|
||||||
|
Gfx_SetupDL_39Opa(fileChooseContext->state.gfxCtx);
|
||||||
|
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||||
|
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0,
|
||||||
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD,
|
||||||
|
G_TX_NOLOD);
|
||||||
|
FileChoose_DrawTextRec(fileChooseContext->state.gfxCtx, fileChooseContext->stickLeftPrompt.arrowColorR,
|
||||||
|
fileChooseContext->stickLeftPrompt.arrowColorG,
|
||||||
|
fileChooseContext->stickLeftPrompt.arrowColorB, textAlpha, 160, (92 + textYOffset),
|
||||||
|
0.42f, 0, 0, -1.0f, 1.0f);
|
||||||
|
FileChoose_DrawTextRec(fileChooseContext->state.gfxCtx, fileChooseContext->stickRightPrompt.arrowColorR,
|
||||||
|
fileChooseContext->stickRightPrompt.arrowColorG,
|
||||||
|
fileChooseContext->stickRightPrompt.arrowColorB, textAlpha, (171 + finalKerning),
|
||||||
|
(92 + textYOffset), 0.42f, 0, 0, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CLOSE_DISPS(fileChooseContext->state.gfxCtx);
|
||||||
|
}
|
||||||
|
|
||||||
void BossRush_SpawnBlueWarps(PlayState* play) {
|
void BossRush_SpawnBlueWarps(PlayState* play) {
|
||||||
|
|
||||||
// Spawn blue warps in Chamber of Sages based on what bosses have been defeated.
|
// Spawn blue warps in Chamber of Sages based on what bosses have been defeated.
|
||||||
|
@ -316,7 +565,7 @@ void BossRush_HandleCompleteBoss(PlayState* play) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BossRush_InitSave() {
|
extern "C" void BossRush_InitSave() {
|
||||||
|
|
||||||
// Set player name to Lonk for the few textboxes that show up during Boss Rush. Player can't input their own name.
|
// Set player name to Lonk for the few textboxes that show up during Boss Rush. Player can't input their own name.
|
||||||
std::array<char, 8> brPlayerName = { 21, 50, 49, 46, 62, 62, 62, 62 };
|
std::array<char, 8> brPlayerName = { 21, 50, 49, 46, 62, 62, 62, 62 };
|
||||||
|
@ -609,6 +858,17 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||||
*should = false;
|
*should = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Handle the heal on blue warp
|
||||||
|
case VB_BLUE_WARP_CONSIDER_ADULT_IN_RANGE: {
|
||||||
|
if (*should) {
|
||||||
|
BossRush_HandleBlueWarpHeal(gPlayState);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VB_SHOW_GAMEPLAY_TIMER: {
|
||||||
|
*should |= gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_TIMER] == BR_CHOICE_TIMER_YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Prevent saving
|
// Prevent saving
|
||||||
case VB_BE_ABLE_TO_SAVE:
|
case VB_BE_ABLE_TO_SAVE:
|
||||||
// Disable doors so the player can't leave the boss rooms backwards.
|
// Disable doors so the player can't leave the boss rooms backwards.
|
||||||
|
@ -629,25 +889,6 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BossRush_OnActorInitHandler(void* actorRef) {
|
|
||||||
Actor* actor = static_cast<Actor*>(actorRef);
|
|
||||||
|
|
||||||
if (actor->id == ACTOR_DEMO_SA && gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) {
|
|
||||||
BossRush_SpawnBlueWarps(gPlayState);
|
|
||||||
Actor_Kill(actor);
|
|
||||||
GET_PLAYER(gPlayState)->actor.world.rot.y = GET_PLAYER(gPlayState)->actor.shape.rot.y = 27306;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove chests, mainly for the chest in King Dodongo's boss room.
|
|
||||||
// Remove bushes, used in Gohma's arena.
|
|
||||||
// Remove pots, used in Barinade's and Ganondorf's arenas.
|
|
||||||
if (actor->id == ACTOR_EN_KUSA || actor->id == ACTOR_OBJ_TSUBO || actor->id == ACTOR_EN_BOX) {
|
|
||||||
Actor_Kill(actor);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BossRush_OnSceneInitHandler(s16 sceneNum) {
|
void BossRush_OnSceneInitHandler(s16 sceneNum) {
|
||||||
// Unpause the timer when the scene loaded isn't the Chamber of Sages.
|
// Unpause the timer when the scene loaded isn't the Chamber of Sages.
|
||||||
if (sceneNum != SCENE_CHAMBER_OF_THE_SAGES) {
|
if (sceneNum != SCENE_CHAMBER_OF_THE_SAGES) {
|
||||||
|
@ -667,38 +908,32 @@ void BossRush_OnBlueWarpUpdate(void* actor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BossRush_RegisterHooks() {
|
void RegisterBossRush() {
|
||||||
static u32 onVanillaBehaviorHook = 0;
|
COND_HOOK(OnLoadGame, true, [](int32_t fileNum) {
|
||||||
static u32 onSceneInitHook = 0;
|
COND_ID_HOOK(OnActorInit, ACTOR_DEMO_SA, IS_BOSS_RUSH, [](void* actorPtr) {
|
||||||
static u32 onActorInitHook = 0;
|
BossRush_SpawnBlueWarps(gPlayState);
|
||||||
static u32 onBossDefeatHook = 0;
|
Actor_Kill((Actor*)actorPtr);
|
||||||
static u32 onActorUpdate = 0;
|
GET_PLAYER(gPlayState)->actor.world.rot.y = 27306;
|
||||||
|
GET_PLAYER(gPlayState)->actor.shape.rot.y = 27306;
|
||||||
|
});
|
||||||
|
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) {
|
// Remove bushes, used in Gohma's arena
|
||||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(onVanillaBehaviorHook);
|
COND_ID_HOOK(OnActorInit, ACTOR_EN_KUSA, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); });
|
||||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(onSceneInitHook);
|
|
||||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(onActorInitHook);
|
|
||||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnBossDefeat>(onBossDefeatHook);
|
|
||||||
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnActorUpdate>(onActorUpdate);
|
|
||||||
|
|
||||||
onVanillaBehaviorHook = 0;
|
// Remove pots, used in Barinade's and Ganondorf's arenas
|
||||||
onSceneInitHook = 0;
|
COND_ID_HOOK(OnActorInit, ACTOR_OBJ_TSUBO, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); });
|
||||||
onActorInitHook = 0;
|
|
||||||
onBossDefeatHook = 0;
|
|
||||||
onActorUpdate = 0;
|
|
||||||
|
|
||||||
if (!IS_BOSS_RUSH)
|
// Remove chests, mainly for the chest in King Dodongo's boss room
|
||||||
return;
|
COND_ID_HOOK(OnActorInit, ACTOR_EN_BOX, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); });
|
||||||
|
|
||||||
onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(
|
COND_HOOK(OnVanillaBehavior, IS_BOSS_RUSH, BossRush_OnVanillaBehaviorHandler);
|
||||||
BossRush_OnVanillaBehaviorHandler);
|
|
||||||
onSceneInitHook =
|
COND_HOOK(OnSceneInit, IS_BOSS_RUSH, BossRush_OnSceneInitHandler);
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>(BossRush_OnSceneInitHandler);
|
|
||||||
onActorInitHook =
|
COND_HOOK(OnBossDefeat, IS_BOSS_RUSH, BossRush_OnBossDefeatHandler);
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>(BossRush_OnActorInitHandler);
|
|
||||||
onBossDefeatHook =
|
COND_ID_HOOK(OnActorUpdate, ACTOR_DOOR_WARP1, IS_BOSS_RUSH, BossRush_OnBlueWarpUpdate);
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnBossDefeat>(BossRush_OnBossDefeatHandler);
|
|
||||||
onActorUpdate = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(
|
|
||||||
ACTOR_DOOR_WARP1, BossRush_OnBlueWarpUpdate);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc initFunc(RegisterBossRush);
|
|
@ -1,16 +1,41 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "z64.h"
|
#include <libultraship/libultra/types.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void BossRush_HandleBlueWarpHeal(PlayState* play);
|
struct GameState;
|
||||||
void BossRush_InitSave();
|
struct FileChooseContext;
|
||||||
|
|
||||||
|
void FileChoose_UpdateBossRushMenu(struct GameState* gameState);
|
||||||
|
void FileChoose_DrawBossRushMenuWindowContents(struct FileChooseContext* fileChooseContext);
|
||||||
const char* BossRush_GetSettingName(u8 optionIndex, u8 language);
|
const char* BossRush_GetSettingName(u8 optionIndex, u8 language);
|
||||||
const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language);
|
const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language);
|
||||||
u8 BossRush_GetSettingOptionsAmount(u8 optionIndex);
|
u8 BossRush_GetSettingOptionsAmount(u8 optionIndex);
|
||||||
void BossRush_RegisterHooks();
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define BOSSRUSH_MAX_OPTIONS_ON_SCREEN 6
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_OPTIONS_BOSSES,
|
||||||
|
BR_OPTIONS_HEARTS,
|
||||||
|
BR_OPTIONS_AMMO,
|
||||||
|
BR_OPTIONS_HEAL,
|
||||||
|
BR_OPTIONS_HYPERBOSSES,
|
||||||
|
BR_OPTIONS_MAGIC,
|
||||||
|
BR_OPTIONS_BGS,
|
||||||
|
BR_OPTIONS_BOTTLE,
|
||||||
|
BR_OPTIONS_LONGSHOT,
|
||||||
|
BR_OPTIONS_HOVERBOOTS,
|
||||||
|
BR_OPTIONS_BUNNYHOOD,
|
||||||
|
BR_OPTIONS_TIMER,
|
||||||
|
BR_OPTIONS_MAX,
|
||||||
|
} BossRushOptionEnums;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BR_CHOICE_HYPERBOSSES_NO,
|
||||||
|
BR_CHOICE_HYPERBOSSES_YES,
|
||||||
|
} BossRushHyperBossesChoices;
|
|
@ -1,91 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define BOSSRUSH_MAX_OPTIONS_ON_SCREEN 6
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_OPTIONS_BOSSES,
|
|
||||||
BR_OPTIONS_HEARTS,
|
|
||||||
BR_OPTIONS_AMMO,
|
|
||||||
BR_OPTIONS_HEAL,
|
|
||||||
BR_OPTIONS_HYPERBOSSES,
|
|
||||||
BR_OPTIONS_MAGIC,
|
|
||||||
BR_OPTIONS_BGS,
|
|
||||||
BR_OPTIONS_BOTTLE,
|
|
||||||
BR_OPTIONS_LONGSHOT,
|
|
||||||
BR_OPTIONS_HOVERBOOTS,
|
|
||||||
BR_OPTIONS_BUNNYHOOD,
|
|
||||||
BR_OPTIONS_TIMER,
|
|
||||||
BR_OPTIONS_MAX,
|
|
||||||
} BossRushOptionEnums;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_BOSSES_ALL,
|
|
||||||
BR_CHOICE_BOSSES_CHILD,
|
|
||||||
BR_CHOICE_BOSSES_ADULT,
|
|
||||||
BR_CHOICE_BOSSES_GANONDORF_GANON
|
|
||||||
} BossRushBossesChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_HEARTS_10,
|
|
||||||
BR_CHOICE_HEARTS_15,
|
|
||||||
BR_CHOICE_HEARTS_20,
|
|
||||||
BR_CHOICE_HEARTS_3,
|
|
||||||
BR_CHOICE_HEARTS_5,
|
|
||||||
BR_CHOICE_HEARTS_7
|
|
||||||
} BossRushHeartsChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_AMMO_LIMITED,
|
|
||||||
BR_CHOICE_AMMO_FULL,
|
|
||||||
BR_CHOICE_AMMO_MAXED,
|
|
||||||
} BossRushAmmoChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_HEAL_GANONDORF,
|
|
||||||
BR_CHOICE_HEAL_EVERYBOSS,
|
|
||||||
BR_CHOICE_HEAL_NEVER,
|
|
||||||
} BossRushHealChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_HYPERBOSSES_NO,
|
|
||||||
BR_CHOICE_HYPERBOSSES_YES,
|
|
||||||
} BossRushHyperBossesChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_MAGIC_SINGLE,
|
|
||||||
BR_CHOICE_MAGIC_DOUBLE,
|
|
||||||
} BossRushMagicChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_BGS_NO,
|
|
||||||
BR_CHOICE_BGS_YES,
|
|
||||||
} BossRushBgsChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_BOTTLE_NO,
|
|
||||||
BR_CHOICE_BOTTLE_EMPTY,
|
|
||||||
BR_CHOICE_BOTTLE_FAIRY,
|
|
||||||
BR_CHOICE_BOTTLE_REDPOTION,
|
|
||||||
BR_CHOICE_BOTTLE_GREENPOTION,
|
|
||||||
BR_CHOICE_BOTTLE_BLUEPOTION
|
|
||||||
} BossRushBottleChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_LONGSHOT_NO,
|
|
||||||
BR_CHOICE_LONGSHOT_YES,
|
|
||||||
} BossRushLongshotChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_HOVERBOOTS_NO,
|
|
||||||
BR_CHOICE_HOVERBOOTS_YES,
|
|
||||||
} BossRushHoverBootsChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_BUNNYHOOD_NO,
|
|
||||||
BR_CHOICE_BUNNYHOOD_YES,
|
|
||||||
} BossRushBunnyHoodChoices;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BR_CHOICE_TIMER_YES,
|
|
||||||
BR_CHOICE_TIMER_NO,
|
|
||||||
} BossRushTimerChoices;
|
|
|
@ -112,7 +112,9 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TIME_TRAVEL_DISABLED,
|
TIME_TRAVEL_DISABLED,
|
||||||
TIME_TRAVEL_OOT,
|
TIME_TRAVEL_OOT,
|
||||||
|
TIME_TRAVEL_OOT_MS,
|
||||||
TIME_TRAVEL_ANY,
|
TIME_TRAVEL_ANY,
|
||||||
|
TIME_TRAVEL_ANY_MS
|
||||||
} TimeTravelType;
|
} TimeTravelType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace GameInteractionEffect {
|
||||||
|
|
||||||
// MARK: - Flags
|
// MARK: - Flags
|
||||||
GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() {
|
GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ void SetSceneFlag::_Apply() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() {
|
GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ void UnsetSceneFlag::_Apply() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectQueryResult SetFlag::CanBeApplied() {
|
GameInteractionEffectQueryResult SetFlag::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ void SetFlag::_Apply() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() {
|
GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ void UnsetFlag::_Apply() {
|
||||||
|
|
||||||
// MARK: - ModifyHeartContainers
|
// MARK: - ModifyHeartContainers
|
||||||
GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() {
|
GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if ((parameters[0] > 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) > 0x140)) ||
|
} else if ((parameters[0] > 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) > 0x140)) ||
|
||||||
(parameters[0] < 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) < 0x10))) {
|
(parameters[0] < 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) < 0x10))) {
|
||||||
|
@ -115,7 +115,7 @@ void ModifyHeartContainers::_Apply() {
|
||||||
|
|
||||||
// MARK: - FillMagic
|
// MARK: - FillMagic
|
||||||
GameInteractionEffectQueryResult FillMagic::CanBeApplied() {
|
GameInteractionEffectQueryResult FillMagic::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if (!gSaveContext.isMagicAcquired || gSaveContext.magic >= ((gSaveContext.isDoubleMagicAcquired + 1) * 48)) {
|
} else if (!gSaveContext.isMagicAcquired || gSaveContext.magic >= ((gSaveContext.isDoubleMagicAcquired + 1) * 48)) {
|
||||||
return GameInteractionEffectQueryResult::NotPossible;
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
|
@ -129,7 +129,7 @@ void FillMagic::_Apply() {
|
||||||
|
|
||||||
// MARK: - EmptyMagic
|
// MARK: - EmptyMagic
|
||||||
GameInteractionEffectQueryResult EmptyMagic::CanBeApplied() {
|
GameInteractionEffectQueryResult EmptyMagic::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if (!gSaveContext.isMagicAcquired || gSaveContext.magic <= 0) {
|
} else if (!gSaveContext.isMagicAcquired || gSaveContext.magic <= 0) {
|
||||||
return GameInteractionEffectQueryResult::NotPossible;
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
|
@ -143,7 +143,7 @@ void EmptyMagic::_Apply() {
|
||||||
|
|
||||||
// MARK: - ModifyRupees
|
// MARK: - ModifyRupees
|
||||||
GameInteractionEffectQueryResult ModifyRupees::CanBeApplied() {
|
GameInteractionEffectQueryResult ModifyRupees::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if ((parameters[0] < 0 && gSaveContext.rupees <= 0) ||
|
} else if ((parameters[0] < 0 && gSaveContext.rupees <= 0) ||
|
||||||
(parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET))) {
|
(parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET))) {
|
||||||
|
@ -158,7 +158,7 @@ void ModifyRupees::_Apply() {
|
||||||
|
|
||||||
// MARK: - NoUI
|
// MARK: - NoUI
|
||||||
GameInteractionEffectQueryResult NoUI::CanBeApplied() {
|
GameInteractionEffectQueryResult NoUI::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -173,7 +173,7 @@ void NoUI::_Remove() {
|
||||||
|
|
||||||
// MARK: - ModifyGravity
|
// MARK: - ModifyGravity
|
||||||
GameInteractionEffectQueryResult ModifyGravity::CanBeApplied() {
|
GameInteractionEffectQueryResult ModifyGravity::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -188,7 +188,7 @@ void ModifyGravity::_Remove() {
|
||||||
|
|
||||||
// MARK: - ModifyHealth
|
// MARK: - ModifyHealth
|
||||||
GameInteractionEffectQueryResult ModifyHealth::CanBeApplied() {
|
GameInteractionEffectQueryResult ModifyHealth::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if ((parameters[0] > 0 && gSaveContext.health == gSaveContext.healthCapacity) ||
|
} else if ((parameters[0] > 0 && gSaveContext.health == gSaveContext.healthCapacity) ||
|
||||||
(parameters[0] < 0 && (gSaveContext.health + (16 * parameters[0]) <= 0))) {
|
(parameters[0] < 0 && (gSaveContext.health + (16 * parameters[0]) <= 0))) {
|
||||||
|
@ -204,7 +204,7 @@ void ModifyHealth::_Apply() {
|
||||||
// MARK: - SetPlayerHealth
|
// MARK: - SetPlayerHealth
|
||||||
GameInteractionEffectQueryResult SetPlayerHealth::CanBeApplied() {
|
GameInteractionEffectQueryResult SetPlayerHealth::CanBeApplied() {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -217,7 +217,7 @@ void SetPlayerHealth::_Apply() {
|
||||||
// MARK: - FreezePlayer
|
// MARK: - FreezePlayer
|
||||||
GameInteractionEffectQueryResult FreezePlayer::CanBeApplied() {
|
GameInteractionEffectQueryResult FreezePlayer::CanBeApplied() {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -230,7 +230,7 @@ void FreezePlayer::_Apply() {
|
||||||
// MARK: - BurnPlayer
|
// MARK: - BurnPlayer
|
||||||
GameInteractionEffectQueryResult BurnPlayer::CanBeApplied() {
|
GameInteractionEffectQueryResult BurnPlayer::CanBeApplied() {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -243,7 +243,7 @@ void BurnPlayer::_Apply() {
|
||||||
// MARK: - ElectrocutePlayer
|
// MARK: - ElectrocutePlayer
|
||||||
GameInteractionEffectQueryResult ElectrocutePlayer::CanBeApplied() {
|
GameInteractionEffectQueryResult ElectrocutePlayer::CanBeApplied() {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -256,7 +256,7 @@ void ElectrocutePlayer::_Apply() {
|
||||||
// MARK: - KnockbackPlayer
|
// MARK: - KnockbackPlayer
|
||||||
GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() {
|
GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() ||
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() ||
|
||||||
player->stateFlags2 & PLAYER_STATE2_CRAWLING) {
|
player->stateFlags2 & PLAYER_STATE2_CRAWLING) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
|
@ -269,7 +269,7 @@ void KnockbackPlayer::_Apply() {
|
||||||
|
|
||||||
// MARK: - ModifyLinkSize
|
// MARK: - ModifyLinkSize
|
||||||
GameInteractionEffectQueryResult ModifyLinkSize::CanBeApplied() {
|
GameInteractionEffectQueryResult ModifyLinkSize::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -284,7 +284,7 @@ void ModifyLinkSize::_Remove() {
|
||||||
|
|
||||||
// MARK: - InvisibleLink
|
// MARK: - InvisibleLink
|
||||||
GameInteractionEffectQueryResult InvisibleLink::CanBeApplied() {
|
GameInteractionEffectQueryResult InvisibleLink::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -299,7 +299,7 @@ void InvisibleLink::_Remove() {
|
||||||
|
|
||||||
// MARK: - PacifistMode
|
// MARK: - PacifistMode
|
||||||
GameInteractionEffectQueryResult PacifistMode::CanBeApplied() {
|
GameInteractionEffectQueryResult PacifistMode::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -314,7 +314,7 @@ void PacifistMode::_Remove() {
|
||||||
|
|
||||||
// MARK: - DisableZTargeting
|
// MARK: - DisableZTargeting
|
||||||
GameInteractionEffectQueryResult DisableZTargeting::CanBeApplied() {
|
GameInteractionEffectQueryResult DisableZTargeting::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -329,7 +329,7 @@ void DisableZTargeting::_Remove() {
|
||||||
|
|
||||||
// MARK: - WeatherRainstorm
|
// MARK: - WeatherRainstorm
|
||||||
GameInteractionEffectQueryResult WeatherRainstorm::CanBeApplied() {
|
GameInteractionEffectQueryResult WeatherRainstorm::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -344,7 +344,7 @@ void WeatherRainstorm::_Remove() {
|
||||||
|
|
||||||
// MARK: - ReverseControls
|
// MARK: - ReverseControls
|
||||||
GameInteractionEffectQueryResult ReverseControls::CanBeApplied() {
|
GameInteractionEffectQueryResult ReverseControls::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -359,7 +359,7 @@ void ReverseControls::_Remove() {
|
||||||
|
|
||||||
// MARK: - ForceEquipBoots
|
// MARK: - ForceEquipBoots
|
||||||
GameInteractionEffectQueryResult ForceEquipBoots::CanBeApplied() {
|
GameInteractionEffectQueryResult ForceEquipBoots::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -374,7 +374,7 @@ void ForceEquipBoots::_Remove() {
|
||||||
|
|
||||||
// MARK: - ModifyMovementSpeedMultiplier
|
// MARK: - ModifyMovementSpeedMultiplier
|
||||||
GameInteractionEffectQueryResult ModifyMovementSpeedMultiplier::CanBeApplied() {
|
GameInteractionEffectQueryResult ModifyMovementSpeedMultiplier::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -393,7 +393,7 @@ void ModifyMovementSpeedMultiplier::_Remove() {
|
||||||
|
|
||||||
// MARK: - OneHitKO
|
// MARK: - OneHitKO
|
||||||
GameInteractionEffectQueryResult OneHitKO::CanBeApplied() {
|
GameInteractionEffectQueryResult OneHitKO::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -408,7 +408,7 @@ void OneHitKO::_Remove() {
|
||||||
|
|
||||||
// MARK: - ModifyDefenseModifier
|
// MARK: - ModifyDefenseModifier
|
||||||
GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() {
|
GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -423,7 +423,7 @@ void ModifyDefenseModifier::_Remove() {
|
||||||
|
|
||||||
// MARK: - GiveOrTakeShield
|
// MARK: - GiveOrTakeShield
|
||||||
GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() {
|
GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) &
|
} else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) &
|
||||||
gSaveContext.inventory.equipment)) ||
|
gSaveContext.inventory.equipment)) ||
|
||||||
|
@ -441,7 +441,7 @@ void GiveOrTakeShield::_Apply() {
|
||||||
|
|
||||||
// MARK: - TeleportPlayer
|
// MARK: - TeleportPlayer
|
||||||
GameInteractionEffectQueryResult TeleportPlayer::CanBeApplied() {
|
GameInteractionEffectQueryResult TeleportPlayer::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -453,7 +453,7 @@ void TeleportPlayer::_Apply() {
|
||||||
|
|
||||||
// MARK: - ClearAssignedButtons
|
// MARK: - ClearAssignedButtons
|
||||||
GameInteractionEffectQueryResult ClearAssignedButtons::CanBeApplied() {
|
GameInteractionEffectQueryResult ClearAssignedButtons::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -465,7 +465,7 @@ void ClearAssignedButtons::_Apply() {
|
||||||
|
|
||||||
// MARK: - SetTimeOfDay
|
// MARK: - SetTimeOfDay
|
||||||
GameInteractionEffectQueryResult SetTimeOfDay::CanBeApplied() {
|
GameInteractionEffectQueryResult SetTimeOfDay::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -477,7 +477,7 @@ void SetTimeOfDay::_Apply() {
|
||||||
|
|
||||||
// MARK: - SetCollisionViewer
|
// MARK: - SetCollisionViewer
|
||||||
GameInteractionEffectQueryResult SetCollisionViewer::CanBeApplied() {
|
GameInteractionEffectQueryResult SetCollisionViewer::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -492,7 +492,7 @@ void SetCollisionViewer::_Remove() {
|
||||||
|
|
||||||
// MARK: - RandomizeCosmetics
|
// MARK: - RandomizeCosmetics
|
||||||
GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() {
|
GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -504,7 +504,7 @@ void RandomizeCosmetics::_Apply() {
|
||||||
|
|
||||||
// MARK: - PressButton
|
// MARK: - PressButton
|
||||||
GameInteractionEffectQueryResult PressButton::CanBeApplied() {
|
GameInteractionEffectQueryResult PressButton::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -516,7 +516,7 @@ void PressButton::_Apply() {
|
||||||
|
|
||||||
// MARK: - PressRandomButton
|
// MARK: - PressRandomButton
|
||||||
GameInteractionEffectQueryResult PressRandomButton::CanBeApplied() {
|
GameInteractionEffectQueryResult PressRandomButton::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -528,7 +528,7 @@ void PressRandomButton::_Apply() {
|
||||||
|
|
||||||
// MARK: - AddOrTakeAmmo
|
// MARK: - AddOrTakeAmmo
|
||||||
GameInteractionEffectQueryResult AddOrTakeAmmo::CanBeApplied() {
|
GameInteractionEffectQueryResult AddOrTakeAmmo::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if (!GameInteractor::CanAddOrTakeAmmo(parameters[0], parameters[1])) {
|
} else if (!GameInteractor::CanAddOrTakeAmmo(parameters[0], parameters[1])) {
|
||||||
return GameInteractionEffectQueryResult::NotPossible;
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
|
@ -542,7 +542,7 @@ void AddOrTakeAmmo::_Apply() {
|
||||||
|
|
||||||
// MARK: - RandomBombFuseTimer
|
// MARK: - RandomBombFuseTimer
|
||||||
GameInteractionEffectQueryResult RandomBombFuseTimer::CanBeApplied() {
|
GameInteractionEffectQueryResult RandomBombFuseTimer::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -557,7 +557,7 @@ void RandomBombFuseTimer::_Remove() {
|
||||||
|
|
||||||
// MARK: - DisableLedgeGrabs
|
// MARK: - DisableLedgeGrabs
|
||||||
GameInteractionEffectQueryResult DisableLedgeGrabs::CanBeApplied() {
|
GameInteractionEffectQueryResult DisableLedgeGrabs::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -572,7 +572,7 @@ void DisableLedgeGrabs::_Remove() {
|
||||||
|
|
||||||
// MARK: - RandomWind
|
// MARK: - RandomWind
|
||||||
GameInteractionEffectQueryResult RandomWind::CanBeApplied() {
|
GameInteractionEffectQueryResult RandomWind::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -587,7 +587,7 @@ void RandomWind::_Remove() {
|
||||||
|
|
||||||
// MARK: - RandomBonks
|
// MARK: - RandomBonks
|
||||||
GameInteractionEffectQueryResult RandomBonks::CanBeApplied() {
|
GameInteractionEffectQueryResult RandomBonks::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -602,7 +602,7 @@ void RandomBonks::_Remove() {
|
||||||
|
|
||||||
// MARK: - PlayerInvincibility
|
// MARK: - PlayerInvincibility
|
||||||
GameInteractionEffectQueryResult PlayerInvincibility::CanBeApplied() {
|
GameInteractionEffectQueryResult PlayerInvincibility::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -617,7 +617,7 @@ void PlayerInvincibility::_Remove() {
|
||||||
|
|
||||||
// MARK: - SlipperyFloor
|
// MARK: - SlipperyFloor
|
||||||
GameInteractionEffectQueryResult SlipperyFloor::CanBeApplied() {
|
GameInteractionEffectQueryResult SlipperyFloor::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
@ -632,7 +632,7 @@ void SlipperyFloor::_Remove() {
|
||||||
|
|
||||||
// MARK: - SpawnEnemyWithOffset
|
// MARK: - SpawnEnemyWithOffset
|
||||||
GameInteractionEffectQueryResult SpawnEnemyWithOffset::CanBeApplied() {
|
GameInteractionEffectQueryResult SpawnEnemyWithOffset::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
}
|
}
|
||||||
return GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]);
|
return GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]);
|
||||||
|
@ -644,7 +644,7 @@ void SpawnEnemyWithOffset::_Apply() {
|
||||||
|
|
||||||
// MARK: - SpawnActor
|
// MARK: - SpawnActor
|
||||||
GameInteractionEffectQueryResult SpawnActor::CanBeApplied() {
|
GameInteractionEffectQueryResult SpawnActor::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
}
|
}
|
||||||
return GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]);
|
return GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]);
|
||||||
|
|
|
@ -2225,6 +2225,20 @@ typedef enum {
|
||||||
|
|
||||||
// #### `result`
|
// #### `result`
|
||||||
// ```c
|
// ```c
|
||||||
|
// DoorWarp1_PlayerInRange(this, play)
|
||||||
|
// ```
|
||||||
|
// #### `args`
|
||||||
|
// - `*DoorWarp1`
|
||||||
|
VB_BLUE_WARP_CONSIDER_ADULT_IN_RANGE,
|
||||||
|
|
||||||
|
// #### `result`
|
||||||
|
// ```c
|
||||||
|
// (CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowIngameTimer"), 0) && gSaveContext.fileNum >= 0 && gSaveContext.fileNum
|
||||||
|
// <= 2)
|
||||||
|
// ```
|
||||||
|
// #### `args`
|
||||||
|
// - `*PlayState`
|
||||||
|
VB_SHOW_GAMEPLAY_TIMER,
|
||||||
// (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open &&
|
// (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open &&
|
||||||
// this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100
|
// this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100
|
||||||
// ```
|
// ```
|
||||||
|
|
|
@ -51,9 +51,48 @@ typedef enum {
|
||||||
/* 0xA9 */ TIMESTAMP_DEFEAT_GANON, // z_boss_ganon2.c
|
/* 0xA9 */ TIMESTAMP_DEFEAT_GANON, // z_boss_ganon2.c
|
||||||
/* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c
|
/* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c
|
||||||
/* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c
|
/* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c
|
||||||
/* 0xAA */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c
|
/* 0xAB */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c
|
||||||
/* 0xAB */ TIMESTAMP_MAX
|
/* 0xAC */ TIMESTAMP_FOUND_GOHMA_SOUL,
|
||||||
|
/* 0xAD */ TIMESTAMP_FOUND_KING_DODONGO_SOUL,
|
||||||
|
/* 0xAE */ TIMESTAMP_FOUND_BARINADE_SOUL,
|
||||||
|
/* 0xAF */ TIMESTAMP_FOUND_PHANTOM_GANON_SOUL,
|
||||||
|
/* 0xB0 */ TIMESTAMP_FOUND_VOLVAGIA_SOUL,
|
||||||
|
/* 0xB1 */ TIMESTAMP_FOUND_MORPHA_SOUL,
|
||||||
|
/* 0xB2 */ TIMESTAMP_FOUND_BONGO_BONGO_SOUL,
|
||||||
|
/* 0xB3 */ TIMESTAMP_FOUND_TWINROVA_SOUL,
|
||||||
|
/* 0xB5 */ TIMESTAMP_FOUND_GANON_SOUL,
|
||||||
|
/* 0xB6 */ TIMESTAMP_FOUND_BRONZE_SCALE,
|
||||||
|
/* 0xB7 */ TIMESTAMP_FOUND_OCARINA_A_BUTTON,
|
||||||
|
/* 0xB8 */ TIMESTAMP_FOUND_OCARINA_C_UP_BUTTON,
|
||||||
|
/* 0xB9 */ TIMESTAMP_FOUND_OCARINA_C_DOWN_BUTTON,
|
||||||
|
/* 0xBA */ TIMESTAMP_FOUND_OCARINA_C_LEFT_BUTTON,
|
||||||
|
/* 0xBB */ TIMESTAMP_FOUND_OCARINA_C_RIGHT_BUTTON,
|
||||||
|
/* 0xBC */ TIMESTAMP_FOUND_FISHING_POLE,
|
||||||
|
/* 0xBD */ TIMESTAMP_FOUND_GUARD_HOUSE_KEY,
|
||||||
|
/* 0xBE */ TIMESTAMP_FOUND_MARKET_BAZAAR_KEY,
|
||||||
|
/* 0xBF */ TIMESTAMP_FOUND_MARKET_POTION_SHOP_KEY,
|
||||||
|
/* 0xC0 */ TIMESTAMP_FOUND_MASK_SHOP_KEY,
|
||||||
|
/* 0xC1 */ TIMESTAMP_FOUND_MARKET_SHOOTING_GALLERY_KEY,
|
||||||
|
/* 0xC2 */ TIMESTAMP_FOUND_BOMBCHU_BOWLING_KEY,
|
||||||
|
/* 0xC3 */ TIMESTAMP_FOUND_TREASURE_CHEST_GAME_BUILDING_KEY,
|
||||||
|
/* 0xC4 */ TIMESTAMP_FOUND_BOMBCHU_SHOP_KEY,
|
||||||
|
/* 0xC5 */ TIMESTAMP_FOUND_RICHARDS_HOUSE_KEY,
|
||||||
|
/* 0xC6 */ TIMESTAMP_FOUND_ALLEY_HOUSE_KEY,
|
||||||
|
/* 0xC7 */ TIMESTAMP_FOUND_KAK_BAZAAR_KEY,
|
||||||
|
/* 0xC8 */ TIMESTAMP_FOUND_KAK_POTION_SHOP_KEY,
|
||||||
|
/* 0xC9 */ TIMESTAMP_FOUND_BOSS_HOUSE_KEY,
|
||||||
|
/* 0xCA */ TIMESTAMP_FOUND_GRANNYS_POTION_SHOP_KEY,
|
||||||
|
/* 0xCB */ TIMESTAMP_FOUND_SKULLTULA_HOUSE_KEY,
|
||||||
|
/* 0xCC */ TIMESTAMP_FOUND_IMPAS_HOUSE_KEY,
|
||||||
|
/* 0xCD */ TIMESTAMP_FOUND_WINDMILL_KEY,
|
||||||
|
/* 0xCE */ TIMESTAMP_FOUND_KAK_SHOOTING_GALLERY_KEY,
|
||||||
|
/* 0xCF */ TIMESTAMP_FOUND_DAMPES_HUT_KEY,
|
||||||
|
/* 0xD0 */ TIMESTAMP_FOUND_TALONS_HOUSE_KEY,
|
||||||
|
/* 0xD1 */ TIMESTAMP_FOUND_STABLES_KEY,
|
||||||
|
/* 0xD2 */ TIMESTAMP_FOUND_BACK_TOWER_KEY,
|
||||||
|
/* 0xD3 */ TIMESTAMP_FOUND_HYLIA_LAB_KEY,
|
||||||
|
/* 0xD4 */ TIMESTAMP_FOUND_FISHING_HOLE_KEY,
|
||||||
|
/* 0xD5 */ TIMESTAMP_MAX
|
||||||
} GameplayStatTimestamp;
|
} GameplayStatTimestamp;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "soh/SaveManager.h"
|
#include "soh/SaveManager.h"
|
||||||
#include "soh/ResourceManagerHelpers.h"
|
#include "soh/ResourceManagerHelpers.h"
|
||||||
#include "soh/resource/type/Skeleton.h"
|
#include "soh/resource/type/Skeleton.h"
|
||||||
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
|
|
||||||
#include "soh/Enhancements/boss-rush/BossRush.h"
|
#include "soh/Enhancements/boss-rush/BossRush.h"
|
||||||
#include "soh/Enhancements/enhancementTypes.h"
|
#include "soh/Enhancements/enhancementTypes.h"
|
||||||
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
||||||
|
@ -49,7 +48,6 @@ extern "C" {
|
||||||
|
|
||||||
extern SaveContext gSaveContext;
|
extern SaveContext gSaveContext;
|
||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
extern void Overlay_DisplayText(float duration, const char* text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GreyScaleEndDlist
|
// GreyScaleEndDlist
|
||||||
|
@ -131,10 +129,27 @@ void RegisterOcarinaTimeTravel() {
|
||||||
bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime &&
|
bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime &&
|
||||||
!nearbyFrogs && !nearbyGossipStone;
|
!nearbyFrogs && !nearbyGossipStone;
|
||||||
bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
|
bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
|
||||||
bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2;
|
|
||||||
bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
|
bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
|
||||||
// TODO: Once Swordless Adult is fixed: Remove the Master Sword check
|
int timeTravelSetting = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0);
|
||||||
if (justPlayedSoT && notNearAnySource && (hasOcarinaOfTime || doesntNeedOcarinaOfTime) && hasMasterSword) {
|
bool meetsTimeTravelRequirements = false;
|
||||||
|
|
||||||
|
switch (timeTravelSetting) {
|
||||||
|
case TIME_TRAVEL_ANY:
|
||||||
|
meetsTimeTravelRequirements = true;
|
||||||
|
break;
|
||||||
|
case TIME_TRAVEL_ANY_MS:
|
||||||
|
meetsTimeTravelRequirements = hasMasterSword;
|
||||||
|
break;
|
||||||
|
case TIME_TRAVEL_OOT_MS:
|
||||||
|
meetsTimeTravelRequirements = hasMasterSword && hasOcarinaOfTime;
|
||||||
|
break;
|
||||||
|
case TIME_TRAVEL_OOT:
|
||||||
|
default:
|
||||||
|
meetsTimeTravelRequirements = hasOcarinaOfTime;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (justPlayedSoT && notNearAnySource && meetsTimeTravelRequirements) {
|
||||||
SwitchAge();
|
SwitchAge();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -283,49 +298,6 @@ void UpdateHyperEnemiesState() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterBonkDamage() {
|
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerBonk>([]() {
|
|
||||||
uint8_t bonkOption = CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE);
|
|
||||||
if (bonkOption == BONK_DAMAGE_NONE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bonkOption == BONK_DAMAGE_OHKO) {
|
|
||||||
gSaveContext.health = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t bonkDamage = 0;
|
|
||||||
switch (bonkOption) {
|
|
||||||
case BONK_DAMAGE_QUARTER_HEART:
|
|
||||||
bonkDamage = 4;
|
|
||||||
break;
|
|
||||||
case BONK_DAMAGE_HALF_HEART:
|
|
||||||
bonkDamage = 8;
|
|
||||||
break;
|
|
||||||
case BONK_DAMAGE_1_HEART:
|
|
||||||
bonkDamage = 16;
|
|
||||||
break;
|
|
||||||
case BONK_DAMAGE_2_HEARTS:
|
|
||||||
bonkDamage = 32;
|
|
||||||
break;
|
|
||||||
case BONK_DAMAGE_4_HEARTS:
|
|
||||||
bonkDamage = 64;
|
|
||||||
break;
|
|
||||||
case BONK_DAMAGE_8_HEARTS:
|
|
||||||
bonkDamage = 128;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Health_ChangeBy(gPlayState, -bonkDamage);
|
|
||||||
// Set invincibility to make Link flash red as a visual damage indicator.
|
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
|
||||||
player->invincibilityTimer = 28;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateDirtPathFixState(int32_t sceneNum) {
|
void UpdateDirtPathFixState(int32_t sceneNum) {
|
||||||
switch (sceneNum) {
|
switch (sceneNum) {
|
||||||
case SCENE_HYRULE_FIELD:
|
case SCENE_HYRULE_FIELD:
|
||||||
|
@ -957,7 +929,6 @@ void RegisterCustomSkeletons() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitMods() {
|
void InitMods() {
|
||||||
BossRush_RegisterHooks();
|
|
||||||
RandomizerRegisterHooks();
|
RandomizerRegisterHooks();
|
||||||
TimeSaverRegisterHooks();
|
TimeSaverRegisterHooks();
|
||||||
RegisterTTS();
|
RegisterTTS();
|
||||||
|
@ -966,7 +937,6 @@ void InitMods() {
|
||||||
RegisterDeleteFileOnDeath();
|
RegisterDeleteFileOnDeath();
|
||||||
RegisterHyperBosses();
|
RegisterHyperBosses();
|
||||||
UpdateHyperEnemiesState();
|
UpdateHyperEnemiesState();
|
||||||
RegisterBonkDamage();
|
|
||||||
RegisterMenuPathFix();
|
RegisterMenuPathFix();
|
||||||
RegisterMirrorModeHandler();
|
RegisterMirrorModeHandler();
|
||||||
RegisterResetNaviTimer();
|
RegisterResetNaviTimer();
|
||||||
|
|
|
@ -336,7 +336,7 @@ void Rando::StaticData::RegisterCrateLocations() {
|
||||||
locationTable[RC_GF_SOUTHMOST_CENTER_CRATE] = Location::Crate(RC_GF_SOUTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(315, -1534), "Southmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTHMOST_CENTER_CRATE));
|
locationTable[RC_GF_SOUTHMOST_CENTER_CRATE] = Location::Crate(RC_GF_SOUTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(315, -1534), "Southmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTHMOST_CENTER_CRATE));
|
||||||
locationTable[RC_GF_MID_SOUTH_CENTER_CRATE] = Location::Crate(RC_GF_MID_SOUTH_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(315, -1594), "Middle South Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_MID_SOUTH_CENTER_CRATE));
|
locationTable[RC_GF_MID_SOUTH_CENTER_CRATE] = Location::Crate(RC_GF_MID_SOUTH_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(315, -1594), "Middle South Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_MID_SOUTH_CENTER_CRATE));
|
||||||
locationTable[RC_GF_MID_NORTH_CENTER_CRATE] = Location::Crate(RC_GF_MID_NORTH_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1782), "Middle North Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_MID_NORTH_CENTER_CRATE));
|
locationTable[RC_GF_MID_NORTH_CENTER_CRATE] = Location::Crate(RC_GF_MID_NORTH_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1782), "Middle North Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_MID_NORTH_CENTER_CRATE));
|
||||||
locationTable[RR_GF_NORTHMOST_CENTER_CRATE] = Location::Crate(RR_GF_NORTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1842), "Northmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTHMOST_CENTER_CRATE));
|
locationTable[RC_GF_NORTHMOST_CENTER_CRATE] = Location::Crate(RC_GF_NORTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1842), "Northmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTHMOST_CENTER_CRATE));
|
||||||
locationTable[RC_GF_OUTSKIRTS_NE_CRATE] = Location::Crate(RC_GF_OUTSKIRTS_NE_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-60, -2210), "Outskirts Northeast Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_OUTSKIRTS_NE_CRATE));
|
locationTable[RC_GF_OUTSKIRTS_NE_CRATE] = Location::Crate(RC_GF_OUTSKIRTS_NE_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-60, -2210), "Outskirts Northeast Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_OUTSKIRTS_NE_CRATE));
|
||||||
locationTable[RC_GF_OUTSKIRTS_NW_CRATE] = Location::Crate(RC_GF_OUTSKIRTS_NW_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-120, -2210), "Outskirts Northwest Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_OUTSKIRTS_NW_CRATE));
|
locationTable[RC_GF_OUTSKIRTS_NW_CRATE] = Location::Crate(RC_GF_OUTSKIRTS_NW_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-120, -2210), "Outskirts Northwest Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_OUTSKIRTS_NW_CRATE));
|
||||||
locationTable[RC_GF_HBA_RANGE_CRATE_2] = Location::Crate(RC_GF_HBA_RANGE_CRATE_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(4090, -1780), "Horseback Archery Range Crate 2", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_HBA_RANGE_CRATE_2));
|
locationTable[RC_GF_HBA_RANGE_CRATE_2] = Location::Crate(RC_GF_HBA_RANGE_CRATE_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(4090, -1780), "Horseback Archery Range Crate 2", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_HBA_RANGE_CRATE_2));
|
||||||
|
|
|
@ -30,7 +30,7 @@ void RegionTable_Init_GerudoFortress() {
|
||||||
LOCATION(RC_GF_SOUTHMOST_CENTER_CRATE, logic->CanBreakCrates()),
|
LOCATION(RC_GF_SOUTHMOST_CENTER_CRATE, logic->CanBreakCrates()),
|
||||||
LOCATION(RC_GF_MID_SOUTH_CENTER_CRATE, logic->CanBreakCrates()),
|
LOCATION(RC_GF_MID_SOUTH_CENTER_CRATE, logic->CanBreakCrates()),
|
||||||
LOCATION(RC_GF_MID_NORTH_CENTER_CRATE, logic->CanBreakCrates()),
|
LOCATION(RC_GF_MID_NORTH_CENTER_CRATE, logic->CanBreakCrates()),
|
||||||
LOCATION(RR_GF_NORTHMOST_CENTER_CRATE, logic->CanBreakCrates()),
|
LOCATION(RC_GF_NORTHMOST_CENTER_CRATE, logic->CanBreakCrates()),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_TH_1_TORCH_CELL, []{return true;}),
|
Entrance(RR_TH_1_TORCH_CELL, []{return true;}),
|
||||||
|
|
|
@ -2332,7 +2332,7 @@ std::map<RandomizerCheck, RandomizerInf> rcToRandomizerInf = {
|
||||||
RAND_INF_GF_MID_NORTH_CENTER_CRATE,
|
RAND_INF_GF_MID_NORTH_CENTER_CRATE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
RR_GF_NORTHMOST_CENTER_CRATE,
|
RC_GF_NORTHMOST_CENTER_CRATE,
|
||||||
RAND_INF_GF_NORTHMOST_CENTER_CRATE,
|
RAND_INF_GF_NORTHMOST_CENTER_CRATE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -5783,6 +5783,53 @@ void RandomizerSettingsWindow::InitElement() {
|
||||||
mSettings->UpdateOptionProperties();
|
mSettings->UpdateOptionProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::unordered_map<RandomizerGet, GameplayStatTimestamp> randomizerGetToStatsTimeStamp = {
|
||||||
|
{ RG_GOHMA_SOUL, TIMESTAMP_FOUND_GOHMA_SOUL },
|
||||||
|
{ RG_KING_DODONGO_SOUL, TIMESTAMP_FOUND_KING_DODONGO_SOUL },
|
||||||
|
{ RG_BARINADE_SOUL, TIMESTAMP_FOUND_BARINADE_SOUL },
|
||||||
|
{ RG_PHANTOM_GANON_SOUL, TIMESTAMP_FOUND_PHANTOM_GANON_SOUL },
|
||||||
|
{ RG_VOLVAGIA_SOUL, TIMESTAMP_FOUND_VOLVAGIA_SOUL },
|
||||||
|
{ RG_MORPHA_SOUL, TIMESTAMP_FOUND_MORPHA_SOUL },
|
||||||
|
{ RG_BONGO_BONGO_SOUL, TIMESTAMP_FOUND_BONGO_BONGO_SOUL },
|
||||||
|
{ RG_TWINROVA_SOUL, TIMESTAMP_FOUND_TWINROVA_SOUL },
|
||||||
|
{ RG_GANON_SOUL, TIMESTAMP_FOUND_GANON_SOUL },
|
||||||
|
|
||||||
|
{ RG_BRONZE_SCALE, TIMESTAMP_FOUND_BRONZE_SCALE },
|
||||||
|
|
||||||
|
{ RG_OCARINA_A_BUTTON, TIMESTAMP_FOUND_OCARINA_A_BUTTON },
|
||||||
|
{ RG_OCARINA_C_UP_BUTTON, TIMESTAMP_FOUND_OCARINA_C_UP_BUTTON },
|
||||||
|
{ RG_OCARINA_C_DOWN_BUTTON, TIMESTAMP_FOUND_OCARINA_C_DOWN_BUTTON },
|
||||||
|
{ RG_OCARINA_C_LEFT_BUTTON, TIMESTAMP_FOUND_OCARINA_C_LEFT_BUTTON },
|
||||||
|
{ RG_OCARINA_C_RIGHT_BUTTON, TIMESTAMP_FOUND_OCARINA_C_RIGHT_BUTTON },
|
||||||
|
|
||||||
|
{ RG_FISHING_POLE, TIMESTAMP_FOUND_FISHING_POLE },
|
||||||
|
|
||||||
|
{ RG_GUARD_HOUSE_KEY, TIMESTAMP_FOUND_GUARD_HOUSE_KEY },
|
||||||
|
{ RG_MARKET_BAZAAR_KEY, TIMESTAMP_FOUND_MARKET_BAZAAR_KEY },
|
||||||
|
{ RG_MARKET_POTION_SHOP_KEY, TIMESTAMP_FOUND_MARKET_POTION_SHOP_KEY },
|
||||||
|
{ RG_MASK_SHOP_KEY, TIMESTAMP_FOUND_MASK_SHOP_KEY },
|
||||||
|
{ RG_MARKET_SHOOTING_GALLERY_KEY, TIMESTAMP_FOUND_MARKET_SHOOTING_GALLERY_KEY },
|
||||||
|
{ RG_BOMBCHU_BOWLING_KEY, TIMESTAMP_FOUND_BOMBCHU_BOWLING_KEY },
|
||||||
|
{ RG_TREASURE_CHEST_GAME_BUILDING_KEY, TIMESTAMP_FOUND_TREASURE_CHEST_GAME_BUILDING_KEY },
|
||||||
|
{ RG_BOMBCHU_SHOP_KEY, TIMESTAMP_FOUND_BOMBCHU_SHOP_KEY },
|
||||||
|
{ RG_RICHARDS_HOUSE_KEY, TIMESTAMP_FOUND_RICHARDS_HOUSE_KEY },
|
||||||
|
{ RG_ALLEY_HOUSE_KEY, TIMESTAMP_FOUND_ALLEY_HOUSE_KEY },
|
||||||
|
{ RG_KAK_BAZAAR_KEY, TIMESTAMP_FOUND_KAK_BAZAAR_KEY },
|
||||||
|
{ RG_KAK_POTION_SHOP_KEY, TIMESTAMP_FOUND_KAK_POTION_SHOP_KEY },
|
||||||
|
{ RG_BOSS_HOUSE_KEY, TIMESTAMP_FOUND_BOSS_HOUSE_KEY },
|
||||||
|
{ RG_GRANNYS_POTION_SHOP_KEY, TIMESTAMP_FOUND_GRANNYS_POTION_SHOP_KEY },
|
||||||
|
{ RG_SKULLTULA_HOUSE_KEY, TIMESTAMP_FOUND_SKULLTULA_HOUSE_KEY },
|
||||||
|
{ RG_IMPAS_HOUSE_KEY, TIMESTAMP_FOUND_IMPAS_HOUSE_KEY },
|
||||||
|
{ RG_WINDMILL_KEY, TIMESTAMP_FOUND_WINDMILL_KEY },
|
||||||
|
{ RG_KAK_SHOOTING_GALLERY_KEY, TIMESTAMP_FOUND_KAK_SHOOTING_GALLERY_KEY },
|
||||||
|
{ RG_DAMPES_HUT_KEY, TIMESTAMP_FOUND_DAMPES_HUT_KEY },
|
||||||
|
{ RG_TALONS_HOUSE_KEY, TIMESTAMP_FOUND_TALONS_HOUSE_KEY },
|
||||||
|
{ RG_STABLES_KEY, TIMESTAMP_FOUND_STABLES_KEY },
|
||||||
|
{ RG_BACK_TOWER_KEY, TIMESTAMP_FOUND_BACK_TOWER_KEY },
|
||||||
|
{ RG_HYLIA_LAB_KEY, TIMESTAMP_FOUND_HYLIA_LAB_KEY },
|
||||||
|
{ RG_FISHING_HOLE_KEY, TIMESTAMP_FOUND_FISHING_HOLE_KEY },
|
||||||
|
};
|
||||||
|
|
||||||
// Gameplay stat tracking: Update time the item was acquired
|
// Gameplay stat tracking: Update time the item was acquired
|
||||||
// (special cases for rando items)
|
// (special cases for rando items)
|
||||||
void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
|
void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
|
||||||
|
@ -5797,6 +5844,12 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
|
||||||
// Use ITEM_KEY_BOSS to timestamp Ganon's boss key
|
// Use ITEM_KEY_BOSS to timestamp Ganon's boss key
|
||||||
if (item == RG_GANONS_CASTLE_BOSS_KEY) {
|
if (item == RG_GANONS_CASTLE_BOSS_KEY) {
|
||||||
gSaveContext.ship.stats.itemTimestamp[ITEM_KEY_BOSS] = time;
|
gSaveContext.ship.stats.itemTimestamp[ITEM_KEY_BOSS] = time;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (randomizerGetToStatsTimeStamp.contains((RandomizerGet)item)) {
|
||||||
|
gSaveContext.ship.stats.itemTimestamp[randomizerGetToStatsTimeStamp[(RandomizerGet)item]] = time;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count any bottled item as a bottle
|
// Count any bottled item as a bottle
|
||||||
|
@ -5806,6 +5859,7 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count any bombchu pack as bombchus
|
// Count any bombchu pack as bombchus
|
||||||
if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) {
|
if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) {
|
||||||
if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = 0) {
|
if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = 0) {
|
||||||
|
@ -5813,11 +5867,15 @@ void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item == RG_MAGIC_SINGLE) {
|
if (item == RG_MAGIC_SINGLE) {
|
||||||
gSaveContext.ship.stats.itemTimestamp[ITEM_SINGLE_MAGIC] = time;
|
gSaveContext.ship.stats.itemTimestamp[ITEM_SINGLE_MAGIC] = time;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item == RG_DOUBLE_DEFENSE) {
|
if (item == RG_DOUBLE_DEFENSE) {
|
||||||
gSaveContext.ship.stats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time;
|
gSaveContext.ship.stats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2396,7 +2396,7 @@ typedef enum {
|
||||||
RC_GF_SOUTHMOST_CENTER_CRATE,
|
RC_GF_SOUTHMOST_CENTER_CRATE,
|
||||||
RC_GF_MID_SOUTH_CENTER_CRATE,
|
RC_GF_MID_SOUTH_CENTER_CRATE,
|
||||||
RC_GF_MID_NORTH_CENTER_CRATE,
|
RC_GF_MID_NORTH_CENTER_CRATE,
|
||||||
RR_GF_NORTHMOST_CENTER_CRATE,
|
RC_GF_NORTHMOST_CENTER_CRATE,
|
||||||
RC_GF_OUTSKIRTS_NE_CRATE,
|
RC_GF_OUTSKIRTS_NE_CRATE,
|
||||||
RC_GF_OUTSKIRTS_NW_CRATE,
|
RC_GF_OUTSKIRTS_NW_CRATE,
|
||||||
RC_GF_HBA_RANGE_CRATE_1,
|
RC_GF_HBA_RANGE_CRATE_1,
|
||||||
|
|
|
@ -449,7 +449,8 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) {
|
||||||
result.currentCapacity =
|
result.currentCapacity =
|
||||||
IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET);
|
IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET);
|
||||||
result.maxCapacity =
|
result.maxCapacity =
|
||||||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999 : 500;
|
IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999
|
||||||
|
: 500;
|
||||||
result.currentAmmo = gSaveContext.rupees;
|
result.currentAmmo = gSaveContext.rupees;
|
||||||
break;
|
break;
|
||||||
case ITEM_BOMBCHU:
|
case ITEM_BOMBCHU:
|
||||||
|
@ -502,7 +503,28 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) {
|
||||||
result.maxCapacity = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX;
|
result.maxCapacity = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX;
|
||||||
break;
|
break;
|
||||||
case SCENE_THIEVES_HIDEOUT:
|
case SCENE_THIEVES_HIDEOUT:
|
||||||
result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX;
|
if (IS_RANDO) {
|
||||||
|
switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)) {
|
||||||
|
case RO_GF_CARPENTERS_NORMAL:
|
||||||
|
result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX;
|
||||||
|
break;
|
||||||
|
case RO_GF_CARPENTERS_FAST:
|
||||||
|
result.maxCapacity = 1;
|
||||||
|
break;
|
||||||
|
case RO_GF_CARPENTERS_FREE:
|
||||||
|
result.maxCapacity = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result.maxCapacity = 0;
|
||||||
|
SPDLOG_ERROR(
|
||||||
|
"Invalid value for RSK_GERUDO_FORTRESS: " +
|
||||||
|
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS));
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCENE_INSIDE_GANONS_CASTLE:
|
case SCENE_INSIDE_GANONS_CASTLE:
|
||||||
result.maxCapacity = GANONS_CASTLE_SMALL_KEY_MAX;
|
result.maxCapacity = GANONS_CASTLE_SMALL_KEY_MAX;
|
||||||
|
|
|
@ -2600,15 +2600,6 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Overlay_DisplayText(float duration, const char* text) {
|
|
||||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(duration, true, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void Overlay_DisplayText_Seconds(int seconds, const char* text) {
|
|
||||||
float duration = seconds * OTRGlobals::Instance->GetInterpolationFPS() * 0.05;
|
|
||||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(duration, true, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex) {
|
extern "C" void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex) {
|
||||||
SetCurrentGrottoIDForTracker(entranceIndex);
|
SetCurrentGrottoIDForTracker(entranceIndex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,8 +156,6 @@ void Randomizer_SetSpoilerLoaded(bool spoilerLoaded);
|
||||||
uint8_t Randomizer_GenerateRandomizer();
|
uint8_t Randomizer_GenerateRandomizer();
|
||||||
void Randomizer_ShowRandomizerMenu();
|
void Randomizer_ShowRandomizerMenu();
|
||||||
int CustomMessage_RetrieveIfExists(PlayState* play);
|
int CustomMessage_RetrieveIfExists(PlayState* play);
|
||||||
void Overlay_DisplayText(float duration, const char* text);
|
|
||||||
void Overlay_DisplayText_Seconds(int seconds, const char* text);
|
|
||||||
GetItemEntry ItemTable_Retrieve(int16_t getItemID);
|
GetItemEntry ItemTable_Retrieve(int16_t getItemID);
|
||||||
GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID);
|
GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID);
|
||||||
void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex);
|
void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex);
|
||||||
|
|
|
@ -56,7 +56,9 @@ static const std::unordered_map<int32_t, const char*> chestStyleMatchesContentsO
|
||||||
static const std::unordered_map<int32_t, const char*> timeTravelOptions = {
|
static const std::unordered_map<int32_t, const char*> timeTravelOptions = {
|
||||||
{ TIME_TRAVEL_DISABLED, "Disabled" },
|
{ TIME_TRAVEL_DISABLED, "Disabled" },
|
||||||
{ TIME_TRAVEL_OOT, "Ocarina of Time" },
|
{ TIME_TRAVEL_OOT, "Ocarina of Time" },
|
||||||
|
{ TIME_TRAVEL_OOT_MS, "Ocarina of Time + Master Sword" },
|
||||||
{ TIME_TRAVEL_ANY, "Any Ocarina" },
|
{ TIME_TRAVEL_ANY, "Any Ocarina" },
|
||||||
|
{ TIME_TRAVEL_ANY_MS, "Any Ocarina + Master Sword" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::unordered_map<int32_t, const char*> sleepingWaterfallOptions = {
|
static const std::unordered_map<int32_t, const char*> sleepingWaterfallOptions = {
|
||||||
|
@ -783,9 +785,9 @@ void SohMenu::AddMenuEnhancements() {
|
||||||
.Tooltip("Allows Link to freely change age by playing the Song of Time.\n"
|
.Tooltip("Allows Link to freely change age by playing the Song of Time.\n"
|
||||||
"Time Blocks can still be used properly.\n\n"
|
"Time Blocks can still be used properly.\n\n"
|
||||||
"Requirements:\n"
|
"Requirements:\n"
|
||||||
" - Obtained the Ocarina of Time (depends on selection)\n"
|
|
||||||
" - Obtained the Song of Time\n"
|
" - Obtained the Song of Time\n"
|
||||||
" - Obtained the Master Sword\n"
|
" - Obtained the Ocarina of Time (depends on selection)\n"
|
||||||
|
" - Obtained the Master Sword (depends on selection)\n"
|
||||||
" - Not within range of a Time Block\n"
|
" - Not within range of a Time Block\n"
|
||||||
" - Not within range of Ocarina Playing spots"));
|
" - Not within range of Ocarina Playing spots"));
|
||||||
|
|
||||||
|
|
|
@ -640,10 +640,8 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
|
||||||
if (gPlayState != NULL) {
|
if (gPlayState != NULL) {
|
||||||
previousSceneNum = gPlayState->sceneNum;
|
previousSceneNum = gPlayState->sceneNum;
|
||||||
}
|
}
|
||||||
const char* sequenceName = AudioCollection_GetSequenceName(seqId);
|
|
||||||
if (sequenceName != NULL) {
|
AudioCollection_EmitSongNameNotification(seqId);
|
||||||
Overlay_DisplayText_Seconds(CVarGetInteger(CVAR_AUDIO("SeqNameOverlayDuration"), 5), sequenceName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
#include "libultraship/bridge.h"
|
#include "libultraship/bridge.h"
|
||||||
#include "soh/Enhancements/gameplaystats.h"
|
#include "soh/Enhancements/gameplaystats.h"
|
||||||
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
|
|
||||||
#include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h"
|
#include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h"
|
||||||
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
|
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
|
||||||
#include "soh/Enhancements/enhancementTypes.h"
|
#include "soh/Enhancements/enhancementTypes.h"
|
||||||
|
@ -6374,11 +6373,10 @@ void Interface_Draw(PlayState* play) {
|
||||||
|
|
||||||
void Interface_DrawTotalGameplayTimer(PlayState* play) {
|
void Interface_DrawTotalGameplayTimer(PlayState* play) {
|
||||||
// Draw timer based on the Gameplay Stats total time.
|
// Draw timer based on the Gameplay Stats total time.
|
||||||
|
if (GameInteractor_Should(VB_SHOW_GAMEPLAY_TIMER,
|
||||||
if ((IS_BOSS_RUSH && gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_TIMER] == BR_CHOICE_TIMER_YES) ||
|
CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowIngameTimer"), 0) && gSaveContext.fileNum >= 0 &&
|
||||||
(CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowIngameTimer"), 0) && gSaveContext.fileNum >= 0 &&
|
gSaveContext.fileNum <= 2,
|
||||||
gSaveContext.fileNum <= 2)) {
|
play)) {
|
||||||
|
|
||||||
s32 X_Margins_Timer = 0;
|
s32 X_Margins_Timer = 0;
|
||||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.IGT.UseMargins"), 0) != 0) {
|
if (CVarGetInteger(CVAR_COSMETIC("HUD.IGT.UseMargins"), 0) != 0) {
|
||||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.IGT.PosType"), 0) == ORIGINAL_LOCATION) {
|
if (CVarGetInteger(CVAR_COSMETIC("HUD.IGT.PosType"), 0) == ORIGINAL_LOCATION) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "z_door_warp1.h"
|
#include "z_door_warp1.h"
|
||||||
#include "objects/object_warp1/object_warp1.h"
|
#include "objects/object_warp1/object_warp1.h"
|
||||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||||
#include "soh/Enhancements/boss-rush/BossRush.h"
|
|
||||||
#include "soh/OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
|
||||||
|
@ -693,12 +692,7 @@ void DoorWarp1_AdultWarpIdle(DoorWarp1* this, PlayState* play) {
|
||||||
|
|
||||||
Audio_PlayActorSound2(&this->actor, NA_SE_EV_WARP_HOLE - SFX_FLAG);
|
Audio_PlayActorSound2(&this->actor, NA_SE_EV_WARP_HOLE - SFX_FLAG);
|
||||||
|
|
||||||
if (DoorWarp1_PlayerInRange(this, play)) {
|
if (GameInteractor_Should(VB_BLUE_WARP_CONSIDER_ADULT_IN_RANGE, DoorWarp1_PlayerInRange(this, play), this)) {
|
||||||
// Heal player in Boss Rush
|
|
||||||
if (IS_BOSS_RUSH) {
|
|
||||||
BossRush_HandleBlueWarpHeal(play);
|
|
||||||
}
|
|
||||||
|
|
||||||
player = GET_PLAYER(play);
|
player = GET_PLAYER(play);
|
||||||
|
|
||||||
OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM);
|
OnePointCutscene_Init(play, 0x25E8, 999, &this->actor, MAIN_CAM);
|
||||||
|
|
|
@ -1398,110 +1398,6 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static s8 sLastBossRushOptionIndex = -1;
|
|
||||||
static s8 sLastBossRushOptionValue = -1;
|
|
||||||
|
|
||||||
void FileChoose_UpdateBossRushMenu(GameState* thisx) {
|
|
||||||
FileChoose_UpdateStickDirectionPromptAnim(thisx);
|
|
||||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
|
||||||
Input* input = &this->state.input[0];
|
|
||||||
bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0);
|
|
||||||
|
|
||||||
// Fade in elements after opening Boss Rush options menu
|
|
||||||
this->bossRushUIAlpha += 25;
|
|
||||||
if (this->bossRushUIAlpha > 255) {
|
|
||||||
this->bossRushUIAlpha = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animate up/down arrows.
|
|
||||||
this->bossRushArrowOffset += 1;
|
|
||||||
if (this->bossRushArrowOffset >= 30) {
|
|
||||||
this->bossRushArrowOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move menu selection up or down.
|
|
||||||
if (ABS(this->stickRelY) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) {
|
|
||||||
// Move down
|
|
||||||
if (this->stickRelY < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN))) {
|
|
||||||
// When selecting past the last option, cycle back to the first option.
|
|
||||||
if ((this->bossRushIndex + 1) > BR_OPTIONS_MAX - 1) {
|
|
||||||
this->bossRushIndex = 0;
|
|
||||||
this->bossRushOffset = 0;
|
|
||||||
} else {
|
|
||||||
this->bossRushIndex++;
|
|
||||||
// When last visible option is selected when moving down, offset the list down by one.
|
|
||||||
if (this->bossRushIndex - this->bossRushOffset > BOSSRUSH_MAX_OPTIONS_ON_SCREEN - 1) {
|
|
||||||
this->bossRushOffset++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (this->stickRelY > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DUP))) {
|
|
||||||
// When selecting past the first option, cycle back to the last option and offset the list to view it
|
|
||||||
// properly.
|
|
||||||
if ((this->bossRushIndex - 1) < 0) {
|
|
||||||
this->bossRushIndex = BR_OPTIONS_MAX - 1;
|
|
||||||
this->bossRushOffset = this->bossRushIndex - BOSSRUSH_MAX_OPTIONS_ON_SCREEN + 1;
|
|
||||||
} else {
|
|
||||||
// When first visible option is selected when moving up, offset the list up by one.
|
|
||||||
if (this->bossRushIndex - this->bossRushOffset == 0) {
|
|
||||||
this->bossRushOffset--;
|
|
||||||
}
|
|
||||||
this->bossRushIndex--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
|
||||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cycle through choices for currently selected option.
|
|
||||||
if (ABS(this->stickRelX) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) {
|
|
||||||
if (this->stickRelX > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT))) {
|
|
||||||
// If exceeding the amount of choices for the selected option, cycle back to the first.
|
|
||||||
if ((gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] + 1) ==
|
|
||||||
BossRush_GetSettingOptionsAmount(this->bossRushIndex)) {
|
|
||||||
gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] = 0;
|
|
||||||
} else {
|
|
||||||
gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]++;
|
|
||||||
}
|
|
||||||
} else if (this->stickRelX < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT))) {
|
|
||||||
// If cycling back when already at the first choice for the selected option, cycle back to the last choice.
|
|
||||||
if ((gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] - 1) < 0) {
|
|
||||||
gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex] =
|
|
||||||
BossRush_GetSettingOptionsAmount(this->bossRushIndex) - 1;
|
|
||||||
} else {
|
|
||||||
gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
|
||||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sLastBossRushOptionIndex != this->bossRushIndex ||
|
|
||||||
sLastBossRushOptionValue != gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]) {
|
|
||||||
GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(
|
|
||||||
this->bossRushIndex, gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex]);
|
|
||||||
sLastBossRushOptionIndex = this->bossRushIndex;
|
|
||||||
sLastBossRushOptionValue = gSaveContext.ship.quest.data.bossRush.options[this->bossRushIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
|
||||||
this->configMode = CM_BOSS_RUSH_TO_QUEST;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load into the game.
|
|
||||||
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
|
||||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
|
||||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
|
||||||
this->buttonIndex = 0xFE;
|
|
||||||
this->menuMode = FS_MENU_MODE_SELECT;
|
|
||||||
this->selectMode = SM_FADE_OUT;
|
|
||||||
this->prevConfigMode = this->configMode;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileChoose_UpdateRandomizerMenu(GameState* thisx) {
|
void FileChoose_UpdateRandomizerMenu(GameState* thisx) {
|
||||||
FileChoose_UpdateStickDirectionPromptAnim(thisx);
|
FileChoose_UpdateStickDirectionPromptAnim(thisx);
|
||||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||||
|
@ -2590,63 +2486,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (this->configMode == CM_BOSS_RUSH_MENU) {
|
} else if (this->configMode == CM_BOSS_RUSH_MENU) {
|
||||||
uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language;
|
FileChoose_DrawBossRushMenuWindowContents(this);
|
||||||
uint8_t listOffset = this->bossRushOffset;
|
|
||||||
uint8_t textAlpha = this->bossRushUIAlpha;
|
|
||||||
|
|
||||||
// Draw arrows to indicate that the list can scroll up or down.
|
|
||||||
// Arrow up
|
|
||||||
if (listOffset > 0) {
|
|
||||||
uint16_t arrowUpX = 140;
|
|
||||||
uint16_t arrowUpY = 76 - (this->bossRushArrowOffset / 10);
|
|
||||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowUpTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0,
|
|
||||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
|
||||||
G_TX_NOLOD, G_TX_NOLOD);
|
|
||||||
gSPWideTextureRectangle(POLY_OPA_DISP++, arrowUpX << 2, arrowUpY << 2, (arrowUpX + 8) << 2,
|
|
||||||
(arrowUpY + 8) << 2, G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11));
|
|
||||||
}
|
|
||||||
// Arrow down
|
|
||||||
if (BR_OPTIONS_MAX - listOffset > BOSSRUSH_MAX_OPTIONS_ON_SCREEN) {
|
|
||||||
uint16_t arrowDownX = 140;
|
|
||||||
uint16_t arrowDownY = 181 + (this->bossRushArrowOffset / 10);
|
|
||||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowDownTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0,
|
|
||||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
|
||||||
G_TX_NOLOD, G_TX_NOLOD);
|
|
||||||
gSPWideTextureRectangle(POLY_OPA_DISP++, arrowDownX << 2, arrowDownY << 2, (arrowDownX + 8) << 2,
|
|
||||||
(arrowDownY + 8) << 2, G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw options. There's more options than what fits on the screen, so the visible options
|
|
||||||
// depend on the current offset of the list. Currently selected option pulses in
|
|
||||||
// color and has arrows surrounding the option.
|
|
||||||
for (uint8_t i = listOffset; i - listOffset < BOSSRUSH_MAX_OPTIONS_ON_SCREEN; i++) {
|
|
||||||
uint16_t textYOffset = (i - listOffset) * 16;
|
|
||||||
|
|
||||||
// Option name.
|
|
||||||
Interface_DrawTextLine(this->state.gfxCtx, BossRush_GetSettingName(i, language), 65, (87 + textYOffset),
|
|
||||||
255, 255, 80, textAlpha, 0.8f, true);
|
|
||||||
|
|
||||||
// Selected choice for option.
|
|
||||||
uint16_t finalKerning = Interface_DrawTextLine(
|
|
||||||
this->state.gfxCtx,
|
|
||||||
BossRush_GetSettingChoiceName(i, gSaveContext.ship.quest.data.bossRush.options[i], language), 165,
|
|
||||||
(87 + textYOffset), 255, 255, 255, textAlpha, 0.8f, true);
|
|
||||||
|
|
||||||
// Draw arrows around selected option.
|
|
||||||
if (this->bossRushIndex == i) {
|
|
||||||
Gfx_SetupDL_39Opa(this->state.gfxCtx);
|
|
||||||
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
|
||||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0,
|
|
||||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD,
|
|
||||||
G_TX_NOLOD);
|
|
||||||
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.arrowColorR,
|
|
||||||
this->stickLeftPrompt.arrowColorG, this->stickLeftPrompt.arrowColorB, textAlpha,
|
|
||||||
160, (92 + textYOffset), 0.42f, 0, 0, -1.0f, 1.0f);
|
|
||||||
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.arrowColorR,
|
|
||||||
this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB,
|
|
||||||
textAlpha, (171 + finalKerning), (92 + textYOffset), 0.42f, 0, 0, 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (this->configMode == CM_RANDOMIZER_SETTINGS_MENU) {
|
} else if (this->configMode == CM_RANDOMIZER_SETTINGS_MENU) {
|
||||||
uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language;
|
uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language;
|
||||||
uint8_t textAlpha = this->randomizerUIAlpha;
|
uint8_t textAlpha = this->randomizerUIAlpha;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue