Add persistent bunny mask enhancement (#537)

This commit is contained in:
Garrett Cox
2024-08-18 11:41:17 -04:00
committed by GitHub
parent 63ffddb67b
commit 53faf37dc1
13 changed files with 305 additions and 28 deletions
+5
View File
@@ -593,6 +593,11 @@ void DrawEnhancementsMenu() {
UIWidgets::CVarCheckbox("Fierce Deity's Mask Anywhere", "gEnhancements.Masks.FierceDeitysAnywhere",
{ .tooltip = "Allow using Fierce Deity's mask outside of boss rooms." });
UIWidgets::CVarCheckbox("No Blast Mask Cooldown", "gEnhancements.Masks.NoBlastMaskCooldown", {});
if (UIWidgets::CVarCheckbox("Persistent Bunny Hood", "gEnhancements.Masks.PersistentBunnyHood.Enabled",
{ .tooltip = "Permanantly toggle a speed boost from the bunny hood by pressing "
"'A' on it in the mask menu." })) {
UpdatePersistentMasksState();
}
ImGui::EndMenu();
}
+1
View File
@@ -37,6 +37,7 @@ void InitEnhancements() {
RegisterFierceDeityAnywhere();
RegisterBlastMaskKeg();
RegisterNoBlastMaskCooldown();
RegisterPersistentMasks();
// Minigames
RegisterAlwaysWinDoggyRace();
+1
View File
@@ -18,6 +18,7 @@
#include "Masks/FierceDeityAnywhere.h"
#include "Masks/NoBlastMaskCooldown.h"
#include "Masks/FastTransformation.h"
#include "Masks/PersistentMasks.h"
#include "Minigames/AlwaysWinDoggyRace.h"
#include "Cutscenes/Cutscenes.h"
#include "Restorations/FlipHopVariable.h"
@@ -27,6 +27,17 @@ void GameInteractor_ExecuteOnKaleidoUpdate(PauseContext* pauseCtx) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnKaleidoUpdate>(pauseCtx);
}
void GameInteractor_ExecuteBeforeKaleidoDrawPage(PauseContext* pauseCtx, u16 pauseIndex) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::BeforeKaleidoDrawPage>(pauseCtx, pauseIndex);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::BeforeKaleidoDrawPage>(pauseIndex, pauseCtx,
pauseIndex);
}
void GameInteractor_ExecuteAfterKaleidoDrawPage(PauseContext* pauseCtx, u16 pauseIndex) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::AfterKaleidoDrawPage>(pauseCtx, pauseIndex);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::AfterKaleidoDrawPage>(pauseIndex, pauseCtx, pauseIndex);
}
void GameInteractor_ExecuteOnSaveInit(s16 fileNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaveInit>(fileNum);
}
@@ -123,6 +134,12 @@ void GameInteractor_ExecuteOnActorKill(Actor* actor) {
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorKill>(actor);
}
void GameInteractor_ExecuteOnPlayerPostLimbDraw(Player* player, s32 limbIndex) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayerPostLimbDraw>(player, limbIndex);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnPlayerPostLimbDraw>(limbIndex, player, limbIndex);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnPlayerPostLimbDraw>(player, limbIndex);
}
void GameInteractor_ExecuteOnSceneFlagSet(s16 sceneId, FlagType flagType, u32 flag) {
SPDLOG_DEBUG("OnSceneFlagSet: sceneId: {}, flagType: {}, flag: {}", sceneId, (u32)flagType, flag);
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneFlagSet>(sceneId, flagType, flag);
@@ -5,8 +5,6 @@
#include <string>
extern "C" {
#endif
#include "z64actor.h"
#include "z64camera.h"
#include "z64.h"
#ifdef __cplusplus
}
@@ -48,6 +46,11 @@ typedef enum {
GI_VB_SONG_AVAILABLE_TO_PLAY,
GI_VB_USE_CUSTOM_CAMERA,
GI_VB_DELETE_OWL_SAVE,
GI_VB_CONSIDER_BUNNY_HOOD_EQUIPPED,
GI_VB_USE_ITEM_EQUIP_MASK,
GI_VB_KALEIDO_DISPLAY_ITEM_TEXT,
GI_VB_USE_ITEM_CONSIDER_LINK_HUMAN,
GI_VB_DRAW_ITEM_EQUIPPED_OUTLINE,
GI_VB_PLAY_TRANSITION_CS,
GI_VB_TATL_INTERUPT_MSG3,
GI_VB_TATL_INTERUPT_MSG6,
@@ -260,6 +263,8 @@ class GameInteractor {
DEFINE_HOOK(OnGameStateUpdate, ());
DEFINE_HOOK(OnConsoleLogoUpdate, ());
DEFINE_HOOK(OnKaleidoUpdate, (PauseContext * pauseCtx));
DEFINE_HOOK(BeforeKaleidoDrawPage, (PauseContext * pauseCtx, u16 pauseIndex));
DEFINE_HOOK(AfterKaleidoDrawPage, (PauseContext * pauseCtx, u16 pauseIndex));
DEFINE_HOOK(OnSaveInit, (s16 fileNum));
DEFINE_HOOK(BeforeEndOfCycleSave, ());
DEFINE_HOOK(AfterEndOfCycleSave, ());
@@ -277,6 +282,7 @@ class GameInteractor {
DEFINE_HOOK(ShouldActorDraw, (Actor * actor, bool* should));
DEFINE_HOOK(OnActorDraw, (Actor * actor));
DEFINE_HOOK(OnActorKill, (Actor * actor));
DEFINE_HOOK(OnPlayerPostLimbDraw, (Player * player, s32 limbIndex));
DEFINE_HOOK(OnSceneFlagSet, (s16 sceneId, FlagType flagType, u32 flag));
DEFINE_HOOK(OnSceneFlagUnset, (s16 sceneId, FlagType flagType, u32 flag));
@@ -305,6 +311,8 @@ void GameInteractor_ExecuteOnGameStateDrawFinish();
void GameInteractor_ExecuteOnGameStateUpdate();
void GameInteractor_ExecuteOnConsoleLogoUpdate();
void GameInteractor_ExecuteOnKaleidoUpdate(PauseContext* pauseCtx);
void GameInteractor_ExecuteBeforeKaleidoDrawPage(PauseContext* pauseCtx, u16 pauseIndex);
void GameInteractor_ExecuteAfterKaleidoDrawPage(PauseContext* pauseCtx, u16 pauseIndex);
void GameInteractor_ExecuteOnSaveInit(s16 fileNum);
void GameInteractor_ExecuteBeforeEndOfCycleSave();
void GameInteractor_ExecuteAfterEndOfCycleSave();
@@ -322,6 +330,7 @@ void GameInteractor_ExecuteOnActorUpdate(Actor* actor);
bool GameInteractor_ShouldActorDraw(Actor* actor);
void GameInteractor_ExecuteOnActorDraw(Actor* actor);
void GameInteractor_ExecuteOnActorKill(Actor* actor);
void GameInteractor_ExecuteOnPlayerPostLimbDraw(Player* player, s32 limbIndex);
void GameInteractor_ExecuteOnSceneFlagSet(s16 sceneId, FlagType flagType, u32 flag);
void GameInteractor_ExecuteOnSceneFlagUnset(s16 sceneId, FlagType flagType, u32 flag);
@@ -0,0 +1,206 @@
#include <libultraship/bridge.h>
#include <spdlog/spdlog.h>
#include "Enhancements/GameInteractor/GameInteractor.h"
#include "Enhancements/FrameInterpolation/FrameInterpolation.h"
extern "C" {
#include "z64.h"
#include "z64player.h"
#include "functions.h"
#include "macros.h"
#include "gfx.h"
#include "src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
#include "assets/interface/parameter_static/parameter_static.h"
void func_8082E1F0(Player* player, u16 sfxId);
void Player_DrawBunnyHood(PlayState* play);
extern PlayState* gPlayState;
extern const char* D_801C0B20[28];
extern SaveContext gSaveContext;
}
void UpdatePersistentMasksState() {
static Vtx* persistentMasksVtx;
static HOOK_ID beforePageDrawHook = 0;
static HOOK_ID onPlayerPostLimbDrawHook = 0;
GameInteractor::Instance->UnregisterGameHook<GameInteractor::BeforeKaleidoDrawPage>(beforePageDrawHook);
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnPlayerPostLimbDraw>(onPlayerPostLimbDrawHook);
if (!CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.Enabled", 0)) {
CVarClear("gEnhancements.Masks.PersistentBunnyHood.State");
return;
}
// If the mask is equipped, unequip it
if (gSaveContext.save.equippedMask == PLAYER_MASK_BUNNY) {
gSaveContext.save.equippedMask = PLAYER_MASK_NONE;
CVarSetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 1);
if (gPlayState != NULL) {
Player* player = GET_PLAYER(gPlayState);
player->prevMask = player->currentMask;
player->currentMask = PLAYER_MASK_NONE;
}
}
// If they don't have the mask, clear the state
if (INV_CONTENT(ITEM_MASK_BUNNY) != ITEM_MASK_BUNNY) {
CVarClear("gEnhancements.Masks.PersistentBunnyHood.State");
}
// This hook draws the mask on the players head when it's active and they aren't in first person
onPlayerPostLimbDrawHook = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnPlayerPostLimbDraw>(
PLAYER_LIMB_HEAD, [](Player* player, s32 limbIndex) {
// Ensure they aren't in first person
if (CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 0) &&
!(player->stateFlags1 & PLAYER_STATE1_100000)) {
OPEN_DISPS(gPlayState->state.gfxCtx);
Matrix_Push();
Player_DrawBunnyHood(gPlayState);
gSPDisplayList(POLY_OPA_DISP++,
(Gfx*)D_801C0B20[PLAYER_MASK_BUNNY - 1]); // D_801C0B20 is an array of mask DLs
Matrix_Pop();
CLOSE_DISPS(gPlayState->state.gfxCtx);
}
});
// This hook sets up the quad and draws the "active" blue border around the mask in the pause menu
beforePageDrawHook = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::BeforeKaleidoDrawPage>(
PAUSE_MASK, [](PauseContext* _, u16 __) {
GraphicsContext* gfxCtx = gPlayState->state.gfxCtx;
PauseContext* pauseCtx = &gPlayState->pauseCtx;
s16 i = 0;
s16 j = 0;
s16 k;
OPEN_DISPS(gfxCtx);
persistentMasksVtx = (Vtx*)GRAPH_ALLOC(gfxCtx, (4 * 4) * sizeof(Vtx));
if ((pauseCtx->state == PAUSE_STATE_MAIN)) {
s16 slot = SLOT_MASK_BUNNY - ITEM_NUM_SLOTS;
s16 slotX = slot % MASK_GRID_COLS;
s16 slotY = slot / MASK_GRID_COLS;
s16 initialX = 0 - (MASK_GRID_COLS * MASK_GRID_CELL_WIDTH) / 2;
s16 initialY = (MASK_GRID_ROWS * MASK_GRID_CELL_HEIGHT) / 2 - 6;
s16 vtxX = (initialX + (slotX * MASK_GRID_CELL_WIDTH)) + MASK_GRID_QUAD_MARGIN;
s16 vtxY = (initialY - (slotY * MASK_GRID_CELL_HEIGHT)) + pauseCtx->offsetY - MASK_GRID_QUAD_MARGIN;
persistentMasksVtx[i + 0].v.ob[0] = persistentMasksVtx[i + 2].v.ob[0] =
vtxX + MASK_GRID_SELECTED_QUAD_MARGIN;
persistentMasksVtx[i + 1].v.ob[0] = persistentMasksVtx[i + 3].v.ob[0] =
persistentMasksVtx[i + 0].v.ob[0] + MASK_GRID_SELECTED_QUAD_WIDTH;
persistentMasksVtx[i + 0].v.ob[1] = persistentMasksVtx[i + 1].v.ob[1] =
vtxY - MASK_GRID_SELECTED_QUAD_MARGIN;
persistentMasksVtx[i + 2].v.ob[1] = persistentMasksVtx[i + 3].v.ob[1] =
persistentMasksVtx[i + 0].v.ob[1] - MASK_GRID_SELECTED_QUAD_HEIGHT;
persistentMasksVtx[i + 0].v.ob[2] = persistentMasksVtx[i + 1].v.ob[2] =
persistentMasksVtx[i + 2].v.ob[2] = persistentMasksVtx[i + 3].v.ob[2] = 0;
persistentMasksVtx[i + 0].v.flag = persistentMasksVtx[i + 1].v.flag = persistentMasksVtx[i + 2].v.flag =
persistentMasksVtx[i + 3].v.flag = 0;
persistentMasksVtx[i + 0].v.tc[0] = persistentMasksVtx[i + 0].v.tc[1] =
persistentMasksVtx[i + 1].v.tc[1] = persistentMasksVtx[i + 2].v.tc[0] = 0;
persistentMasksVtx[i + 1].v.tc[0] = persistentMasksVtx[i + 2].v.tc[1] =
persistentMasksVtx[i + 3].v.tc[0] = persistentMasksVtx[i + 3].v.tc[1] =
MASK_GRID_SELECTED_QUAD_TEX_SIZE * (1 << 5);
persistentMasksVtx[i + 0].v.cn[0] = persistentMasksVtx[i + 1].v.cn[0] =
persistentMasksVtx[i + 2].v.cn[0] = persistentMasksVtx[i + 3].v.cn[0] =
persistentMasksVtx[i + 0].v.cn[1] = persistentMasksVtx[i + 1].v.cn[1] =
persistentMasksVtx[i + 2].v.cn[1] = persistentMasksVtx[i + 3].v.cn[1] =
persistentMasksVtx[i + 0].v.cn[2] = persistentMasksVtx[i + 1].v.cn[2] =
persistentMasksVtx[i + 2].v.cn[2] = persistentMasksVtx[i + 3].v.cn[2] = 255;
persistentMasksVtx[i + 0].v.cn[3] = persistentMasksVtx[i + 1].v.cn[3] =
persistentMasksVtx[i + 2].v.cn[3] = persistentMasksVtx[i + 3].v.cn[3] = pauseCtx->alpha;
if (CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 0)) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 100, 200, 255, 255);
gSPVertex(POLY_OPA_DISP++, (uintptr_t)persistentMasksVtx, 4, 0);
POLY_OPA_DISP = Gfx_DrawTexQuadIA8(POLY_OPA_DISP, (TexturePtr)gEquippedItemOutlineTex, 32, 32, 0);
}
}
CLOSE_DISPS(gfxCtx);
});
}
void RegisterPersistentMasks() {
UpdatePersistentMasksState();
// Easiest way to handle things like loading into a different file, debug warping, etc.
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>(
[](s8 sceneId, s8 spawnNum) { UpdatePersistentMasksState(); });
// Speed the player up when the bunny hood state is active
REGISTER_VB_SHOULD(GI_VB_CONSIDER_BUNNY_HOOD_EQUIPPED, {
if (CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 0)) {
*should = true;
}
});
// Overrides allowing them to equip a mask while transformed
REGISTER_VB_SHOULD(GI_VB_USE_ITEM_CONSIDER_LINK_HUMAN, {
if (CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.Enabled", 0) &&
*(PlayerItemAction*)opt == PLAYER_IA_MASK_BUNNY) {
*should = true;
}
});
// When they do equip the mask, prevent it and instead set our state
REGISTER_VB_SHOULD(GI_VB_USE_ITEM_EQUIP_MASK, {
PlayerMask* maskId = (PlayerMask*)opt;
Player* player = GET_PLAYER(gPlayState);
if (*maskId == PLAYER_MASK_BUNNY && CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.Enabled", 0)) {
*should = false;
CVarSetInteger("gEnhancements.Masks.PersistentBunnyHood.State",
!CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 0));
if (CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 0)) {
func_8082E1F0(player, NA_SE_PL_CHANGE_ARMS);
} else {
func_8082E1F0(player, NA_SE_PL_TAKE_OUT_SHIELD);
}
}
});
// Prevent the "equipped" white border from being drawn so ours shows instead (ours was drawn before it, so it's
// underneath)
REGISTER_VB_SHOULD(GI_VB_DRAW_ITEM_EQUIPPED_OUTLINE, {
if (*(ItemId*)opt == ITEM_MASK_BUNNY && CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 0)) {
*should = false;
}
});
// Typically when you are in a transformation all masks are dimmed on the C-Buttons
REGISTER_VB_SHOULD(GI_VB_ITEM_BE_RESTRICTED, {
if (*(ItemId*)opt == ITEM_MASK_BUNNY && CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.Enabled", 0)) {
*should = false;
}
});
// Override "A" press behavior on kaleido scope to toggle the mask state
REGISTER_VB_SHOULD(GI_VB_KALEIDO_DISPLAY_ITEM_TEXT, {
ItemId* itemId = (ItemId*)opt;
if (CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.Enabled", 0) && *itemId == ITEM_MASK_BUNNY) {
*should = false;
CVarSetInteger("gEnhancements.Masks.PersistentBunnyHood.State",
!CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 0));
if (CVarGetInteger("gEnhancements.Masks.PersistentBunnyHood.State", 0)) {
Audio_PlaySfx(NA_SE_SY_CAMERA_ZOOM_DOWN);
} else {
Audio_PlaySfx(NA_SE_SY_CAMERA_ZOOM_UP);
}
} else if (CVarGetInteger("gEnhancements.Masks.PersistentGreatFairyMask.Enabled", 0) &&
*itemId == ITEM_MASK_GREAT_FAIRY) {
*should = false;
CVarSetInteger("gEnhancements.Masks.PersistentGreatFairyMask.State",
!CVarGetInteger("gEnhancements.Masks.PersistentGreatFairyMask.State", 0));
}
});
}
@@ -0,0 +1,7 @@
#ifndef MASKS_PERSISTENT_MASKS_H
#define MASKS_PERSISTENT_MASKS_H
void RegisterPersistentMasks();
void UpdatePersistentMasksState();
#endif // MASKS_PERSISTENT_MASKS_H
+8
View File
@@ -1,6 +1,10 @@
#ifndef GFXPRINT_H
#define GFXPRINT_H
#ifdef __cplusplus
#define this thisx
#endif
#include "color.h"
#include "PR/gbi.h"
#include "PR/ultratypes.h"
@@ -61,4 +65,8 @@ s32 GfxPrint_Printf(GfxPrint* this, const char* fmt, ...);
(void)0
// #endregion
#ifdef __cplusplus
#undef this
#endif
#endif
-2
View File
@@ -2,7 +2,6 @@
#define Z64_H
#ifdef __cplusplus
extern "C" {
#define this thisx
#endif
#include "libc/math.h"
#include "libc/stdarg.h"
@@ -308,6 +307,5 @@ typedef enum {
//
#ifdef __cplusplus
}
#undef this
#endif
#endif
+3
View File
@@ -43,6 +43,7 @@
// Assets for other actors
#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
#include "2s2h/Enhancements/GameInteractor/GameInteractor.h"
void PlayerCall_Init(Actor* thisx, PlayState* play);
void PlayerCall_Destroy(Actor* thisx, PlayState* play);
@@ -4020,5 +4021,7 @@ void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList1, G
Player_SetFeetPos(play, player, limbIndex);
}
GameInteractor_ExecuteOnPlayerPostLimbDraw(player, limbIndex);
func_8012536C();
}
@@ -4471,7 +4471,9 @@ void Player_UseItem(PlayState* play, Player* this, ItemId item) {
(itemAction == PLAYER_IA_MASK_ZORA) ||
((this->currentBoots >= PLAYER_BOOTS_ZORA_UNDERWATER) && (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND)))) {
s32 var_v1 = ((itemAction >= PLAYER_IA_MASK_MIN) && (itemAction <= PLAYER_IA_MASK_MAX) &&
((this->transformation != PLAYER_FORM_HUMAN) || (itemAction >= PLAYER_IA_MASK_GIANT)));
(!GameInteractor_Should(GI_VB_USE_ITEM_CONSIDER_LINK_HUMAN,
this->transformation == PLAYER_FORM_HUMAN, &itemAction) ||
(itemAction >= PLAYER_IA_MASK_GIANT)));
CollisionPoly* sp5C;
s32 sp58;
f32 sp54;
@@ -4531,20 +4533,23 @@ void Player_UseItem(PlayState* play, Player* this, ItemId item) {
} else {
Audio_PlaySfx(NA_SE_SY_ERROR);
}
} else if ((this->transformation == PLAYER_FORM_HUMAN) && (itemAction >= PLAYER_IA_MASK_MIN) &&
(itemAction < PLAYER_IA_MASK_GIANT)) {
} else if (GameInteractor_Should(GI_VB_USE_ITEM_CONSIDER_LINK_HUMAN, this->transformation == PLAYER_FORM_HUMAN,
&itemAction) &&
(itemAction >= PLAYER_IA_MASK_MIN) && (itemAction < PLAYER_IA_MASK_GIANT)) {
PlayerMask maskId = GET_MASK_FROM_IA(itemAction);
// Handle wearable masks
this->prevMask = this->currentMask;
if (maskId == this->currentMask) {
this->currentMask = PLAYER_MASK_NONE;
func_8082E1F0(this, NA_SE_PL_TAKE_OUT_SHIELD);
} else {
this->currentMask = maskId;
func_8082E1F0(this, NA_SE_PL_CHANGE_ARMS);
if (GameInteractor_Should(GI_VB_USE_ITEM_EQUIP_MASK, true, &maskId)) {
// Handle wearable masks
this->prevMask = this->currentMask;
if (maskId == this->currentMask) {
this->currentMask = PLAYER_MASK_NONE;
func_8082E1F0(this, NA_SE_PL_TAKE_OUT_SHIELD);
} else {
this->currentMask = maskId;
func_8082E1F0(this, NA_SE_PL_CHANGE_ARMS);
}
gSaveContext.save.equippedMask = this->currentMask;
}
gSaveContext.save.equippedMask = this->currentMask;
} else if ((itemAction != this->heldItemAction) ||
((this->heldActor == NULL) && (Player_ExplosiveFromIA(this, itemAction) > PLAYER_EXPLOSIVE_NONE))) {
u8 nextAnimType;
@@ -12193,7 +12198,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
this->actor.shape.face = ((play->gameplayFrames & 0x20) ? 0 : 3) + this->blinkInfo.eyeTexIndex;
if (this->currentMask == PLAYER_MASK_BUNNY) {
if (GameInteractor_Should(GI_VB_CONSIDER_BUNNY_HOOD_EQUIPPED, this->currentMask == PLAYER_MASK_BUNNY, this)) {
Player_UpdateBunnyEars(this);
}
@@ -14458,7 +14463,7 @@ void Player_Action_13(Player* this, PlayState* play) {
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_CURVED, play);
if (this->currentMask == PLAYER_MASK_BUNNY) {
if (GameInteractor_Should(GI_VB_CONSIDER_BUNNY_HOOD_EQUIPPED, this->currentMask == PLAYER_MASK_BUNNY, this)) {
speedTarget *= 1.5f;
}
@@ -210,8 +210,11 @@ void KaleidoScope_DrawMaskSelect(PlayState* play) {
for (i = 0, j = MASK_NUM_SLOTS * 4; i < 3; i++, j += 4) {
if (GET_CUR_FORM_BTN_ITEM(i + 1) != ITEM_NONE) {
if (GET_CUR_FORM_BTN_SLOT(i + 1) >= ITEM_NUM_SLOTS) {
gSPVertex(POLY_OPA_DISP++, &pauseCtx->maskVtx[j], 4, 0);
POLY_OPA_DISP = Gfx_DrawTexQuadIA8(POLY_OPA_DISP, gEquippedItemOutlineTex, 32, 32, 0);
ItemId item = GET_CUR_FORM_BTN_ITEM(i + 1);
if (GameInteractor_Should(GI_VB_DRAW_ITEM_EQUIPPED_OUTLINE, true, &item)) {
gSPVertex(POLY_OPA_DISP++, &pauseCtx->maskVtx[j], 4, 0);
POLY_OPA_DISP = Gfx_DrawTexQuadIA8(POLY_OPA_DISP, gEquippedItemOutlineTex, 32, 32, 0);
}
}
}
}
@@ -220,8 +223,11 @@ void KaleidoScope_DrawMaskSelect(PlayState* play) {
for (i = EQUIP_SLOT_D_RIGHT; i <= EQUIP_SLOT_D_UP; i++, j += 4) {
if (DPAD_GET_CUR_FORM_BTN_ITEM(i) != ITEM_NONE) {
if (DPAD_GET_CUR_FORM_BTN_SLOT(i) >= ITEM_NUM_SLOTS) {
gSPVertex(POLY_OPA_DISP++, &pauseCtx->maskVtx[j], 4, 0);
POLY_OPA_DISP = Gfx_DrawTexQuadIA8(POLY_OPA_DISP, gEquippedItemOutlineTex, 32, 32, 0);
ItemId item = DPAD_GET_CUR_FORM_BTN_ITEM(i);
if (GameInteractor_Should(GI_VB_DRAW_ITEM_EQUIPPED_OUTLINE, true, &item)) {
gSPVertex(POLY_OPA_DISP++, &pauseCtx->maskVtx[j], 4, 0);
POLY_OPA_DISP = Gfx_DrawTexQuadIA8(POLY_OPA_DISP, gEquippedItemOutlineTex, 32, 32, 0);
}
}
}
}
@@ -669,12 +675,15 @@ void KaleidoScope_UpdateMaskCursor(PlayState* play) {
} else if ((pauseCtx->debugEditor == DEBUG_EDITOR_NONE) && (pauseCtx->state == PAUSE_STATE_MAIN) &&
(pauseCtx->mainState == PAUSE_MAIN_STATE_IDLE) &&
CHECK_BTN_ALL(input->press.button, BTN_A) && (msgCtx->msgLength == 0)) {
// Give description on item through a message box
pauseCtx->itemDescriptionOn = true;
if (pauseCtx->cursorYIndex[PAUSE_MASK] < 2) {
func_801514B0(play, 0x1700 + pauseCtx->cursorItem[PAUSE_MASK], 3);
} else {
func_801514B0(play, 0x1700 + pauseCtx->cursorItem[PAUSE_MASK], 1);
if (GameInteractor_Should(GI_VB_KALEIDO_DISPLAY_ITEM_TEXT, true,
&pauseCtx->cursorItem[PAUSE_MASK])) {
// Give description on item through a message box
pauseCtx->itemDescriptionOn = true;
if (pauseCtx->cursorYIndex[PAUSE_MASK] < 2) {
func_801514B0(play, 0x1700 + pauseCtx->cursorItem[PAUSE_MASK], 3);
} else {
func_801514B0(play, 0x1700 + pauseCtx->cursorItem[PAUSE_MASK], 1);
}
}
}
}
@@ -834,7 +834,9 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
POLY_OPA_DISP =
KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->itemPageVtx, sItemPageBgTextures);
GameInteractor_ExecuteBeforeKaleidoDrawPage(pauseCtx, pauseCtx->pageIndex);
KaleidoScope_DrawItemSelect(play);
GameInteractor_ExecuteAfterKaleidoDrawPage(pauseCtx, pauseCtx->pageIndex);
}
break;
@@ -855,6 +857,7 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
POLY_OPA_DISP = KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->mapPageVtx, sMapPageBgTextures);
GameInteractor_ExecuteBeforeKaleidoDrawPage(pauseCtx, pauseCtx->pageIndex);
if (sInDungeonScene) {
KaleidoScope_DrawDungeonMap(play);
Gfx_SetupDL42_Opa(gfxCtx);
@@ -884,6 +887,7 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
KaleidoScope_DrawWorldMap(play);
}
GameInteractor_ExecuteAfterKaleidoDrawPage(pauseCtx, pauseCtx->pageIndex);
break;
case PAUSE_QUEST:
@@ -906,7 +910,9 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
POLY_OPA_DISP =
KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->questPageVtx, sQuestPageBgTextures);
GameInteractor_ExecuteBeforeKaleidoDrawPage(pauseCtx, pauseCtx->pageIndex);
KaleidoScope_DrawQuestStatus(play);
GameInteractor_ExecuteAfterKaleidoDrawPage(pauseCtx, pauseCtx->pageIndex);
break;
case PAUSE_MASK:
@@ -927,7 +933,9 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
POLY_OPA_DISP =
KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->maskPageVtx, sMaskPageBgTextures);
GameInteractor_ExecuteBeforeKaleidoDrawPage(pauseCtx, pauseCtx->pageIndex);
KaleidoScope_DrawMaskSelect(play);
GameInteractor_ExecuteAfterKaleidoDrawPage(pauseCtx, pauseCtx->pageIndex);
break;
}
}