// // Generated by dtk // Translation Unit: f_op_actor_mng.cpp // #include "f_op/f_op_actor_mng.h" #include "f_op/f_op_actor.h" #include "f_op/f_op_scene_mng.h" #include "f_op/f_op_camera.h" #include "d/d_com_inf_game.h" #include "d/d_item_data.h" #include "d/d_stage.h" #include "d/d_procname.h" #include "d/d_item.h" #include "d/d_item_data.h" #include "d/d_bg_s_lin_chk.h" #include "d/actor/d_a_player.h" #include "d/actor/d_a_item.h" #include "d/actor/d_a_sea.h" #include "d/actor/d_a_ib.h" #include "m_Do/m_Do_ext.h" #include "m_Do/m_Do_lib.h" #include "m_Do/m_Do_printf.h" #include "m_Do/m_Do_mtx.h" #include "JSystem/JKernel/JKRHeap.h" #include "JSystem/JKernel/JKRSolidHeap.h" #include "JSystem/JUtility/JUTAssert.h" #include "SSystem/SComponent/c_malloc.h" #include "weak_bss_3569.h" // IWYU pragma: keep #define MAKE_ITEM_PARAMS(itemNo, itemBitNo, switchNo2, type, action) \ ((itemNo & 0xFF) << 0 | (itemBitNo & 0xFF) << 0x8 | switchNo2 << 0x10 | (type & 0x3) << 0x18 | (action & 0x3F) << 0x1A) /* 80024060-80024104 .text fopAcM_setStageLayer__FPv */ void fopAcM_setStageLayer(void* pProc) { scene_class* stageProc = fopScnM_SearchByID(dStage_roomControl_c::getProcID()); JUT_ASSERT(0xee, stageProc != NULL); fpcM_ChangeLayerID(pProc, fopScnM_LayerID(stageProc)); } /* 80024104-800241C0 .text fopAcM_setRoomLayer__FPvi */ void fopAcM_setRoomLayer(void* pProc, int room_no) { if (room_no >= 0) { scene_class* roomProc = fopScnM_SearchByID(dStage_roomControl_c::getStatusProcID(room_no)); JUT_ASSERT(0x105, roomProc != NULL); fpcM_ChangeLayerID(pProc, fopScnM_LayerID(roomProc)); } } /* 800241C0-80024230 .text fopAcM_SearchByID__FUiPP10fopAc_ac_c */ BOOL fopAcM_SearchByID(fpc_ProcID actorID, fopAc_ac_c** pDstActor) { if (fpcM_IsCreating(actorID)) { *pDstActor = NULL; } else { fopAc_ac_c *pActor = fopAcM_Search((fopAcIt_JudgeFunc)fpcSch_JudgeByID, &actorID); *pDstActor = pActor; if (*pDstActor == NULL) return FALSE; } return TRUE; } /* 80024230-800242AC .text fopAcM_SearchByName__FsPP10fopAc_ac_c */ BOOL fopAcM_SearchByName(s16 procName, fopAc_ac_c** pDstActor) { *pDstActor = fopAcM_Search((fopAcIt_JudgeFunc)fpcSch_JudgeForPName, &procName); if (*pDstActor == NULL) { return FALSE; } else { if (fpcM_IsCreating(fopAcM_GetID(*pDstActor))) { *pDstActor = NULL; } return TRUE; } } /* 800242AC-80024320 .text fopAcM_CreateAppend__Fv */ fopAcM_prm_class* fopAcM_CreateAppend() { fopAcM_prm_class* params = (fopAcM_prm_class*)cMl::memalignB(-4, sizeof(fopAcM_prm_class)); if (params != NULL) { cLib_memSet(params, 0, sizeof(fopAcM_prm_class)); params->base.setID = 0xFFFF; params->room_no = -1; params->scale.x = 10; params->scale.y = 10; params->scale.z = 10; params->parent_id = fpcM_ERROR_PROCESS_ID_e; params->subtype = -1; } return params; } /* 80024320-80024474 .text createAppend__FUlP4cXyziP5csXyzP4cXyzScUi */ fopAcM_prm_class * createAppend(u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, s8 subtype, fpc_ProcID parentPcId) { fopAcM_prm_class * params = fopAcM_CreateAppend(); if (params == NULL) return NULL; if (pPos != NULL) params->base.position = *pPos; else params->base.position = cXyz::Zero; params->room_no = roomNo; if (pAngle != NULL) params->base.angle = *pAngle; else params->base.angle = csXyz::Zero; if (pScale != NULL) { params->scale.x = 10.0f * pScale->x; params->scale.y = 10.0f * pScale->y; params->scale.z = 10.0f * pScale->z; } else { params->scale.x = 10.0f; params->scale.y = 10.0f; params->scale.z = 10.0f; } params->base.parameters = parameter; params->parent_id = parentPcId; params->subtype = subtype; return params; } /* 80024474-80024478 .text fopAcM_Log__FP10fopAc_ac_cPc */ void fopAcM_Log(fopAc_ac_c*, char*) { /* Empty function */ } /* 80024478-800244B8 .text fopAcM_delete__FP10fopAc_ac_c */ BOOL fopAcM_delete(fopAc_ac_c* pActor) { /* "Deleting Actor" */ fopAcM_Log(pActor, "アクターの削除"); return fpcM_Delete(pActor); } /* 800244B8-8002451C .text fopAcM_delete__FUi */ BOOL fopAcM_delete(fpc_ProcID actorID) { fopAc_ac_c* pActor = (fopAc_ac_c*)fopAcM_SearchByID(actorID); if (pActor != NULL) { /* "Deleting Actor" */ fopAcM_Log(pActor, "アクターの削除"); return fpcM_Delete(pActor); } else { return TRUE; } } /* 8002451C-80024598 .text fopAcM_create__FsUlP4cXyziP5csXyzP4cXyzScPFPv_i */ fpc_ProcID fopAcM_create(s16 procName, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, s8 subtype, createFunc createFunc) { fopAcM_prm_class* params = createAppend(parameter, pPos, roomNo, pAngle, pScale, subtype, fpcM_ERROR_PROCESS_ID_e); if (params == NULL) return fpcM_ERROR_PROCESS_ID_e; return fpcM_Create(procName, createFunc, params); } /* 80024598-80024614 .text fopAcM_create__FPcUlP4cXyziP5csXyzP4cXyzPFPv_i */ fpc_ProcID fopAcM_create(char* pProcNameString, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, createFunc createFunc) { dStage_objectNameInf * nameInf = dStage_searchName(pProcNameString); if (nameInf == NULL) return fpcM_ERROR_PROCESS_ID_e; return fopAcM_create(nameInf->mProcName, parameter, pPos, roomNo, pAngle, pScale, nameInf->mSubtype, createFunc); } /* 80024614-8002468C .text fopAcM_fastCreate__FsUlP4cXyziP5csXyzP4cXyzScPFPv_iPv */ void* fopAcM_fastCreate(s16 procName, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, s8 subtype, createFunc createFunc, void* pUserData) { fopAcM_prm_class* params = createAppend(parameter, pPos, roomNo, pAngle, pScale, subtype, fpcM_ERROR_PROCESS_ID_e); if (params == NULL) return NULL; return fpcM_FastCreate(procName, createFunc, pUserData, params); } /* 8002468C-80024710 .text fopAcM_fastCreate__FPcUlP4cXyziP5csXyzP4cXyzPFPv_iPv */ void* fopAcM_fastCreate(char* pProcNameString, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, createFunc createFunc, void *pUserData) { dStage_objectNameInf * nameInf = dStage_searchName(pProcNameString); if (nameInf == NULL) return NULL; return fopAcM_fastCreate(nameInf->mProcName, parameter, pPos, roomNo, pAngle, pScale, nameInf->mSubtype, createFunc, pUserData); } /* 80024710-80024790 .text fopAcM_createChild__FsUiUlP4cXyziP5csXyzP4cXyzScPFPv_i */ fpc_ProcID fopAcM_createChild(s16 procName, fpc_ProcID parentPcId, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, s8 subtype, createFunc createFunc) { fopAcM_prm_class* params = createAppend(parameter, pPos, roomNo, pAngle, pScale, subtype, parentPcId); if (params == NULL) return fpcM_ERROR_PROCESS_ID_e; return fpcM_Create(procName, createFunc, params); } /* 80024790-80024814 .text fopAcM_createChild__FPcUiUlP4cXyziP5csXyzP4cXyzPFPv_i */ fpc_ProcID fopAcM_createChild(char* pProcNameString, fpc_ProcID parentPcId, u32 parameter, cXyz* pPos, int roomNo, csXyz* pAngle, cXyz* pScale, createFunc createFunc) { dStage_objectNameInf * nameInf = dStage_searchName(pProcNameString); if (nameInf == NULL) return fpcM_ERROR_PROCESS_ID_e; return fopAcM_createChild(nameInf->mProcName, parentPcId, parameter, pPos, roomNo, pAngle, pScale, nameInf->mSubtype, createFunc); } /* 80024814-800249D4 .text fopAcM_createChildFromOffset__FsUiUlP4cXyziP5csXyzP4cXyzScPFPv_i */ fpc_ProcID fopAcM_createChildFromOffset(s16 procName, fpc_ProcID parentPcId, u32 parameter, cXyz* pPosOffs, int roomNo, csXyz* pAngleOffs, cXyz* pScale, s8 subtype, createFunc createFunc) { fopAc_ac_c * pParent = fopAcM_SearchByID(parentPcId); s16 parentAngleY = pParent->current.angle.y; cXyz posOffs; if (pPosOffs == NULL) posOffs = cXyz::Zero; else posOffs = *pPosOffs; csXyz angleOffs; if (pAngleOffs == NULL) angleOffs = csXyz::Zero; else angleOffs = *pAngleOffs; cXyz pos = pParent->current.pos; csXyz angle(angleOffs); angle.y += parentAngleY; pos.x += posOffs.z * cM_ssin(parentAngleY) + posOffs.x * cM_scos(parentAngleY); pos.y += posOffs.y; pos.z += posOffs.z * cM_scos(parentAngleY) - posOffs.x * cM_ssin(parentAngleY); fopAcM_prm_class* params = createAppend(parameter, &pos, roomNo, &angle, pScale, subtype, parentPcId); if (params == NULL) return fpcM_ERROR_PROCESS_ID_e; return fpcM_Create(procName, createFunc, params); } /* 800249D4-80024B78 .text fopAcM_createChildFromOffset__FPcUiUlP4cXyziP5csXyzP4cXyzPFPv_i */ fpc_ProcID fopAcM_createChildFromOffset(char* pProcNameString, fpc_ProcID parentPcId, u32 parameter, cXyz* pPosOffs, int roomNo, csXyz* pAngleOffs, cXyz* pScale, createFunc createFunc) { fopAc_ac_c * pParent = fopAcM_SearchByID(parentPcId); s16 parentAngleY = pParent->current.angle.y; cXyz pos = pParent->current.pos; cXyz posOffs; if (pPosOffs == NULL) posOffs = cXyz::Zero; else posOffs = *pPosOffs; csXyz angleOffs; if (pAngleOffs == NULL) angleOffs = csXyz::Zero; else angleOffs = *pAngleOffs; csXyz angle(angleOffs); angle.y += parentAngleY; pos.x += posOffs.z * cM_ssin(parentAngleY) + posOffs.x * cM_scos(parentAngleY); pos.y += posOffs.y; pos.z += posOffs.z * cM_scos(parentAngleY) - posOffs.x * cM_ssin(parentAngleY); return fopAcM_createChild(pProcNameString, parentPcId, parameter, &pos, roomNo, &angle, pScale, createFunc); } /* 80024B78-80024CA0 .text fopAcM_createHeap__FP10fopAc_ac_cUlUl */ s32 fopAcM_createHeap(fopAc_ac_c* i_this, u32 size, u32 align) { JUT_ASSERT(0x33b, i_this); JUT_ASSERT(0x33c, i_this->heap == NULL); fopAcM_Log(i_this, "アクターのヒープの生成"); if (align == 0) align = 0x20; i_this->heap = mDoExt_createSolidHeapFromGameToCurrent(size, align); if (i_this->heap == 0) { OSReport_Error("fopAcM_createHeap 確保失敗\n"); JUT_CONFIRM(0x34c, i_this->heap != 0); return FALSE; } return TRUE; } /* 80024CA0-80024CD4 .text fopAcM_adjustHeap__FP10fopAc_ac_c */ void fopAcM_adjustHeap(fopAc_ac_c* i_this) { mDoExt_restoreCurrentHeap(); mDoExt_adjustSolidHeap(i_this->heap); } /* 80024CD4-80024D24 .text fopAcM_DeleteHeap__FP10fopAc_ac_c */ void fopAcM_DeleteHeap(fopAc_ac_c* i_this) { /* "Destroying Actor Heap" */ fopAcM_Log(i_this, "アクターのヒープの破壊"); if (i_this->heap != NULL) { mDoExt_destroySolidHeap(i_this->heap); i_this->heap = NULL; } } namespace fopAcM { bool HeapAdjustEntry = false; bool HeapAdjustVerbose = false; bool HeapAdjustQuiet = false; } /* 80024D24-800250E4 .text fopAcM_entrySolidHeap__FP10fopAc_ac_cPFP10fopAc_ac_c_iUl */ bool fopAcM_entrySolidHeap(fopAc_ac_c* i_this, heapCallbackFunc createHeapCB, u32 estimatedHeapSize) { const char * pProcNameString = fopAcM_getProcNameString(i_this); JKRSolidHeap * heap = NULL; if (estimatedHeapSize != 0) { heap = mDoExt_createSolidHeapFromGameToCurrent(estimatedHeapSize, 0x20); if (heap != NULL) { bool result = createHeapCB(i_this); if (heap->getFreeSize() >= 0x20) JKRHeap::alloc(0x20, 0, NULL); mDoExt_restoreCurrentHeap(); if (!result) { if (!fopAcM::HeapAdjustQuiet) { // "Entry failed with estimated heap size (%08x). [%s]\n" OSReport_Error("見積もりヒープサイズ(%08x)で登録失敗しました。[%s]\n", estimatedHeapSize, pProcNameString); } mDoExt_destroySolidHeap(heap); heap = NULL; } else { u32 allocSize = ALIGN_NEXT(heap->getSize() - heap->getFreeSize(), 0x20); if (estimatedHeapSize < allocSize + 0x40) { mDoExt_adjustSolidHeap(heap); i_this->heap = heap; return true; } if (fopAcM::HeapAdjustVerbose) { // "The estimated heap size leaves too much free space. %08x %08x\n\x1b[m" OSReport_Warning("見積もりヒープサイズでは空きが多すぎます。 %08x %08x\n\x1b[m", allocSize, estimatedHeapSize); } } } else { if (!fopAcM::HeapAdjustQuiet) { // "Failed to allocate the estimated heap size.\n" OSReport_Warning("見積もりヒープが確保できませんでした。\n"); } } } if (heap == NULL) { heap = mDoExt_createSolidHeapFromGameToCurrent(-1, 0x20); JUT_ASSERT(0x453, heap); bool result = createHeapCB(i_this); mDoExt_restoreCurrentHeap(); if (!result) { // "Entry failed with the max allocatable heap size. [%s]\n" OSReport_Error("最大空きヒープサイズで登録失敗。[%s]\n", pProcNameString); mDoExt_destroySolidHeap(heap); return false; } if (!fopAcM::HeapAdjustQuiet) heap->getFreeSize(); } if (heap != NULL) { if (!fopAcM::HeapAdjustEntry) { mDoExt_adjustSolidHeap(heap); i_this->heap = heap; return true; } // If fopAcM::HeapAdjustEntry is set, try to reallocate everything a second time. // This time we set the estimated maximum heap size to the exact size allocated last time. JKRSolidHeap * heap1 = NULL; u32 allocSize = ALIGN_NEXT(heap->getSize() - heap->getFreeSize(), 0x10); if (allocSize + 0x10 + sizeof(JKRSolidHeap) < mDoExt_getGameHeap()->getFreeSize()) heap1 = mDoExt_createSolidHeapFromGameToCurrent(allocSize, 0x20); if (heap1 != NULL) { if (heap1 < heap) { // The exact size heap allocated successfully, and it is located before the original (larger) heap. mDoExt_destroySolidHeap(heap); heap = NULL; bool result = createHeapCB(i_this); mDoExt_restoreCurrentHeap(); JUT_ASSERT(0x48d, result != FALSE); if (result == FALSE) { // "Entry failed with the exact size heap? (Bug)\n" OSReport_Error("ぴったりサイズで、登録失敗?(バグ)\n"); mDoExt_destroySolidHeap(heap1); heap1 = NULL; } } else { mDoExt_restoreCurrentHeap(); mDoExt_destroySolidHeap(heap1); heap1 = NULL; } } if (heap1 != NULL) { mDoExt_adjustSolidHeap(heap1); i_this->heap = heap1; return true; } if (heap != NULL) { mDoExt_adjustSolidHeap(heap); i_this->heap = heap; return true; } // "Buggy!\n" OSReport_Error("ばぐばぐです\n"); JUT_ASSERT(0x4b5, FALSE); } // "fopAcM_entrySolidHeap failed. [%s]\n" OSReport_Error("fopAcM_entrySolidHeap だめでした [%s]\n", pProcNameString); return false; } /* 800250E4-80025100 .text fopAcM_setCullSizeBox__FP10fopAc_ac_cffffff */ void fopAcM_setCullSizeBox(fopAc_ac_c* i_this, f32 minX, f32 minY, f32 minZ, f32 maxX, f32 maxY, f32 maxZ) { i_this->cull.box.min.x = minX; i_this->cull.box.min.y = minY; i_this->cull.box.min.z = minZ; i_this->cull.box.max.x = maxX; i_this->cull.box.max.y = maxY; i_this->cull.box.max.z = maxZ; } /* 80025100-80025114 .text fopAcM_setCullSizeSphere__FP10fopAc_ac_cffff */ void fopAcM_setCullSizeSphere(fopAc_ac_c* i_this, f32 x, f32 y, f32 z, f32 r) { i_this->cull.sphere.center.x = x; i_this->cull.sphere.center.y = y; i_this->cull.sphere.center.z = z; i_this->cull.sphere.radius = r; } /* 80025114-80025144 .text fopAcM_addAngleY__FP10fopAc_ac_css */ bool fopAcM_addAngleY(fopAc_ac_c* i_this, short target, short step) { return cLib_chaseAngleS(&i_this->current.angle.y, target, step); } /* 80025144-800251A0 .text fopAcM_calcSpeed__FP10fopAc_ac_c */ void fopAcM_calcSpeed(fopAc_ac_c* i_this) { f32 speedF = fopAcM_GetSpeedF(i_this); f32 gravity = fopAcM_GetGravity(i_this); f32 xSpeed = speedF * cM_ssin(i_this->current.angle.y); f32 ySpeed = i_this->speed.y + gravity; f32 zSpeed = speedF * cM_scos(i_this->current.angle.y); if (ySpeed < fopAcM_GetMaxFallSpeed(i_this)) ySpeed = fopAcM_GetMaxFallSpeed(i_this); fopAcM_SetSpeed(i_this, xSpeed, ySpeed, zSpeed); } /* 800251A0-8002520C .text fopAcM_posMove__FP10fopAc_ac_cPC4cXyz */ void fopAcM_posMove(fopAc_ac_c* i_this, const cXyz* move) { i_this->current.pos.x += i_this->speed.x; i_this->current.pos.y += i_this->speed.y; i_this->current.pos.z += i_this->speed.z; if (move != NULL) { i_this->current.pos.x += move->x; i_this->current.pos.y += move->y; i_this->current.pos.z += move->z; } } /* 8002520C-80025250 .text fopAcM_posMoveF__FP10fopAc_ac_cPC4cXyz */ void fopAcM_posMoveF(fopAc_ac_c* i_this, const cXyz* move) { fopAcM_calcSpeed(i_this); fopAcM_posMove(i_this, move); } /* 80025250-80025278 .text fopAcM_searchActorAngleY__FP10fopAc_ac_cP10fopAc_ac_c */ s16 fopAcM_searchActorAngleY(fopAc_ac_c* i_this, fopAc_ac_c* i_other) { return cLib_targetAngleY(&i_this->current.pos, &i_other->current.pos); } /* 80025278-800252BC .text fopAcM_seenActorAngleY__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_seenActorAngleY(fopAc_ac_c* i_this, fopAc_ac_c* i_other) { s16 angleY = cLib_targetAngleY(&i_this->current.pos, &i_other->current.pos); return abs((s16)(angleY - i_this->shape_angle.y)); } /* 800252BC-80025370 .text fopAcM_searchActorDistance__FP10fopAc_ac_cP10fopAc_ac_c */ f32 fopAcM_searchActorDistance(fopAc_ac_c* i_this, fopAc_ac_c* i_other) { cXyz delta = i_other->current.pos - i_this->current.pos; return delta.abs(); } /* 80025370-800253C0 .text fopAcM_searchActorDistance2__FP10fopAc_ac_cP10fopAc_ac_c */ f32 fopAcM_searchActorDistance2(fopAc_ac_c* i_this, fopAc_ac_c* i_other) { cXyz delta = i_other->current.pos - i_this->current.pos; return delta.abs2(); } /* 800253C0-80025470 .text fopAcM_searchActorDistanceXZ__FP10fopAc_ac_cP10fopAc_ac_c */ f32 fopAcM_searchActorDistanceXZ(fopAc_ac_c* i_this, fopAc_ac_c* i_other) { cXyz* this_pos = fopAcM_GetPosition_p(i_this); cXyz* other_pos = fopAcM_GetPosition_p(i_other); return (*other_pos - *this_pos).absXZ(); } /* 80025470-800254BC .text fopAcM_searchActorDistanceXZ2__FP10fopAc_ac_cP10fopAc_ac_c */ f32 fopAcM_searchActorDistanceXZ2(fopAc_ac_c* i_this, fopAc_ac_c* i_other) { cXyz* this_pos = fopAcM_GetPosition_p(i_this); cXyz* other_pos = fopAcM_GetPosition_p(i_other); return (*other_pos - *this_pos).abs2XZ(); } /* 800254BC-800255B4 .text fopAcM_rollPlayerCrash__FP10fopAc_ac_cfUl */ s32 fopAcM_rollPlayerCrash(fopAc_ac_c* i_this, f32 distAdjust, u32 flag) { f32 maxDist = distAdjust + 40.0f; f32 xzDist2 = fopAcM_searchPlayerDistanceXZ2(i_this); f32 yDist = fopAcM_searchPlayerDistanceY(i_this); if (xzDist2 < maxDist*maxDist && yDist > -100.0f && yDist < 200.0f) { daPy_py_c* player = (daPy_py_c*)dComIfGp_getPlayer(0); s16 angle = fopAcM_searchPlayerAngleY(i_this); if (cM_scos(player->current.angle.y - angle) < -0.9f) { if (fopAcM_GetName(player) == PROC_PLAYER) { player->onFrollCrashFlg(flag); return TRUE; } } } return FALSE; } /* 800255B4-80025660 .text fopAcM_checkCullingBox__FPA4_fffffff */ s32 fopAcM_checkCullingBox(Mtx pMtx, f32 x0, f32 y0, f32 z0, f32 x1, f32 y1, f32 z1) { Vec p0 = { x0, y0, z0 }; Vec p1 = { x1, y1, z1 }; Mtx viewMtx; MTXConcat(j3dSys.mViewMtx, pMtx, viewMtx); return mDoLib_clipper::clip(viewMtx, &p1, &p0) != 0; } static l_HIO l_hio; static fopAc_cullSizeBox l_cullSizeBox[14] = { /* fopAc_CULLBOX_0_e */ fopAc_cullSizeBox(cXyz(-40.0f, 0.0f, -40.0f), cXyz(40.0f, 125.0f, 40.0f)), /* fopAc_CULLBOX_1_e */ fopAc_cullSizeBox(cXyz(-25.0f, 0.0f, -25.0f), cXyz(25.0f, 50.0f, 25.0f)), /* fopAc_CULLBOX_2_e */ fopAc_cullSizeBox(cXyz(-50.0f, 0.0f, -50.0f), cXyz(50.0f, 100.0f, 50.0f)), /* fopAc_CULLBOX_3_e */ fopAc_cullSizeBox(cXyz(-75.0f, 0.0f, -75.0f), cXyz(75.0f, 150.0f, 75.0f)), /* fopAc_CULLBOX_4_e */ fopAc_cullSizeBox(cXyz(-100.0f, 0.0f, -100.0f), cXyz(100.0f, 800.0f, 100.0f)), /* fopAc_CULLBOX_5_e */ fopAc_cullSizeBox(cXyz(-125.0f, 0.0f, -125.0f), cXyz(125.0f, 250.0f, 125.0f)), /* fopAc_CULLBOX_6_e */ fopAc_cullSizeBox(cXyz(-150.0f, 0.0f, -150.0f), cXyz(150.0f, 300.0f, 150.0f)), /* fopAc_CULLBOX_7_e */ fopAc_cullSizeBox(cXyz(-200.0f, 0.0f, -200.0f), cXyz(200.0f, 400.0f, 200.0f)), /* fopAc_CULLBOX_8_e */ fopAc_cullSizeBox(cXyz(-600.0f, 0.0f, -600.0f), cXyz(600.0f, 900.0f, 600.0f)), /* fopAc_CULLBOX_9_e */ fopAc_cullSizeBox(cXyz(-250.0f, 0.0f, -50.0f), cXyz(250.0f, 450.0f, 50.0f)), /* fopAc_CULLBOX_10_e */ fopAc_cullSizeBox(cXyz(-60.0f, 0.0f, -20.0f), cXyz(40.0f, 130.0f, 150.0f)), /* fopAc_CULLBOX_11_e */ fopAc_cullSizeBox(cXyz(-75.0f, 0.0f, -75.0f), cXyz(75.0f, 210.0f, 75.0f)), /* fopAc_CULLBOX_12_e */ fopAc_cullSizeBox(cXyz(-70.0f, -100.0f, -80.0f), cXyz(70.0f, 240.0f, 100.0f)), /* fopAc_CULLBOX_13_e */ fopAc_cullSizeBox(cXyz(-60.0f, -20.0f, -60.0f), cXyz(60.0f, 160.0f, 60.0f)), }; static fopAc_cullSizeSphere l_cullSizeSphere[8] = { /* fopAc_CULLSPHERE_0_e */ fopAc_cullSizeSphere(cXyz(0.0f, 0.0f, 0.0f), 80.0f), /* fopAc_CULLSPHERE_1_e */ fopAc_cullSizeSphere(cXyz(0.0f, 0.0f, 0.0f), 50.0f), /* fopAc_CULLSPHERE_2_e */ fopAc_cullSizeSphere(cXyz(0.0f, 0.0f, 0.0f), 100.0f), /* fopAc_CULLSPHERE_3_e */ fopAc_cullSizeSphere(cXyz(0.0f, 0.0f, 0.0f), 150.0f), /* fopAc_CULLSPHERE_4_e */ fopAc_cullSizeSphere(cXyz(0.0f, 0.0f, 0.0f), 200.0f), /* fopAc_CULLSPHERE_5_e */ fopAc_cullSizeSphere(cXyz(0.0f, 0.0f, 0.0f), 250.0f), /* fopAc_CULLSPHERE_6_e */ fopAc_cullSizeSphere(cXyz(0.0f, 0.0f, 0.0f), 300.0f), /* fopAc_CULLSPHERE_7_e */ fopAc_cullSizeSphere(cXyz(0.0f, 0.0f, 0.0f), 400.0f), }; static void dummy() { static Vec dummy_4863; static Vec min; static Vec dummy_4899; static Vec max; } /* 80025660-800259A8 .text fopAcM_cullingCheck__FP10fopAc_ac_c */ s32 fopAcM_cullingCheck(fopAc_ac_c* i_this) { MtxP pMtx; if (fopAcM_GetMtx(i_this) == NULL) { pMtx = j3dSys.getViewMtx(); } else { Mtx mtx; cMtx_concat(j3dSys.getViewMtx(), fopAcM_GetMtx(i_this), mtx); pMtx = mtx; } f32 cullFar = fopAcM_getCullSizeFar(i_this); if (dComIfGp_event_runCheck()) { cullFar *= dComIfGp_event_getCullRate(); } if (fopAcM_CULLSIZE_IS_BOX(fopAcM_GetCullSize(i_this))) { if (fopAcM_GetCullSize(i_this) == fopAc_CULLBOX_CUSTOM_e) { if (fopAcM_getCullSizeFar(i_this) > 0.0f) { mDoLib_clipper::changeFar(cullFar * mDoLib_clipper::getFar()); s32 ret = mDoLib_clipper::clip(pMtx, fopAcM_getCullSizeBoxMax(i_this), fopAcM_getCullSizeBoxMin(i_this)); mDoLib_clipper::resetFar(); return ret; } else { return mDoLib_clipper::clip(pMtx, fopAcM_getCullSizeBoxMax(i_this), fopAcM_getCullSizeBoxMin(i_this)); } } else { fopAc_cullSizeBox& cullBox = l_cullSizeBox[fopAcM_CULLSIZE_IDX(fopAcM_GetCullSize(i_this))]; if (fopAcM_getCullSizeFar(i_this) > 0.0f) { mDoLib_clipper::changeFar(cullFar * mDoLib_clipper::getFar()); s32 ret = mDoLib_clipper::clip(pMtx, &cullBox.max, &cullBox.min); mDoLib_clipper::resetFar(); return ret; } else { return mDoLib_clipper::clip(pMtx, &cullBox.max, &cullBox.min); } } } else { // Sphere if (fopAcM_GetCullSize(i_this) == fopAc_CULLSPHERE_CUSTOM_e) { if (fopAcM_getCullSizeFar(i_this) > 0.0f) { mDoLib_clipper::changeFar(cullFar * mDoLib_clipper::getFar()); f32 radius = fopAcM_getCullSizeSphereR(i_this); Vec center = *fopAcM_getCullSizeSphereCenter(i_this); s32 ret = mDoLib_clipper::clip(pMtx, center, radius); mDoLib_clipper::resetFar(); return ret; } else { f32 radius = fopAcM_getCullSizeSphereR(i_this); return mDoLib_clipper::clip(pMtx, *fopAcM_getCullSizeSphereCenter(i_this), radius); } } else { fopAc_cullSizeSphere& cullSphere = l_cullSizeSphere[fopAcM_CULLSIZE_Q_IDX(fopAcM_GetCullSize(i_this))]; if (fopAcM_getCullSizeFar(i_this) > 0.0f) { mDoLib_clipper::changeFar(cullFar * mDoLib_clipper::getFar()); f32 radius = cullSphere.radius; Vec center = cullSphere.center; s32 ret = mDoLib_clipper::clip(pMtx, center, radius); mDoLib_clipper::resetFar(); return ret; } else { f32 radius = cullSphere.radius; return mDoLib_clipper::clip(pMtx, cullSphere.center, radius); } } } } /* 800259A8-800259F8 .text fopAcM_orderTalkEvent__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_orderTalkEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { return dComIfGp_event_order(dEvtType_TALK_e, 0x1FF, 0, 0x14F, i_this, i_partner); } /* 800259F8-80025A48 .text fopAcM_orderTalkXBtnEvent__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_orderTalkXBtnEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { return dComIfGp_event_order(dEvtType_SHOWITEM_X_e, 0x1F4, 0, 0x14F, i_this, i_partner); } /* 80025A48-80025A98 .text fopAcM_orderTalkYBtnEvent__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_orderTalkYBtnEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { return dComIfGp_event_order(dEvtType_SHOWITEM_Y_e, 0x1F4, 0, 0x14F, i_this, i_partner); } /* 80025A98-80025AE8 .text fopAcM_orderTalkZBtnEvent__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_orderTalkZBtnEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { return dComIfGp_event_order(dEvtType_SHOWITEM_Z_e, 0x1F4, 0, 0x14F, i_this, i_partner); } /* 80025AE8-80025B3C .text fopAcM_orderZHintEvent__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_orderZHintEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { return dComIfGp_event_order(dEvtType_TALK_e, 0x1FF, 0, 0xFFFF, i_this, i_partner); } /* 80025B3C-80025B8C .text fopAcM_orderSpeakEvent__FP10fopAc_ac_c */ s32 fopAcM_orderSpeakEvent(fopAc_ac_c* i_this) { return dComIfGp_event_order(dEvtType_TALK_e, 0x1EA, 0, 0x14F, dComIfGp_getPlayer(0), i_this); } /* 80025B8C-80025BE0 .text fopAcM_orderDoorEvent__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_orderDoorEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { return dComIfGp_event_order(dEvtType_DOOR_e, 0xFF, 0, 0xFFFF, i_this, i_partner); } /* 80025BE0-80025C34 .text fopAcM_orderCatchEvent__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_orderCatchEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { return dComIfGp_event_order(dEvtType_CATCH_e, 1, 0, 0xFFFF, i_this, i_partner); } /* 80025C34-80025CC8 .text fopAcM_orderOtherEvent2__FP10fopAc_ac_cPcUsUs */ s32 fopAcM_orderOtherEvent2(fopAc_ac_c* i_this, char* pEventName, u16 flag, u16 hind) { u16 prio = dComIfGp_evmng_getEventPrio(dComIfGp_evmng_getEventIdx(pEventName)); if (prio == 0) prio = 0xFF; return dComIfGp_event_orderOld(dEvtType_OTHER_e, prio, flag, hind, i_this, dComIfGp_getPlayer(0), pEventName); } /* 80025CC8-80025D28 .text fopAcM_orderChangeEvent__FP10fopAc_ac_cPcUsUs */ s32 fopAcM_orderChangeEvent(fopAc_ac_c* i_this, char* pEventName, u16 flag, u16 hind) { return fopAcM_orderChangeEventId(i_this, dComIfGp_evmng_getEventIdx(pEventName), flag, hind); } /* 80025D28-80025D94 .text fopAcM_orderChangeEvent__FP10fopAc_ac_cP10fopAc_ac_cPcUsUs */ s32 fopAcM_orderChangeEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner, char* pEventName, u16 flag, u16 hind) { return fopAcM_orderChangeEventId(i_this, i_partner, dComIfGp_evmng_getEventIdx(pEventName), flag, hind); } /* 80025D94-80025E1C .text fopAcM_orderChangeEventId__FP10fopAc_ac_csUsUs */ s32 fopAcM_orderChangeEventId(fopAc_ac_c* i_this, s16 eventIdx, u16 flag, u16 hind) { u16 prio = dComIfGp_evmng_getEventPrio(eventIdx); if (prio == 0) prio = 0xFF; return dComIfGp_event_order(dEvtType_CHANGE_e, prio, flag, hind, i_this, dComIfGp_getPlayer(0), eventIdx); } /* 80025E1C-80025EA4 .text fopAcM_orderChangeEventId__FP10fopAc_ac_cP10fopAc_ac_csUsUs */ s32 fopAcM_orderChangeEventId(fopAc_ac_c* i_this, fopAc_ac_c* i_partner, s16 eventIdx, u16 flag, u16 hind) { u16 prio = dComIfGp_evmng_getEventPrio(eventIdx); if (prio == 0) prio = 0xFF; return dComIfGp_event_order(dEvtType_CHANGE_e, prio, flag, hind, i_this, i_partner, eventIdx); } /* 80025EA4-80025F3C .text fopAcM_orderOtherEventId__FP10fopAc_ac_csUcUsUsUs */ s32 fopAcM_orderOtherEventId(fopAc_ac_c* i_this, s16 eventIdx, u8 infoIdx, u16 hind, u16 priority, u16 flag) { u16 prio; if (priority != 0) { prio = priority; } else { prio = dComIfGp_evmng_getEventPrio(eventIdx); if (prio == 0) prio = 0xFF; } return dComIfGp_event_order(dEvtType_OTHER_e, prio, flag, hind, i_this, dComIfGp_getPlayer(0), eventIdx, infoIdx); } /* 80025F3C-80025F9C .text fopAcM_orderPotentialEvent__FP10fopAc_ac_cUsUsUs */ s32 fopAcM_orderPotentialEvent(fopAc_ac_c* i_this, u16 flag, u16 hind, u16 priority) { if (priority == 0) priority = 0xFF; return dComIfGp_event_order(dEvtType_POTENTIAL_e, priority, flag, hind, i_this, dComIfGp_getPlayer(0)); } /* 80025F9C-80025FF0 .text fopAcM_orderItemEvent__FP10fopAc_ac_c */ s32 fopAcM_orderItemEvent(fopAc_ac_c* i_this) { return dComIfGp_event_order(dEvtType_ITEM_e, 0xFF, 0, 0xFFFF, dComIfGp_getPlayer(0), i_this); } /* 80025FF0-80026044 .text fopAcM_orderTreasureEvent__FP10fopAc_ac_cP10fopAc_ac_c */ s32 fopAcM_orderTreasureEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { return dComIfGp_event_order(dEvtType_TREASURE_e, 0xFF, 0, 0xFFFF, i_this, i_partner); } /* 80026044-80026074 .text fopAcM_getTalkEventPartner__FP10fopAc_ac_c */ fopAc_ac_c* fopAcM_getTalkEventPartner(fopAc_ac_c*) { return (fopAc_ac_c*)dComIfGp_event_getTalkPartner(); } /* 80026074-800260A4 .text fopAcM_getItemEventPartner__FP10fopAc_ac_c */ fopAc_ac_c* fopAcM_getItemEventPartner(fopAc_ac_c*) { return (fopAc_ac_c*)dComIfGp_event_getItemPartner(); } /* 800260A4-80026118 .text fopAcM_getEventPartner__FP10fopAc_ac_c */ fopAc_ac_c* fopAcM_getEventPartner(fopAc_ac_c* i_this) { if (dComIfGp_event_getPt1() != i_this) return (fopAc_ac_c*)dComIfGp_event_getPt1(); return (fopAc_ac_c*)dComIfGp_event_getPt2(); } /* 80026118-800261E8 .text fopAcM_createItemForPresentDemo__FP4cXyziUciiP5csXyzP4cXyz */ fpc_ProcID fopAcM_createItemForPresentDemo(cXyz* pos, int i_itemNo, u8 argFlag, int roomNo, int param_5, csXyz* angle, cXyz* scale) { JUT_ASSERT(2413, 0 <= i_itemNo && i_itemNo < 256); dComIfGp_event_setGtItm(i_itemNo); if (i_itemNo == dItem_NONE_e) { return fpcM_ERROR_PROCESS_ID_e; } return fopAcM_createDemoItem(pos, i_itemNo, roomNo, angle, param_5, scale, argFlag); } /* 800261E8-800262B4 .text fopAcM_createItemForTrBoxDemo__FP4cXyziiiP5csXyzP4cXyz */ fpc_ProcID fopAcM_createItemForTrBoxDemo(cXyz* pos, int i_itemNo, int roomNo, int param_5, csXyz* angle, cXyz* scale) { JUT_ASSERT(2458, 0 <= i_itemNo && i_itemNo < 256); dComIfGp_event_setGtItm(i_itemNo); if (i_itemNo == dItem_NONE_e) { return fpcM_ERROR_PROCESS_ID_e; } return fopAcM_createDemoItem(pos, i_itemNo, roomNo, angle, param_5, scale, 0x00); } /* 800262B4-80026694 .text fopAcM_createItemFromTable__FP4cXyziiiiP5csXyziP4cXyz */ fpc_ProcID fopAcM_createItemFromTable(cXyz* p_pos, int i_itemNo, int i_itemBitNo, int roomNo, int type, csXyz* p_angle, int action, cXyz* p_scale) { JUT_ASSERT(2514, 0 <= i_itemNo && i_itemNo < 64 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127); static cXyz fairy_offset_tbl[3] = { cXyz(40.0f, 0.0f, 0.0f), cXyz(-40.0f, 0.0f, 0.0f), cXyz(0.0f, 0.0f, 40.0f), }; cXyz pos(0.0f, 0.0f, 0.0f); csXyz angle(0, 0, 0); if (i_itemNo >= 0x20 && i_itemNo <= 0x3E) { ItemTableList* itemTableList = dComIfGp_getItemTable(); int tableIdx = i_itemNo - 0x20; switch (tableIdx) { case 0x01: case 0x02: case 0x03: case 0x04: { int life = dComIfGs_getLife() * 100; int max = dComIfGs_getMaxLife() & 0xFC; u8 lifePercent = life / max; if (lifePercent != 0 && lifePercent <= 20) { tableIdx = 4; } else if (lifePercent > 20 && lifePercent <= 40) { tableIdx = 3; } else if (lifePercent > 40 && lifePercent <= 80) { tableIdx = 2; } else if (lifePercent > 80 && lifePercent <= 100) { tableIdx = 1; } break; } case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: if (itemTableList == NULL) { return fpcM_ERROR_PROCESS_ID_e; } u8* pItemTable = itemTableList->mItemTables[tableIdx]; u32 itemNo; fpc_ProcID lastItemPID; for (int i = 0; (itemNo = *pItemTable) != dItem_NONE_e && i < 0x10; pItemTable++, i++) { if (p_pos) { pos = *p_pos; } if (p_angle) { angle = *p_angle; } if (tableIdx == dItem_RECOVER_FAIRY_e) { // Bug: This condition never gets triggered. // They meant to check if (itemNo == dItem_RECOVER_FAIRY_e) so that the // 3x fairies drop table (table 0x14) spawns them in a triangle. // But instead they check if the table index is equal to // 0x16/dItem_RECOVER_FAIRY_e, which will never be true. pos += fairy_offset_tbl[i]; angle.y = cM_rndF((f32)0x7FFE); } itemNo = getItemNoByLife((s8)itemNo); daItem_c* item = (daItem_c*)fopAcM_fastCreateItem2(&pos, itemNo, i_itemBitNo, roomNo, type, &angle, daItemAct_8_e); lastItemPID = fopAcM_GetID(item); if (lastItemPID == fpcM_ERROR_PROCESS_ID_e) { break; } } return lastItemPID; } int itemIdx = (int)cM_rndF(15.9999f); i_itemNo = itemTableList->mItemTables[tableIdx][itemIdx]; } if (i_itemNo == 0x3F || i_itemNo == 0xFF) { return fpcM_ERROR_PROCESS_ID_e; } else { u32 itemNo = getItemNoByLife(i_itemNo); daItem_c* item = (daItem_c*)fopAcM_fastCreateItem2(p_pos, itemNo, i_itemBitNo, roomNo, type, p_angle, action, p_scale); return fopAcM_GetID(item); } } /* 80026694-800267C8 .text fopAcM_createRaceItemFromTable__FP4cXyziiiP5csXyzP4cXyzi */ fpc_ProcID fopAcM_createRaceItemFromTable(cXyz* pos, int i_itemNo, int i_itemBitNo, int i_roomNo, csXyz* angle, cXyz* scale, int param_7) { JUT_ASSERT(2660, 0 <= i_itemNo && i_itemNo < 64 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127); if (i_itemNo >= 0x20 && i_itemNo <= 0x3E) { ItemTableList* itemTableList = dComIfGp_getItemTable(); int itemIdx = (int)cM_rndF(15.9999f); int tableIdx = i_itemNo - 0x20; i_itemNo = itemTableList->mItemTables[tableIdx][itemIdx]; } if (i_itemNo == 0x3F || i_itemNo == 0xFF) { return fpcM_ERROR_PROCESS_ID_e; } i_itemNo = getItemNoByLife(i_itemNo); return fopAcM_createRaceItem(pos, i_itemNo, i_itemBitNo, angle, i_roomNo, scale, param_7); } /* 800267C8-8002688C .text fopAcM_createShopItem__FP4cXyziP5csXyziP4cXyzPFPv_i */ fpc_ProcID fopAcM_createShopItem(cXyz* pos, int i_itemNo, csXyz* angle, int roomNo, cXyz* scale, createFunc createFunc) { JUT_ASSERT(2716, 0 <= i_itemNo && i_itemNo < 256); if (i_itemNo == dItem_NONE_e) { return fpcM_ERROR_PROCESS_ID_e; } return fopAcM_create(PROC_ShopItem, i_itemNo, pos, roomNo, angle, scale, -1, createFunc); } /* 8002688C-80026980 .text fopAcM_createRaceItem__FP4cXyziiP5csXyziP4cXyzi */ fpc_ProcID fopAcM_createRaceItem(cXyz* pos, int i_itemNo, int i_itemBitNo, csXyz* angle, int roomNo, cXyz* scale, int param_7) { JUT_ASSERT(2763, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127); if (i_itemNo == dItem_NONE_e) { return fpcM_ERROR_PROCESS_ID_e; } i_itemNo = check_itemno(i_itemNo); u32 params = (i_itemBitNo & 0x7F) << 0x08 | (i_itemNo & 0xFF) | (param_7 & 0xF) << 0xF; return fopAcM_create(PROC_RACEITEM, params, pos, roomNo, angle, scale); } /* 80026980-80026A68 .text fopAcM_createDemoItem__FP4cXyziiP5csXyziP4cXyzUc */ fpc_ProcID fopAcM_createDemoItem(cXyz* pos, int i_itemNo, int i_itemBitNo, csXyz* i_angle, int i_roomNo, cXyz* i_scale, u8 i_argFlag) { JUT_ASSERT(2813, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127); if (i_itemNo == dItem_NONE_e) { return fpcM_ERROR_PROCESS_ID_e; } u32 params = (i_itemNo & 0xFF) | (i_itemBitNo & 0x7F) << 0x08 | (i_argFlag & 0xFF) << 0x10; return fopAcM_create(PROC_Demo_Item, params, pos, i_roomNo, i_angle, i_scale); } /* 80026A68-80026ADC .text fopAcM_createItemForBoss__FP4cXyziiP5csXyzP4cXyzi */ fpc_ProcID fopAcM_createItemForBoss(cXyz* pos, int unused, int roomNo, csXyz* angle, cXyz* scale, int param_6) { switch (param_6) { case 1: return fopAcM_createItem(pos, dItem_HEART_CONTAINER_e, -1, roomNo, daItemType_3_e, angle, daItemAct_BOSS_e, scale); case 0: // Disappear default: return fopAcM_createItem(pos, dItem_HEART_CONTAINER_e, -1, roomNo, daItemType_3_e, angle, daItemAct_BOSS_DISAPPEAR_e, scale); } } /* 80026ADC-80026C90 .text fopAcM_createItem__FP4cXyziiiiP5csXyziP4cXyz */ fpc_ProcID fopAcM_createItem(cXyz* pos, int i_itemNo, int i_itemBitNo, int roomNo, int type, csXyz* angle, int action, cXyz* scale) { int switchNo = 0xFF; int switchNo2 = 0xFF; JUT_ASSERT(2915, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127); if (i_itemNo == dItem_NONE_e) { return fpcM_ERROR_PROCESS_ID_e; } csXyz prmAngle = csXyz::Zero; if (angle) { prmAngle = *angle; } prmAngle.z = switchNo; u8 itemNo = check_itemno(i_itemNo); u32 params = MAKE_ITEM_PARAMS(itemNo, i_itemBitNo, switchNo2, type, action); switch (i_itemNo) { case dItem_RECOVER_FAIRY_e: return fopAcM_create(PROC_NPC_FA1, 1, pos, roomNo, angle, scale); case dItem_TRIPLE_HEART_e: // Make the two extra hearts first, then fall-through to make the third heart as normal. for (int i = 0; i < 2; i++) { fopAcM_create(PROC_ITEM, params, pos, roomNo, &prmAngle, scale); } // Fall-through default: return fopAcM_create(PROC_ITEM, params, pos, roomNo, &prmAngle, scale); } } /* 80026C90-80026E5C .text fopAcM_fastCreateItem2__FP4cXyziiiiP5csXyziP4cXyz */ void* fopAcM_fastCreateItem2(cXyz* pos, int i_itemNo, int i_itemBitNo, int roomNo, int type, csXyz* angle, int action, cXyz* scale) { int switchNo = 0xFF; int switchNo2 = 0xFF; JUT_ASSERT(2995, 0 <= i_itemNo && i_itemNo < 256 && (-1 <= i_itemBitNo && i_itemBitNo <= 79) || i_itemBitNo == 127); int i; csXyz prmAngle = csXyz::Zero; if (i_itemNo == dItem_NONE_e) { return NULL; } if (angle) { prmAngle = *angle; } prmAngle.z = switchNo; u8 itemNo = check_itemno(i_itemNo); u32 params = MAKE_ITEM_PARAMS(itemNo, i_itemBitNo, switchNo2, type, action); switch (i_itemNo) { case dItem_RECOVER_FAIRY_e: return fopAcM_fastCreate(PROC_NPC_FA1, 1, pos, roomNo, angle, scale); case dItem_TRIPLE_HEART_e: // Make the two extra hearts first, then fall-through to make the third heart as normal. for (i = 0; i < 2; i++) { fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmAngle, scale); } // Fall-through default: return fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmAngle, scale); } } /* 80026E5C-80026F5C .text fopAcM_createItemForKP2__FP4cXyziiP5csXyzP4cXyzfffUs */ fopAc_ac_c* fopAcM_createItemForKP2(cXyz* pos, int i_itemNo, int roomNo, csXyz* angle, cXyz* scale, f32 speedF, f32 speedY, f32 gravity, u16 i_itemBitNo) { JUT_ASSERT(0xc25, 0 <= i_itemNo && i_itemNo < 256); if (i_itemNo == dItem_NONE_e) return NULL; fopAc_ac_c* ac = (fopAc_ac_c*)fopAcM_fastCreate(PROC_SPC_ITEM01, i_itemNo | (i_itemBitNo & 0xFFFF) << 8, pos, roomNo, angle, scale); if (ac != NULL) { fopAcM_SetSpeedF(ac, speedF); ac->speed.y = speedY; fopAcM_SetGravity(ac, gravity); } return ac; } /* 80026F5C-80026F98 .text fopAcM_createItemForSimpleDemo__FP4cXyziiP5csXyzP4cXyzff */ daItem_c* fopAcM_createItemForSimpleDemo(cXyz* pos, int i_itemNo, int roomNo, csXyz* angle, cXyz* scale, f32 speedF, f32 speedY) { daItem_c* item = (daItem_c*)fopAcM_fastCreateItem(pos, i_itemNo, roomNo, angle, scale, speedF, speedY, -7.0f); if (item != NULL) item->setStatus(5); return item; } /* 80026F98-80027254 .text fopAcM_fastCreateItem__FP4cXyziiP5csXyzP4cXyzfffiPFPv_i */ void* fopAcM_fastCreateItem(cXyz* pos, int i_itemNo, int roomNo, csXyz* angle, cXyz* scale, f32 speedF, f32 speedY, f32 gravity, int i_itemBitNo, createFunc createFunc) { int type = daItemType_0_e; int action = daItemAct_A_e; int switchNo = 0xFF; int switchNo2 = 0xFF; JUT_ASSERT(3201, 0 <= i_itemNo && i_itemNo < 256); if (i_itemNo == dItem_NONE_e) { return NULL; } int i; u8 itemNo = check_itemno(i_itemNo); u8 itemBitNo = i_itemBitNo; u32 params = MAKE_ITEM_PARAMS(itemNo, itemBitNo, switchNo2, type, action); if (isHeart(i_itemNo)) { speedF = 2.0f * speedF; } daItem_c* item; csXyz prmAngle; switch (i_itemNo) { case dItem_RECOVER_FAIRY_e: item = (daItem_c*)fopAcM_fastCreate(PROC_NPC_FA1, 1, pos, roomNo, angle, scale); return item; case dItem_TRIPLE_HEART_e: // Make the two extra hearts first, then fall-through to make the third heart as normal. for (i = 0; i < 2; i++) { if (angle) { prmAngle = *angle; } else { prmAngle = csXyz::Zero; } prmAngle.z = switchNo; prmAngle.y += (int)cM_rndFX(0x2000); item = (daItem_c*)fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmAngle, scale, -1, createFunc); if (item) { item->speedF = speedF * (1.0f + cM_rndFX(0.3f)); item->speed.y = speedY * (1.0f + cM_rndFX(0.2f)); item->gravity = gravity; } } // Fall-through default: if (angle) { prmAngle = *angle; } else { prmAngle = csXyz::Zero; } prmAngle.z = 0xFF; item = (daItem_c*)fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmAngle, scale, -1, createFunc); if (item) { item->speedF = speedF; item->speed.y = speedY; item->gravity = gravity; } return item; } } /* 80027254-80027280 .text stealItem_CB__FPv */ BOOL stealItem_CB(void* actor) { if (actor) { daItem_c* item = (daItem_c*)actor; item->scale.setall(1.0f); item->setFlag(daItem_c::FLAG_HOOK); } return TRUE; } /* 80027280-800273D4 .text fopAcM_createStealItem__FP4cXyziiP5csXyzi */ void* fopAcM_createStealItem(cXyz* p_pos, int i_tblNo, int i_roomNo, csXyz* p_angle, int i_itemBitNo) { u8 itemNo = getEmonoItemFromLifeBallTable(i_tblNo); if (isLimitedItem(itemNo)) { if ( (i_itemBitNo == 0x1F || i_itemBitNo == -1 || i_itemBitNo == 0xFF) || ( !(i_itemBitNo == 0x1F || i_itemBitNo == -1 || i_itemBitNo == 0xFF) && fopAcM_isItemForIb(i_itemBitNo, itemNo, i_roomNo) ) ) { i_itemBitNo = -1; itemNo = getItemFromLifeBallTableWithoutEmono(i_tblNo); } } else if (isNonSavedEmono(itemNo)) { if (i_itemBitNo != 0) { itemNo = getItemFromLifeBallTableWithoutEmono(i_tblNo); } i_itemBitNo = -1; } else { if (itemNo == dItem_NONE_e) { itemNo = getItemFromLifeBallTableWithoutEmono(i_tblNo); } i_itemBitNo = -1; } return fopAcM_fastCreateItem(p_pos, itemNo, i_roomNo, p_angle, NULL, 0.0f, 0.0f, -6.0f, i_itemBitNo, stealItem_CB); } /* 800273D4-8002777C .text fopAcM_createItemFromEnemyTable__FUsiiP4cXyzP5csXyz */ void* fopAcM_createItemFromEnemyTable(u16 itemTableIdx, int i_itemBitNo, int i_roomNo, cXyz* p_pos, csXyz* p_angle) { int items[16]; int itemIdx = (int)cM_rndF(15.999f); cXyz scale = cXyz::Zero; items[0] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM0(), itemTableIdx); items[1] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM1(), itemTableIdx); items[2] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM2(), itemTableIdx); items[3] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM3(), itemTableIdx); items[4] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM4(), itemTableIdx); items[5] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM5(), itemTableIdx); items[6] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM6(), itemTableIdx); items[7] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM7(), itemTableIdx); items[8] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM8(), itemTableIdx); items[9] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM9(), itemTableIdx); items[10] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM10(), itemTableIdx); items[11] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM11(), itemTableIdx); items[12] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM12(), itemTableIdx); items[13] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM13(), itemTableIdx); items[14] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM14(), itemTableIdx); items[15] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetNITEM15(), itemTableIdx); if (isLimitedItem(items[itemIdx])) { if ( (i_itemBitNo == 0x1F || i_itemBitNo == -1 || i_itemBitNo == 0xFF) || ( !(i_itemBitNo == 0x1F || i_itemBitNo == -1 || i_itemBitNo == 0xFF) && fopAcM_isItemForIb(i_itemBitNo, items[itemIdx], i_roomNo) ) ) { i_itemBitNo = -1; items[itemIdx] = dItem_YELLOW_RUPEE_e; } } else if (isNonSavedEmono(items[itemIdx])) { if (i_itemBitNo != 0) { items[itemIdx] = getItemFromLifeBallTableWithoutEmono((u16)itemTableIdx); } i_itemBitNo = -1; } else { i_itemBitNo = -1; } items[itemIdx] = getItemNoByLife(items[itemIdx]); return fopAcM_fastCreateItem( p_pos, items[itemIdx], i_roomNo, NULL, &scale, cM_rndFX(5.0f), 50.0f + cM_rndFX(10.0f), -6.0f, i_itemBitNo ); } /* 8002777C-800278D8 .text fopAcM_createIball__FP4cXyziiP5csXyzi */ fpc_ProcID fopAcM_createIball(cXyz* p_pos, int itemTableIdx, int i_roomNo, csXyz* p_angle, int i_itemBitNo) { int dropChance = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->GetPercent(), (u16)itemTableIdx); int randPercent = cM_rndF(99.999f); if (strcmp(dComIfGp_getStartStageName(), "Cave09") == 0 || strcmp(dComIfGp_getStartStageName(), "Cave10") == 0 || strcmp(dComIfGp_getStartStageName(), "Cave11") == 0) { // Savage Labyrinth return fpcM_ERROR_PROCESS_ID_e; } if (dropChance > randPercent) { daIball_c::remove_old(); void* item = fopAcM_fastCreate( PROC_Iball, (u16)itemTableIdx | (i_itemBitNo & 0xFF) << 0x10, p_pos, i_roomNo ); return fopAcM_GetID(item); } else { void* item = fopAcM_createItemFromEnemyTable( itemTableIdx, i_itemBitNo, i_roomNo, p_pos, p_angle ); return fopAcM_GetID(item); } } /* 800278D8-80027920 .text fopAcM_createWarpFlower__FP4cXyzP5csXyziUc */ void fopAcM_createWarpFlower(cXyz* p_pos, csXyz* p_angle, int i_roomNo, u8 param_4) { u32 params = param_4; fopAcM_create(PROC_WARPFLOWER, params, p_pos, i_roomNo, p_angle); } /* 80027920-80027970 .text enemySearchJugge__FPvPv */ fopAc_ac_c * enemySearchJugge(void* ptr, void*) { if (ptr != NULL && fopAc_IsActor(ptr)) { fopAc_ac_c * i_ac = (fopAc_ac_c *)ptr; if (i_ac->group == fopAc_ENEMY_e) return i_ac; } return NULL; } /* 80027970-80027A9C .text fopAcM_myRoomSearchEnemy__FSc */ fopAc_ac_c* fopAcM_myRoomSearchEnemy(s8 roomNo) { JUT_ASSERT(0xe07, roomNo >= 0); scene_class* roomProc = fopScnM_SearchByID(dStage_roomControl_c::getStatusProcID(roomNo)); JUT_ASSERT(0xe0a, roomProc != NULL); fpc_ProcID grabProcID = daPy_getPlayerActorClass()->getGrabActorID(); fopAc_ac_c* enemy = fopAcM_SearchByID(grabProcID); if (enemy != NULL && fopAcM_GetGroup(enemy) == fopAc_ENEMY_e) return enemy; return (fopAc_ac_c*)fpcM_JudgeInLayer(fpcM_LayerID(roomProc), (fpcCtIt_JudgeFunc)enemySearchJugge, NULL); } /* 80027A9C-80027B24 .text fopAcM_createDisappear__FP10fopAc_ac_cP4cXyzUcUcUc */ fpc_ProcID fopAcM_createDisappear(fopAc_ac_c* i_actor, cXyz* p_pos, u8 i_scale, u8 i_dropType, u8 i_itemBitNo) { u32 params = (i_itemBitNo & 0xFF) << 0x10 | (i_scale & 0xFF) << 0x08 | (i_dropType & 0xFF); fopAc_ac_c* disappear = (fopAc_ac_c*)fopAcM_fastCreate(PROC_DISAPPEAR, params, p_pos, fopAcM_GetRoomNo(i_actor), fopAcM_GetAngle_p(i_actor)); if (disappear) { disappear->itemTableIdx = i_actor->itemTableIdx; } return fopAcM_GetID(disappear); } /* 80027B24-80027E28 .text fopAcM_getGroundAngle__FP10fopAc_ac_cP5csXyz */ BOOL fopAcM_getGroundAngle(fopAc_ac_c* actor, csXyz* p_angle) { // TODO: clean this up dBgS_GndChk gndChk; BOOL ret = TRUE; cXyz pos(actor->current.pos); pos.y += 50.0f; gndChk.SetPos(&pos); pos.y = dComIfG_Bgsp()->GroundCross(&gndChk); s16 targetAngleX; int targetAngleZ; if (pos.y != -G_CM3D_F_INF) { f32 origY = pos.y + 50.0f; gndChk.GetPointP()->set(pos.x, origY, pos.z + 10.0f); f32 origX = gndChk.GetPointP()->x; f32 origZ = gndChk.GetPointP()->z; f32 groundY = dComIfG_Bgsp()->GroundCross(&gndChk); if (groundY != -G_CM3D_F_INF) { targetAngleX = -cM_atan2s(groundY - pos.y, origZ - pos.z); } else { pos.y = pos.y; // ?? fakematch? ret = FALSE; } origX = pos.x + 10.0f; origY = pos.y + 50.0f; f32 tempZ = pos.z; gndChk.GetPointP()->set(origX, origY, tempZ); groundY = dComIfG_Bgsp()->GroundCross(&gndChk); if (groundY != -G_CM3D_F_INF) { targetAngleZ = cM_atan2s(groundY - pos.y, origX - pos.x); } else { ret = FALSE; } } else { ret = FALSE; } if (ret) { cLib_addCalcAngleS(&p_angle->x, targetAngleX, 4, 0x200, 0x80); cLib_addCalcAngleS(&p_angle->z, targetAngleZ, 4, 0x200, 0x80); } return ret; } /* 80027E28-80027E5C .text fopAcM_setCarryNow__FP10fopAc_ac_ci */ void fopAcM_setCarryNow(fopAc_ac_c* i_this, BOOL stageLayer) { fopAcM_OnStatus(i_this, fopAcStts_CARRY_e); if (stageLayer) { fopAcM_setStageLayer(i_this); } } /* 80027E5C-80027ED8 .text fopAcM_cancelCarryNow__FP10fopAc_ac_c */ void fopAcM_cancelCarryNow(fopAc_ac_c* i_this) { if (fopAcM_CheckStatus(i_this, fopAcStts_CARRY_e)) { fopAcM_OffStatus(i_this, fopAcStts_CARRY_e); fopAcM_setRoomLayer(i_this, fopAcM_GetRoomNo(i_this)); i_this->shape_angle.z = 0; if (dComIfGp_event_runCheck() && i_this->group != fopAc_ENEMY_e) { fopAcM_OnStatus(i_this, fopAcStts_UNK800_e); } } } /* 80027ED8-800281D8 .text fopAcM_viewCutoffCheck__FP10fopAc_ac_cf */ BOOL fopAcM_viewCutoffCheck(fopAc_ac_c* actor, f32 param_2) { if (param_2 > 0.0f) { camera_class* camera = dComIfGp_getCamera(0); cXyz delta = (camera->mLookat.mEye - actor->eyePos); if (delta.abs() > param_2) { dBgS_LinChk linChk; linChk.Set(&camera->mLookat.mEye, &actor->eyePos, actor); return dComIfG_Bgsp()->LineCross(&linChk); } } return FALSE; } /* 800281D8-800282F8 .text fopAcM_otoCheck__FP10fopAc_ac_cf */ s32 fopAcM_otoCheck(fopAc_ac_c* actor, f32 param_2) { SND_INFLUENCE* sound = dKy_Sound_get(); if (sound->field_0x14 != fpcM_ERROR_PROCESS_ID_e && sound->field_0x14 != fopAcM_GetID(actor)) { cXyz delta = (sound->field_0x0 - actor->current.pos); if (delta.abs() < param_2) { return sound->field_0xc; } } return 0; } /* 800282F8-8002833C .text fopAcM_getProcNameString__FP10fopAc_ac_c */ const char * fopAcM_getProcNameString(fopAc_ac_c* i_this) { const char * pProcNameString = dStage_getName2(fopAcM_GetProfName(i_this), i_this->subtype); if (pProcNameString != NULL) return pProcNameString; return "UNKOWN"; } /* 8002833C-80028410 .text fopAcM_findObjectCB__FP10fopAc_ac_cPv */ fopAc_ac_c* fopAcM_findObjectCB(fopAc_ac_c* it, void* i_prm) { fopAcM_search_prm* Prm = (fopAcM_search_prm*)i_prm; JUT_ASSERT(4095, Prm); dStage_objectNameInf *inf = dStage_searchName(Prm->procname); if (inf == NULL) return NULL; if (inf->mProcName == fopAcM_GetProfName(it) && inf->mSubtype == it->subtype && (Prm->prm_mask == 0 || Prm->parameter == (fopAcM_GetParam(it) & Prm->prm_mask))) return it; return NULL; } /* 80028410-80028448 .text fopAcM_searchFromName__FPcUlUl */ fopAc_ac_c* fopAcM_searchFromName(char* pProcName, u32 paramMask, u32 parameter) { fopAcM_search_prm param; param.procname = pProcName; param.prm_mask = paramMask; param.parameter = parameter; return fopAcM_Search((fopAcIt_JudgeFunc)fopAcM_findObjectCB, ¶m); } /* 80028448-80028560 .text fopAcM_getWaterY__FPC4cXyzPf */ BOOL fopAcM_getWaterY(const cXyz* pPos, f32* pDstWaterY) { static dBgS_WtrChk water_check; BOOL ret = FALSE; *pDstWaterY = -G_CM3D_F_INF; cXyz pos; pos.x = pPos->x; pos.y = pPos->y - 500.0f; pos.z = pPos->z; water_check.Set(pos, pos.y + 1000.0f); bool hit = dComIfG_Bgsp()->WaterChk(&water_check); if (hit) { *pDstWaterY = water_check.GetHeight(); ret = TRUE; } if (daSea_ChkArea(pPos->x, pPos->z)) { f32 waveY = daSea_calcWave(pPos->x, pPos->z); if (waveY > *pDstWaterY) *pDstWaterY = waveY; ret = TRUE; } return ret; } /* 80028684-80028724 .text fopAcM_setGbaName__FP10fopAc_ac_cUcUcUc */ void fopAcM_setGbaName(fopAc_ac_c* i_this, u8 itemNo, u8 gbaName0, u8 gbaName1) { if (dComIfGs_checkGetItem(itemNo) || (itemNo == dItem_BOW_e && (dComIfGs_checkGetItem(dItem_MAGIC_ARROW_e) || dComIfGs_checkGetItem(dItem_LIGHT_ARROW_e))) || (itemNo == dItem_MAGIC_ARROW_e && dComIfGs_checkGetItem(dItem_LIGHT_ARROW_e)) ) i_this->gbaName = gbaName1; else i_this->gbaName = gbaName0; } // Unused function, only exists in debug. void fopAcM_getNameString(fopAc_ac_c*, char*) {} /* 80028724-800287D8 .text fpoAcM_absolutePos__FP10fopAc_ac_cP4cXyzP4cXyz */ void fpoAcM_absolutePos(fopAc_ac_c* i_this, cXyz* relPos, cXyz* absPos) { *absPos = i_this->current.pos; absPos->x += relPos->z * cM_ssin(i_this->shape_angle.y) + relPos->x * cM_scos(i_this->shape_angle.y); absPos->y += relPos->y; absPos->z += relPos->z * cM_scos(i_this->shape_angle.y) - relPos->x * cM_ssin(i_this->shape_angle.y); } /* 800287D8-8002889C .text fpoAcM_relativePos__FP10fopAc_ac_cP4cXyzP4cXyz */ void fpoAcM_relativePos(fopAc_ac_c* i_this, cXyz* absPos, cXyz* relPos) { s16 angle = -i_this->shape_angle.y; cXyz offset = *absPos - i_this->current.pos; relPos->x = offset.z * cM_ssin(angle) + offset.x * cM_scos(angle); relPos->y = offset.y; relPos->z = offset.z * cM_scos(angle) - offset.x * cM_ssin(angle); }