From ba7fc14e8781bf3b62e9e1b5a784c96fe99cb9c1 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Sat, 25 Apr 2026 17:17:12 -0400 Subject: [PATCH] added poe lantern wip code --- include/d/actor/d_a_alink.h | 7 ++ src/d/actor/d_a_alink.cpp | 24 +++++- src/d/actor/d_a_alink_kandelaar.inc | 111 ++++++++++++++++++++++++++++ src/d/actor/d_a_alink_wolf.inc | 12 +++ 4 files changed, 151 insertions(+), 3 deletions(-) diff --git a/include/d/actor/d_a_alink.h b/include/d/actor/d_a_alink.h index f00f238e38..a76b75dd56 100644 --- a/include/d/actor/d_a_alink.h +++ b/include/d/actor/d_a_alink.h @@ -2657,8 +2657,11 @@ public: void checkWaterInKandelaar(f32); void offKandelaarModel(); int kandelaarModelCallBack(); + int ghostLanternModelCallBack(); BOOL checkKandelaarEquipAnime() const; void preKandelaarDraw(); + void preGhostLanternDraw(); + static void* srchPoe(void*, void*); void setKandelaarModel(); void resetOilBottleModel(); void commonKandelaarPourInit(); @@ -3978,6 +3981,9 @@ public: /* 0x006FC */ J3DModel* mpKanteraModel; /* 0x00700 */ J3DModel* mpKanteraGlowModel; /* 0x00704 */ J3DAnmTextureSRTKey* mpKanteraGlowBtk; + /* 0x006FC */ J3DModel* mpGhostLanternModel; + /* 0x00700 */ J3DModel* mpGhostLanternGlowModel; + /* 0x00704 */ J3DAnmTextureSRTKey* mpGhostLanternGlowBtk; /* 0x00708 */ J3DModel* mHeldItemModel; /* 0x0070C */ J3DModel* mpHookTipModel; // related to held item /* 0x00710 */ J3DModel* field_0x0710; // related to held item @@ -4510,6 +4516,7 @@ public: /* 0x035F4 */ cXyz mMidnaAtnPos; /* 0x03600 */ cXyz mMidnaHairAtnPos; /* 0x0360C */ cXyz mKandelaarFlamePos; + /* 0x0360C */ cXyz mGhostLanternFlamePos; /* 0x03618 */ cXyz field_0x3618; /* 0x03624 */ cXyz field_0x3624; /* 0x03630 */ cXyz field_0x3630; diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index 7fc7fadd34..17ca660cbf 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -6088,6 +6088,20 @@ void daAlink_c::setItemMatrix(int param_0) { modelCalc(mpKanteraGlowModel); } + if (mEquipItem == dItemNo_LENS_OF_TRUTH_e) { + simpleAnmPlay(mpGhostLanternGlowBtk); + + mDoMtx_stack_c::copy(mpLinkModel->getAnmMtx(mLeftItemJntNo)); + mDoMtx_stack_c::transM(-2.0f, -0.1f, -0.7f); + mDoMtx_stack_c::XYZrotM(cM_deg2s(100.0f), cM_deg2s(9.3f), cM_deg2s(183.0f)); + mpGhostLanternModel->setBaseTRMtx(mDoMtx_stack_c::get()); + + modelCalc(mpGhostLanternModel); + mDoMtx_stack_c::transS(mGhostLanternFlamePos); + mpGhostLanternGlowModel->setBaseTRMtx(mDoMtx_stack_c::get()); + modelCalc(mpGhostLanternGlowModel); + } + setSwordPos(); simpleAnmPlay(m_mSwordBtk); simpleAnmPlay(m_mSwordBrk); @@ -6908,7 +6922,7 @@ const daAlink_BckData* daAlink_c::getMainBckData(daAlink_c::daAlink_ANM i_anmID) {dRes_ID_ALANM_BCK_WAITHS_e, dRes_ID_ALANM_BCK_WAITHK_e}, }; - if (mEquipItem == dItemNo_KANTERA_e) { + if (mEquipItem == dItemNo_KANTERA_e || mEquipItem == dItemNo_LENS_OF_TRUTH_e) { if (i_anmID == ANM_WAIT) { return &kandelaarAnm[0]; } @@ -14584,8 +14598,6 @@ int daAlink_c::checkNewItemChange(u8 i_selItemIdx) { ) { return ITEM_PROC_NONE; - } else if (sel_item == dItemNo_LENS_OF_TRUTH_e) { - return ITEM_PROC_LENS_OF_TRUTH; } else if (sel_item == dItemNo_HVY_BOOTS_e || checkDungeonWarpItem(sel_item) || checkTradeItem(sel_item) @@ -19725,6 +19737,12 @@ int daAlink_c::draw() { basicModelDraw(mpKanteraGlowModel); } + if (mEquipItem == dItemNo_LENS_OF_TRUTH_e) { + modelDraw(mpGhostLanternModel, isPlayerNoDraw); + preGhostLanternDraw(); + modelDraw(mpGhostLanternGlowModel, isPlayerNoDraw); + } + if (checkEquipHeavyBoots()) { GXColorS10 color = tevStr.TevColor; for (int i = 0; i < 2; i++) { diff --git a/src/d/actor/d_a_alink_kandelaar.inc b/src/d/actor/d_a_alink_kandelaar.inc index 339ff90ce6..0bab821a90 100644 --- a/src/d/actor/d_a_alink_kandelaar.inc +++ b/src/d/actor/d_a_alink_kandelaar.inc @@ -9,6 +9,7 @@ #include "d/actor/d_a_tag_ss_drink.h" #include "m_Do/m_Do_lib.h" #include "SSystem/SComponent/c_math.h" +#include "d/actor/d_a_e_hp.h" static fopAc_ac_c* daAlink_searchTagKandelaar(fopAc_ac_c* i_actor, void* i_data) { UNUSED(i_data); @@ -138,6 +139,49 @@ int daAlink_c::kandelaarModelCallBack() { return 1; } +int daAlink_c::ghostLanternModelCallBack() { + cXyz sp44; + mDoMtx_multVecZero(J3DSys::mCurrentMtx, &sp44); + + field_0x3630 = field_0x3624; + field_0x3624 = mGhostLanternFlamePos; + + cXyz sp38 = (mGhostLanternFlamePos - sp44) + field_0x3618; + sp38.y -= 3.0f; + + cXyz sp2C; + mDoMtx_multVec(J3DSys::mCurrentMtx, &cXyz::BaseZ, &sp2C); + + s16 var_r29 = sp2C.atan2sX_Z(); + mDoMtx_stack_c::YrotS(-var_r29); + mDoMtx_stack_c::multVec(&sp38, &sp38); + + s16 var_r28 = cLib_minMaxLimit(cM_atan2s(-sp38.z, -sp38.y), -0x1800, 0x1800); + s16 var_r27 = cLib_minMaxLimit(cM_atan2s(sp38.x, JMAFastSqrt(SQUARE(sp38.y) + SQUARE(sp38.z))), -0x1800, 0x1800); + + mDoMtx_stack_c::transS(sp44); + if (mProcID != PROC_OPEN_TREASURE && (mProcID != PROC_GET_ITEM || mProcVar4.field_0x3010 == 0)) { + mDoMtx_stack_c::ZXYrotM(var_r28, var_r29, var_r27); + } + + static Vec const kandelaarOffset = {0.0f, -17.0f, 0.0f}; + mDoMtx_stack_c::multVec(&kandelaarOffset, &mGhostLanternFlamePos); + + field_0x3618 = (mGhostLanternFlamePos - field_0x3624) * 0.9f; + + if (!checkEndResetFlg1(ERFLG1_UNK_8)) { + f32 scale = JMAFastSqrt(SQUARE(J3DSys::mCurrentMtx[0][0]) + SQUARE(J3DSys::mCurrentMtx[1][0]) + SQUARE(J3DSys::mCurrentMtx[2][0])); + mDoMtx_stack_c::transS(J3DSys::mCurrentMtx[0][3], J3DSys::mCurrentMtx[1][3], J3DSys::mCurrentMtx[2][3]); + mDoMtx_stack_c::ZXYrotM(var_r28, var_r29, var_r27); + mDoMtx_stack_c::scaleM(scale, scale, scale); + + mpGhostLanternModel->setAnmMtx(1, mDoMtx_stack_c::get()); + cMtx_copy(mDoMtx_stack_c::get(), J3DSys::mCurrentMtx); + } + + return 1; +} + static int daAlink_kandelaarModelCallBack(J3DJoint* i_joint, int param_1) { UNUSED(i_joint); @@ -150,6 +194,18 @@ static int daAlink_kandelaarModelCallBack(J3DJoint* i_joint, int param_1) { return 1; } +static int daAlink_ghostLanternModelCallBack(J3DJoint* i_joint, int param_1) { + UNUSED(i_joint); + + daAlink_c* player_p = (daAlink_c*)j3dSys.getModel()->getUserArea(); + + if (param_1 == 0) { + player_p->ghostLanternModelCallBack(); + } + + return 1; +} + cXyz* daAlink_c::getKandelaarFlamePos() { if ((!checkNoResetFlg2(daPy_FLG2(FLG2_UNK_20000 | FLG2_UNK_1)) && !checkEndResetFlg1(ERFLG1_UNK_4)) || checkWolf() || !checkNoResetFlg1(FLG1_UNK_80)) @@ -164,6 +220,61 @@ BOOL daAlink_c::checkKandelaarEquipAnime() const { return checkUpperAnime(dRes_ID_ALANM_BCK_WAITHK_e) || checkUpperAnime(dRes_ID_ALANM_BCK_WAITK_e); } +void* daAlink_c::srchPoe(void* i_actor, void* i_this) { + if (i_actor != NULL && i_actor != i_this) { + if (fopAcM_IsExecuting(fopAcM_GetID(i_actor)) && fopAcM_GetName(i_actor) == fpcNm_E_HP_e) { + return i_actor; + } + } + return NULL; +} + +void daAlink_c::preGhostLanternDraw() { + J3DMaterial* mat_p = mpGhostLanternGlowModel->getModelData()->getMaterialNodePointer(0); + + daE_HP_c* foundPoe = (daE_HP_c*)fopAcM_Search(srchPoe, this); + + J3DGXColorS10 color; + color.r = 0; + color.g = 0; + color.b = foundPoe != NULL ? 255 : 0; + color.a = foundPoe != NULL ? 255 : 0; + mat_p->setTevColor(1, &color); + + color.r = 0; + color.g = 0; + color.b = foundPoe != NULL ? 255 : 0; + mat_p->setTevColor(2, &color); + + cXyz proj; + mDoLib_project(&mGhostLanternFlamePos, &proj); + + camera_process_class* camera_p = dComIfGp_getCamera(0); + f32 trimHeight; + if (camera_p != NULL) { + trimHeight = camera_p->mCamera.TrimHeight(); + } else { + trimHeight = 0.0f; + } + + if (proj.x > 0.0f && proj.x < FB_WIDTH && proj.y > trimHeight && proj.y < FB_HEIGHT - trimHeight) { + dComIfGd_peekZ(proj.x, proj.y, &field_0x32c8); + } else { + field_0x32c8 = 0; + } + + f32 near_ = dComIfGd_getView()->near_; + f32 far_ = dComIfGd_getView()->far_; + + mDoLib_pos2camera(&mKandelaarFlamePos, &proj); + proj.z += 30.0f; + if (proj.z > -0.01f) { + proj.z = -0.01f; + } + + field_0x344c = ((near_ + (far_ * near_) / proj.z) / (far_ - near_) + 1.0f) * 1.6777215E7f; +} + void daAlink_c::preKandelaarDraw() { J3DMaterial* mat_p = mpKanteraGlowModel->getModelData()->getMaterialNodePointer(0); diff --git a/src/d/actor/d_a_alink_wolf.inc b/src/d/actor/d_a_alink_wolf.inc index b2e60aea01..6e6c417732 100644 --- a/src/d/actor/d_a_alink_wolf.inc +++ b/src/d/actor/d_a_alink_wolf.inc @@ -300,6 +300,7 @@ void daAlink_c::changeWolf() { mAtSph.SetR(40.0f); mpKanteraModel = NULL; + mpGhostLanternModel = NULL; mpLinkHatModel = NULL; mpLinkFaceModel = NULL; mpLinkHandModel = NULL; @@ -403,15 +404,22 @@ void daAlink_c::changeLink(int param_0) { } mpKanteraModel = initModelEnv(static_cast(dComIfG_getObjectRes(mArcName, "al_kantera.bmd")), 0); + mpGhostLanternModel = initModelEnv(static_cast(dComIfG_getObjectRes(mArcName, "al_bootsH.bmd")), 0); modelData = static_cast(dComIfG_getObjectRes(mArcName, "ef_ktGlow.bmd")); mpKanteraGlowModel = initModel(modelData, 0x200); + mpGhostLanternGlowModel = initModel(modelData, 0x200); mpKanteraGlowBtk = static_cast(dComIfG_getObjectRes(mArcName, "ef_ktGlow.btk")); mpKanteraGlowBtk->setFrame(0.0f); mpKanteraGlowBtk->searchUpdateMaterialID(modelData); modelData->entryTexMtxAnimator(mpKanteraGlowBtk); + mpGhostLanternGlowBtk = static_cast(dComIfG_getObjectRes(mArcName, "ef_ktGlow.btk")); + mpGhostLanternGlowBtk->setFrame(0.0f); + mpGhostLanternGlowBtk->searchUpdateMaterialID(modelData); + modelData->entryTexMtxAnimator(mpGhostLanternGlowBtk); + mWoodSwordModel = initModel(static_cast(dComIfG_getObjectRes(mArcName, "al_SWB.bmd")), 0); mDoExt_setCurrentHeap(current_heap); @@ -504,6 +512,10 @@ void daAlink_c::changeLink(int param_0) { mpKanteraModel->setUserArea((uintptr_t)this); mpKanteraModel->getModelData()->getJointNodePointer(1)->setCallBack(daAlink_kandelaarModelCallBack); + + mpGhostLanternModel->setUserArea((uintptr_t)this); + mpGhostLanternModel->getModelData()->getJointNodePointer(1)->setCallBack(daAlink_ghostLanternModelCallBack); + mZ2Link.setLinkState(var_r27); #if VERSION != VERSION_SHIELD_DEBUG