From 27f3ef4c5526284c4141009a681b3e5143f21065 Mon Sep 17 00:00:00 2001 From: LagoLunatic Date: Sat, 9 Dec 2023 15:38:09 -0500 Subject: [PATCH] f_op_actor_mng 99% (1 regswap left) --- include/d/d_item.h | 4 +- include/d/d_kankyo.h | 1 + include/f_op/f_op_actor_mng.h | 15 ++ src/d/actor/d_a_ib.cpp | 14 +- src/d/d_item.cpp | 44 +++--- src/d/d_kankyo.cpp | 4 +- src/f_op/f_op_actor_mng.cpp | 288 +++++++++++++++++++++++++++++----- 7 files changed, 291 insertions(+), 79 deletions(-) diff --git a/include/d/d_item.h b/include/d/d_item.h index 8eeceecf9..bb0fe3e78 100644 --- a/include/d/d_item.h +++ b/include/d/d_item.h @@ -393,7 +393,7 @@ BOOL isTriforce(u8 itemNo); BOOL isHeart(u8 itemNo); u8 getItemNoByLife(u8); u8 check_itemno(int); -int getEmonoItemFromLifeBallTable(u16); -int getItemFromLifeBallTableWithoutEmono(u16); +u8 getEmonoItemFromLifeBallTable(u16); +u8 getItemFromLifeBallTableWithoutEmono(u16); #endif /* D_ITEM_H */ \ No newline at end of file diff --git a/include/d/d_kankyo.h b/include/d/d_kankyo.h index 0f5b022a9..6e21b4cf4 100644 --- a/include/d/d_kankyo.h +++ b/include/d/d_kankyo.h @@ -391,6 +391,7 @@ BOOL dKy_checkEventNightStop(); void dKy_set_nexttime(f32); void dKy_instant_timechg(f32); void dKy_instant_rainchg(); +SND_INFLUENCE * dKy_Sound_get(); void dKy_Sound_set(cXyz i_pos, int param_1, unsigned int i_actorID, int param_3); void dKy_itudemo_se(); void dKy_actor_addcol_set(s16, s16, s16, f32); diff --git a/include/f_op/f_op_actor_mng.h b/include/f_op/f_op_actor_mng.h index f937a48b3..dafa934f2 100644 --- a/include/f_op/f_op_actor_mng.h +++ b/include/f_op/f_op_actor_mng.h @@ -6,6 +6,7 @@ #include "f_pc/f_pc_manager.h" #include "f_pc/f_pc_searcher.h" #include "m_Do/m_Do_audio.h" +#include "d/d_item_data.h" #define fopAcM_SetupActor(ptr,ClassName) \ if (!fopAcM_CheckCondition(ptr, fopAcCnd_INIT_e)) { \ @@ -321,6 +322,15 @@ inline BOOL fopAcM_isItem(fopAc_ac_c* item, int bitNo) { return dComIfGs_isItem(bitNo, fopAcM_GetHomeRoomNo(item)); } +inline BOOL dComIfGs_isSaveSwitch(int i_stageNo, int i_no); +inline BOOL fopAcM_isItemForIb(int itemBitNo, u8 itemNo, s8 roomNo) { + if (itemNo == BLUE_JELLY) { // Blue Chu Jelly uses itemBitNo as if it was a switch. + return dComIfGs_isSaveSwitch(0xE, itemBitNo); + } else { + return dComIfGs_isItem(itemBitNo, roomNo); + } +} + inline f32 fopAcM_searchActorDistanceY(fopAc_ac_c* actorA, fopAc_ac_c* actorB) { return actorB->current.pos.y - actorA->current.pos.y; } @@ -456,6 +466,9 @@ s32 fopAcM_createItemForTrBoxDemo(cXyz* p_pos, int i_itemNo, int i_itemBitNo = - s32 fopAcM_createItemFromTable(cXyz* p_pos, int i_tableNo, int i_itemBitNo, int i_roomNo, int, csXyz* p_angle, int, cXyz* p_scale = NULL); +s32 fopAcM_createRaceItemFromTable(cXyz* pos, int i_itemNo, int i_itemBitNo, int i_roomNo, + csXyz* angle, cXyz* scale, int param_7); + s32 fopAcM_createShopItem(cXyz* p_pos, int i_itemNo, csXyz* p_angle, int roomNo, cXyz* scale = NULL, createFunc createFunc = NULL); @@ -491,6 +504,8 @@ s32 fopAcM_createDisappear(fopAc_ac_c* i_actor, cXyz* p_pos, u8 i_scale, u8 i_he void fopAcM_setCarryNow(fopAc_ac_c* i_this, int stageLayer); void fopAcM_cancelCarryNow(fopAc_ac_c* i_this); s32 fopAcM_otoCheck(fopAc_ac_c*, f32); +BOOL fopAcM_viewCutoffCheck(fopAc_ac_c* actor, f32 param_2); +BOOL fopAcM_getGroundAngle(fopAc_ac_c* actor, csXyz* p_angle); // void vectle_calc(DOUBLE_POS*, cXyz*); // void get_vectle_calc(cXyz*, cXyz*, cXyz*); diff --git a/src/d/actor/d_a_ib.cpp b/src/d/actor/d_a_ib.cpp index 0114b17ed..e80bd51dd 100644 --- a/src/d/actor/d_a_ib.cpp +++ b/src/d/actor/d_a_ib.cpp @@ -115,18 +115,6 @@ static BOOL itemParamSet_CB(void* i_actor) { return TRUE; } -// This is a fake inline, not present in the demo debug map. -// However, it's possible an inline similar to this was added to the final release. -// The kiosk demo calls dSv_memBit_c::isVisitedRoom(int) instead of dSv_memBit_c::isSwitch(int) here, -// so it's plausible they also added this inline while they were modifying that code. -inline BOOL isItemBit(u8 itemNo, s8 itemBitNo, s8 roomNo) { - if (itemNo == BLUE_JELLY) { // Blue Chu Jelly uses itemBitNo as if it was a switch. - return dComIfGs_isSaveSwitch(0xE, itemBitNo); - } else { - return dComIfGs_isItem(itemBitNo, roomNo); - } -} - /* 800F3658-800F3994 .text createItem__9daIball_cFv */ BOOL daIball_c::createItem() { // Fakematch: itemBitNo and itemTableIdx should really be separate variables as they aren't @@ -148,7 +136,7 @@ BOOL daIball_c::createItem() { itemBitNo = -1; if (isLimitedItem(items[i])) { itemBitNo = daIball_prm::getItemBitNo(this); - if (itemBitNo == 0x1F || itemBitNo == 0xFF || itemBitNo == -1 || isItemBit(items[i], itemBitNo, current.roomNo)) { + if ((itemBitNo == 0x1F || itemBitNo == 0xFF || itemBitNo == -1) || fopAcM_isItemForIb(itemBitNo, items[i], current.roomNo)) { itemBitNo = -1; items[i] = YELLOW_RUPEE; } diff --git a/src/d/d_item.cpp b/src/d/d_item.cpp index 370aad48c..d10014f5a 100644 --- a/src/d/d_item.cpp +++ b/src/d/d_item.cpp @@ -2781,7 +2781,7 @@ u8 check_itemno(int itemNo) { } /* 800C7ED0-800C8214 .text getEmonoItemFromLifeBallTable__FUs */ -int getEmonoItemFromLifeBallTable(u16 itemTableIdx) { +u8 getEmonoItemFromLifeBallTable(u16 itemTableIdx) { u8 items[16]; items[0] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_ITEM0, itemTableIdx); @@ -2799,16 +2799,16 @@ int getEmonoItemFromLifeBallTable(u16 itemTableIdx) { } } - items[0] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM0, itemTableIdx); - items[1] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM1, itemTableIdx); - items[2] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM2, itemTableIdx); - items[3] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM3, itemTableIdx); - items[4] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM4, itemTableIdx); - items[5] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM5, itemTableIdx); - items[6] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM6, itemTableIdx); - items[7] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM7, itemTableIdx); - items[8] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM8, itemTableIdx); - items[9] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM9, itemTableIdx); + items[0] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM0, itemTableIdx); + items[1] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM1, itemTableIdx); + items[2] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM2, itemTableIdx); + items[3] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM3, itemTableIdx); + items[4] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM4, itemTableIdx); + items[5] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM5, itemTableIdx); + items[6] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM6, itemTableIdx); + items[7] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM7, itemTableIdx); + items[8] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM8, itemTableIdx); + items[9] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM9, itemTableIdx); items[10] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM10, itemTableIdx); items[11] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM11, itemTableIdx); items[12] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM12, itemTableIdx); @@ -2826,19 +2826,19 @@ int getEmonoItemFromLifeBallTable(u16 itemTableIdx) { } /* 800C8214-800C8498 .text getItemFromLifeBallTableWithoutEmono__FUs */ -int getItemFromLifeBallTableWithoutEmono(u16 itemTableIdx) { +u8 getItemFromLifeBallTableWithoutEmono(u16 itemTableIdx) { u8 items[16]; - items[0] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM0, itemTableIdx); - items[1] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM1, itemTableIdx); - items[2] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM2, itemTableIdx); - items[3] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM3, itemTableIdx); - items[4] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM4, itemTableIdx); - items[5] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM5, itemTableIdx); - items[6] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM6, itemTableIdx); - items[7] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM7, itemTableIdx); - items[8] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM8, itemTableIdx); - items[9] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM9, itemTableIdx); + items[0] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM0, itemTableIdx); + items[1] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM1, itemTableIdx); + items[2] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM2, itemTableIdx); + items[3] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM3, itemTableIdx); + items[4] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM4, itemTableIdx); + items[5] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM5, itemTableIdx); + items[6] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM6, itemTableIdx); + items[7] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM7, itemTableIdx); + items[8] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM8, itemTableIdx); + items[9] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM9, itemTableIdx); items[10] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM10, itemTableIdx); items[11] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM11, itemTableIdx); items[12] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM12, itemTableIdx); diff --git a/src/d/d_kankyo.cpp b/src/d/d_kankyo.cpp index cc47efe03..4461fdf49 100644 --- a/src/d/d_kankyo.cpp +++ b/src/d/d_kankyo.cpp @@ -3024,7 +3024,7 @@ void dKy_Sound_init() { g_env_light.mSound.field_0x0.y = 999999.9f; g_env_light.mSound.field_0x0.z = 999999.9f; g_env_light.mSound.field_0xc = 0; - g_env_light.mSound.field_0x14 = -1; + g_env_light.mSound.field_0x14 = fpcM_ERROR_PROCESS_ID_e; g_env_light.mSound.field_0x10 = 0; } @@ -3050,7 +3050,7 @@ void dKy_Sound_set(cXyz pos, int p2, unsigned int p3, int p4) { dKy_getEnvlight().mSound.field_0x0.y = pos.y; dKy_getEnvlight().mSound.field_0x0.z = pos.z; dKy_getEnvlight().mSound.field_0xc = p2; - dKy_getEnvlight().mSound.field_0x14 = p3; + dKy_getEnvlight().mSound.field_0x14 = fpcM_ERROR_PROCESS_ID_e; dKy_getEnvlight().mSound.field_0x10 = p4; } } diff --git a/src/f_op/f_op_actor_mng.cpp b/src/f_op/f_op_actor_mng.cpp index 30f569155..400a8fbbf 100644 --- a/src/f_op/f_op_actor_mng.cpp +++ b/src/f_op/f_op_actor_mng.cpp @@ -6,6 +6,7 @@ #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" @@ -16,6 +17,7 @@ #include "d/actor/d_a_player_main.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" @@ -408,7 +410,7 @@ bool fopAcM_entrySolidHeap(fopAc_ac_c* i_this, heapCallbackFunc createHeapCB, u3 } /* 800250E4-80025100 .text fopAcM_setCullSizeBox__FP10fopAc_ac_cffffff */ -void fopAcM_setCullSizeBox(fopAc_ac_c* i_this, float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { +void fopAcM_setCullSizeBox(fopAc_ac_c* i_this, f32 minX, f32 minY, f32 minZ, f32 maxX, f32 maxY, f32 maxZ) { i_this->mCull.mBox.mMin.x = minX; i_this->mCull.mBox.mMin.y = minY; i_this->mCull.mBox.mMin.z = minZ; @@ -418,7 +420,7 @@ void fopAcM_setCullSizeBox(fopAc_ac_c* i_this, float minX, float minY, float min } /* 80025100-80025114 .text fopAcM_setCullSizeSphere__FP10fopAc_ac_cffff */ -void fopAcM_setCullSizeSphere(fopAc_ac_c* i_this, float x, float y, float z, float r) { +void fopAcM_setCullSizeSphere(fopAc_ac_c* i_this, f32 x, f32 y, f32 z, f32 r) { i_this->mCull.mSphere.mCenter.x = x; i_this->mCull.mSphere.mCenter.y = y; i_this->mCull.mSphere.mCenter.z = z; @@ -488,14 +490,16 @@ f32 fopAcM_searchActorDistance2(fopAc_ac_c* i_this, fopAc_ac_c* i_other) { /* 800253C0-80025470 .text fopAcM_searchActorDistanceXZ__FP10fopAc_ac_cP10fopAc_ac_c */ f32 fopAcM_searchActorDistanceXZ(fopAc_ac_c* i_this, fopAc_ac_c* i_other) { - /* Nonmatching */ - return (i_other->current.pos - i_this->current.pos).absXZ(); + 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) { - /* Nonmatching */ - return (i_other->current.pos - i_this->current.pos).abs2XZ(); + 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 */ @@ -517,7 +521,7 @@ s32 fopAcM_rollPlayerCrash(fopAc_ac_c* i_this, f32 distAdjust, u32 flag) { } /* 800255B4-80025660 .text fopAcM_checkCullingBox__FPA4_fffffff */ -s32 fopAcM_checkCullingBox(Mtx pMtx, float x0, float y0, float z0, float x1, float y1, float z1) { +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; @@ -690,7 +694,6 @@ s32 fopAcM_orderCatchEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner) { /* 80025C34-80025CC8 .text fopAcM_orderOtherEvent2__FP10fopAc_ac_cPcUsUs */ s32 fopAcM_orderOtherEvent2(fopAc_ac_c* i_this, char* pEventName, u16 flag, u16 hind) { - /* Nonmatching */ u16 prio = dComIfGp_evmng_getEventPrio(dComIfGp_evmng_getEventIdx(pEventName, 0xFF)); if (prio == 0) prio = 0xFF; @@ -710,7 +713,6 @@ s32 fopAcM_orderChangeEvent(fopAc_ac_c* i_this, fopAc_ac_c* i_partner, char* pEv /* 80025D94-80025E1C .text fopAcM_orderChangeEventId__FP10fopAc_ac_csUsUs */ s32 fopAcM_orderChangeEventId(fopAc_ac_c* i_this, s16 eventIdx, u16 flag, u16 hind) { - /* Nonmatching */ u16 prio = dComIfGp_evmng_getEventPrio(eventIdx); if (prio == 0) prio = 0xFF; @@ -720,7 +722,6 @@ s32 fopAcM_orderChangeEventId(fopAc_ac_c* i_this, s16 eventIdx, u16 flag, u16 hi /* 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) { - /* Nonmatching */ u16 prio = dComIfGp_evmng_getEventPrio(eventIdx); if (prio == 0) prio = 0xFF; @@ -895,8 +896,23 @@ s32 fopAcM_createItemFromTable(cXyz* p_pos, int i_itemNo, int i_itemBitNo, int r } /* 80026694-800267C8 .text fopAcM_createRaceItemFromTable__FP4cXyziiiP5csXyzP4cXyzi */ -void fopAcM_createRaceItemFromTable(cXyz*, int, int, int, csXyz*, cXyz*, int) { - /* Nonmatching */ +s32 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 -1; + } + + 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 */ @@ -946,15 +962,49 @@ s32 fopAcM_createItemForBoss(cXyz* pos, int, int roomNo, csXyz* rot, cXyz* scale /* 80026ADC-80026C90 .text fopAcM_createItem__FP4cXyziiiiP5csXyziP4cXyz */ s32 fopAcM_createItem(cXyz* pos, int i_itemNo, int i_itemBitNo, int roomNo, int type, csXyz* rot, int action, cXyz* scale) { - /* Nonmatching */ + 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 == NO_ITEM) { + return -1; + } + + csXyz prmRot = csXyz::Zero; + if (rot) { + prmRot = *rot; + } + prmRot.z = switchNo; + + u8 itemNo = check_itemno(i_itemNo); + u32 params = (i_itemBitNo & 0xFF) << 0x08 | itemNo & 0xFF | switchNo2 << 16 | (type & 3) << 24 | action << 26; + + switch (i_itemNo) { + case RECOVER_FAIRY: + return fopAcM_create(PROC_NPC_FA1, 1, pos, roomNo, rot, scale); + case TRIPLE_HEART: + // 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, &prmRot, scale); + } + // Fall-through + default: + return fopAcM_create(PROC_ITEM, params, pos, roomNo, &prmRot, scale); + } } /* 80026C90-80026E5C .text fopAcM_fastCreateItem2__FP4cXyziiiiP5csXyziP4cXyz */ void* fopAcM_fastCreateItem2(cXyz* pos, int i_itemNo, int i_itemBitNo, int roomNo, int type, - csXyz* rot, int action, cXyz* scale) { - /* Nonmatching (regswap) */ + csXyz* rot, 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 prmRot = csXyz::Zero; if (i_itemNo == NO_ITEM) { @@ -964,18 +1014,17 @@ void* fopAcM_fastCreateItem2(cXyz* pos, int i_itemNo, int i_itemBitNo, int roomN if (rot) { prmRot = *rot; } - prmRot.z = 0xFF; + prmRot.z = switchNo; - u32 params = check_itemno(i_itemNo); - params = (i_itemBitNo & 0xFF) << 0x08 | params & 0xFF | 0x00FF0000 | (type & 3) << 24 | action << 26; + u8 itemNo = check_itemno(i_itemNo); + u32 params = (i_itemBitNo & 0xFF) << 0x08 | itemNo & 0xFF | switchNo2 << 16 | (type & 3) << 24 | action << 26; - daItem_c* item; switch (i_itemNo) { case RECOVER_FAIRY: return fopAcM_fastCreate(PROC_NPC_FA1, 1, pos, roomNo, rot, scale); case TRIPLE_HEART: // Make the two extra hearts first, then fall-through to make the third heart as normal. - for (int i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmRot, scale); } // Fall-through @@ -1010,13 +1059,21 @@ daItem_c* fopAcM_createItemForSimpleDemo(cXyz* pos, int i_itemNo, int roomNo, cs /* 80026F98-80027254 .text fopAcM_fastCreateItem__FP4cXyziiP5csXyzP4cXyzfffiPFPv_i */ void* fopAcM_fastCreateItem(cXyz* pos, int i_itemNo, int roomNo, csXyz* rot, cXyz* scale, f32 speedF, f32 speedY, f32 gravity, int i_itemBitNo, createFunc createFunc) { - /* Nonmatching (regswaps) */ + /* Nonmatching - single regswap on params */ + int type = 0; + int action = 0xA; + int switchNo = 0xFF; + int switchNo2 = 0xFF; + JUT_ASSERT(3201, 0 <= i_itemNo && i_itemNo < 256); if (i_itemNo == NO_ITEM) { return NULL; } - - u32 params = (u8)check_itemno(i_itemNo) & 0xFF | (i_itemBitNo & 0xFF) << 0x08 | 0x28FF0000; + + int i; + + u8 itemNo = check_itemno(i_itemNo); + u32 params = (i_itemBitNo & 0xFF) << 0x08 | itemNo & 0xFF | switchNo2 << 16 | (type & 3) << 24 | action << 26; if (isHeart(i_itemNo)) { speedF = 2.0f * speedF; @@ -1030,13 +1087,13 @@ void* fopAcM_fastCreateItem(cXyz* pos, int i_itemNo, int roomNo, csXyz* rot, cXy return item; case TRIPLE_HEART: // Make the two extra hearts first, then fall-through to make the third heart as normal. - for (int i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { if (rot) { prmRot = *rot; } else { prmRot = csXyz::Zero; } - prmRot.z = 0xFF; + prmRot.z = switchNo; prmRot.y += (int)cM_rndFX(0x2000); item = (daItem_c*)fopAcM_fastCreate(PROC_ITEM, params, pos, roomNo, &prmRot, scale, -1, createFunc); @@ -1076,18 +1133,113 @@ BOOL stealItem_CB(void* actor) { } /* 80027280-800273D4 .text fopAcM_createStealItem__FP4cXyziiP5csXyzi */ -void fopAcM_createStealItem(cXyz* p_pos, int i_tblNo, int, csXyz*, int) { - /* Nonmatching */ +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 == NO_ITEM) { + 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, int, int, cXyz*, csXyz*) { - /* Nonmatching */ +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()->mIndex_N_ITEM0, itemTableIdx); + items[1] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM1, itemTableIdx); + items[2] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM2, itemTableIdx); + items[3] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM3, itemTableIdx); + items[4] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM4, itemTableIdx); + items[5] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM5, itemTableIdx); + items[6] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM6, itemTableIdx); + items[7] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM7, itemTableIdx); + items[8] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM8, itemTableIdx); + items[9] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM9, itemTableIdx); + items[10] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM10, itemTableIdx); + items[11] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM11, itemTableIdx); + items[12] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM12, itemTableIdx); + items[13] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM13, itemTableIdx); + items[14] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM14, itemTableIdx); + items[15] = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_N_ITEM15, 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] = YELLOW_RUPEE; + } + } 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 */ -s32 fopAcM_createIball(cXyz*, int, int, csXyz*, int) { - /* Nonmatching */ +s32 fopAcM_createIball(cXyz* p_pos, int itemTableIdx, int i_roomNo, csXyz* p_angle, int i_itemBitNo) { + int dropChance = dComIfGp_CharTbl()->GetInf(dComIfGp_CharTbl()->mIndex_percent, (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 -1; + } + + 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 */ @@ -1132,8 +1284,49 @@ s32 fopAcM_createDisappear(fopAc_ac_c* i_actor, cXyz* p_pos, u8 i_scale, u8 i_he } /* 80027B24-80027E28 .text fopAcM_getGroundAngle__FP10fopAc_ac_cP5csXyz */ -void fopAcM_getGroundAngle(fopAc_ac_c*, csXyz*) { - /* Nonmatching */ +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 != -1e09f) { + 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 != -1e09f) { + 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 != -1e09f) { + 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 */ @@ -1158,18 +1351,33 @@ void fopAcM_cancelCarryNow(fopAc_ac_c* i_this) { } /* 80027ED8-800281D8 .text fopAcM_viewCutoffCheck__FP10fopAc_ac_cf */ -void fopAcM_viewCutoffCheck(fopAc_ac_c*, float) { - /* Nonmatching */ +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->mEyePos); + if (delta.abs() > param_2) { + dBgS_LinChk linChk; + linChk.Set(&camera->mLookat.mEye, &actor->mEyePos, actor); + return dComIfG_Bgsp()->LineCross(&linChk); + } + } + return FALSE; } /* 800281D8-800282F8 .text fopAcM_otoCheck__FP10fopAc_ac_cf */ -s32 fopAcM_otoCheck(fopAc_ac_c*, float) { - /* Nonmatching */ +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) { - /* Nonmatching */ const char * pProcNameString = dStage_getName2(fpcM_GetProfName(i_this), i_this->mSubtype); if (pProcNameString != NULL) return pProcNameString; @@ -1207,7 +1415,7 @@ fopAc_ac_c* fopAcM_searchFromName(char* pProcName, u32 paramMask, u32 parameter) } /* 80028448-80028560 .text fopAcM_getWaterY__FPC4cXyzPf */ -s32 fopAcM_getWaterY(const cXyz* pPos, float* pDstWaterY) { +s32 fopAcM_getWaterY(const cXyz* pPos, f32* pDstWaterY) { static dBgS_WtrChk water_check; s32 ret = 0; @@ -1262,7 +1470,7 @@ void fpoAcM_relativePos(fopAc_ac_c* i_this, cXyz* absPos, cXyz* relPos) { #ifndef __INTELLISENSE__ /* 80029178-80029198 .text __ct__20fopAc_cullSizeSphereF4cXyzf */ -fopAc_cullSizeSphere::fopAc_cullSizeSphere(cXyz p, float r) { +fopAc_cullSizeSphere::fopAc_cullSizeSphere(cXyz p, f32 r) { mCenter = p; mRadius = r; }