diff --git a/soh/assets/objects/object_link_boy/object_link_boy.h b/soh/assets/objects/object_link_boy/object_link_boy.h index a36662a804c..f1ed9c7a044 100644 --- a/soh/assets/objects/object_link_boy/object_link_boy.h +++ b/soh/assets/objects/object_link_boy/object_link_boy.h @@ -510,5 +510,30 @@ static const ALIGN_ASSET(2) char gLinkAdultVtx_0340A0[] = dgLinkAdultVtx_0340A0; #define dgLinkAdultVtx_02E7E0 "__OTR__objects/object_link_boy/gLinkAdultVtx_02E7E0" static const ALIGN_ASSET(2) char gLinkAdultVtx_02E7E0[] = dgLinkAdultVtx_02E7E0; +// Adult-fitted mask display lists (for use when adult Link wears child masks via the AdultMasks enhancement) +#define dgLinkAdultKeatonMaskDL "__OTR__objects/object_link_boy/gLinkAdultKeatonMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultKeatonMaskDL[] = dgLinkAdultKeatonMaskDL; + +#define dgLinkAdultSkullMaskDL "__OTR__objects/object_link_boy/gLinkAdultSkullMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultSkullMaskDL[] = dgLinkAdultSkullMaskDL; + +#define dgLinkAdultSpookyMaskDL "__OTR__objects/object_link_boy/gLinkAdultSpookyMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultSpookyMaskDL[] = dgLinkAdultSpookyMaskDL; + +#define dgLinkAdultBunnyHoodDL "__OTR__objects/object_link_boy/gLinkAdultBunnyHoodDL" +static const ALIGN_ASSET(2) char gLinkAdultBunnyHoodDL[] = dgLinkAdultBunnyHoodDL; + +#define dgLinkAdultGoronMaskDL "__OTR__objects/object_link_boy/gLinkAdultGoronMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultGoronMaskDL[] = dgLinkAdultGoronMaskDL; + +#define dgLinkAdultZoraMaskDL "__OTR__objects/object_link_boy/gLinkAdultZoraMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultZoraMaskDL[] = dgLinkAdultZoraMaskDL; + +#define dgLinkAdultGerudoMaskDL "__OTR__objects/object_link_boy/gLinkAdultGerudoMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultGerudoMaskDL[] = dgLinkAdultGerudoMaskDL; + +#define dgLinkAdultMaskOfTruthDL "__OTR__objects/object_link_boy/gLinkAdultMaskOfTruthDL" +static const ALIGN_ASSET(2) char gLinkAdultMaskOfTruthDL[] = dgLinkAdultMaskOfTruthDL; + #endif // OBJECTS_OBJECT_LINK_BOY_H diff --git a/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp b/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp new file mode 100644 index 00000000000..104b5afbfd6 --- /dev/null +++ b/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp @@ -0,0 +1,38 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipInit.hpp" +#include "soh/ResourceManagerHelpers.h" + +extern "C" { +#include "macros.h" +#include "functions.h" +#include "objects/object_link_boy/object_link_boy.h" +extern SaveContext gSaveContext; +} + +static const char* sAdultMaskDLists[] = { + gLinkAdultKeatonMaskDL, gLinkAdultSkullMaskDL, gLinkAdultSpookyMaskDL, gLinkAdultBunnyHoodDL, + gLinkAdultGoronMaskDL, gLinkAdultZoraMaskDL, gLinkAdultGerudoMaskDL, gLinkAdultMaskOfTruthDL, +}; + +static void RegisterAgeDependentMasks() { + COND_VB_SHOULD(VB_DRAW_PLAYER_MASK, true, { + if (!LINK_IS_ADULT) + return; + + PlayerMask currentMask = (PlayerMask)va_arg(args, int); + PlayState* play = va_arg(args, PlayState*); + + int maskIndex = currentMask - 1; + if (maskIndex < 0 || maskIndex >= 8) + return; + + const char* adultDL = sAdultMaskDLists[maskIndex]; + if (!ResourceGetIsCustomByName(adultDL) && !ResourceMgr_FileExists(adultDL)) + return; + + *should = false; + gSPDisplayList(play->state.gfxCtx->polyOpa.p++, (Gfx*)adultDL); + }); +} + +static RegisterShipInitFunc initFunc(RegisterAgeDependentMasks); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index d1ed4534100..e81793619c3 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -579,6 +579,15 @@ typedef enum { // - None VB_DRAW_ADDITIONAL_RETICLES, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `PlayerMask currentMask` + // - `*PlayState play` + VB_DRAW_PLAYER_MASK, + // #### `result` // In `Interface_DrawAmmoCount`: // ```c diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 7ffe8af7f43..c6b092ea646 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -12449,8 +12449,10 @@ void Player_DrawGameplay(PlayState* play, Player* this, s32 lod, Gfx* cullDList, MATRIX_TOMTX(bunnyEarMtx); } - if (this->currentMask != PLAYER_MASK_BUNNY || !CVarGetInteger(CVAR_ENHANCEMENT("HideBunnyHood"), 0)) { - gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]); + if (GameInteractor_Should(VB_DRAW_PLAYER_MASK, true, this->currentMask, play)) { + if (this->currentMask != PLAYER_MASK_BUNNY || !CVarGetInteger(CVAR_ENHANCEMENT("HideBunnyHood"), 0)) { + gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]); + } } if (CVarGetInteger(CVAR_GENERAL("FixIceTrapWithBunnyHood"), 1))