diff --git a/include/d/actor/d_a_tag_light.h b/include/d/actor/d_a_tag_light.h index 57cd78f6d..0a08e2e8a 100644 --- a/include/d/actor/d_a_tag_light.h +++ b/include/d/actor/d_a_tag_light.h @@ -2,15 +2,33 @@ #define D_A_TAG_LIGHT_H #include "f_op/f_op_actor.h" +#include "d/d_a_obj.h" class J3DMaterial; namespace daTagLight { class Act_c : public fopAc_ac_c { public: - void chk_inside(const cXyz*) const {} + enum Prm_e { + PRM_CONERATIO_W = 0x04, + PRM_CONERATIO_S = 0x0A, + }; + + void chk_inside(const cXyz* pos) const { + /* Nonmatching */ + // M_box_x_min + // M_box_x_max + // M_box_y_min + // M_box_y_max + // M_box_z_min + // M_box_z_max + // M_cone_lower + // M_cone_upper + prm_get_coneRatio(); + // M_cone_r + } void prm_get_ccR() const {} - void prm_get_coneRatio() const {} + int prm_get_coneRatio() const { return daObj::PrmAbstract(this, PRM_CONERATIO_W, PRM_CONERATIO_S); } void prm_get_fadeType() const {} void prm_get_sch() const {} void prm_get_swSave() const {} diff --git a/include/d/d_attention.h b/include/d/d_attention.h index 016d19218..c0ecaa373 100644 --- a/include/d/d_attention.h +++ b/include/d/d_attention.h @@ -85,6 +85,8 @@ public: void request(fopAc_ac_c*, f32, f32, f32, s16, int); void requestF(fopAc_ac_c*, s16, int); + u32 getLookTarget() { return mLookTargetID; } + private: /* 0x0 */ u32 field_0x0; /* 0x4 */ u32 field_0x4; @@ -172,6 +174,9 @@ public: mCatch.request(param_0, param_1, param_2, param_3, param_4, param_5, param_6); } + fopAc_ac_c* getLookTarget() { return mLook[0].convPId(mLook[0].getLookTarget()); } + fopAc_ac_c* getLook2Target() { return mLook[1].convPId(mLook[1].getLookTarget()); } + // TODO: void GetLockonCount() {} void LockEdge() {} @@ -179,8 +184,6 @@ public: void chkEnemySound() {} u8 getCatchChgItem() { return mCatch.getChangeItem(); } void getCatghTarget() {} - void getLookTarget() {} - void getLook2Target() {} void getZHintTarget() {} void offAleart() {} void revivalAleart() {} diff --git a/include/d/d_detect.h b/include/d/d_detect.h index 84c71fc03..1cacf15ce 100644 --- a/include/d/d_detect.h +++ b/include/d/d_detect.h @@ -10,11 +10,17 @@ public: bool chk_enable() const; /* 0x00 */ cXyz mPos; - /* 0x0C */ s16 mEnable; + /* 0x0C */ s16 mTimer; }; class dDetect_c { public: + struct Attr_c { + /* 0x00 */ f32 maxDistXZ; + /* 0x04 */ f32 maxY; + /* 0x08 */ f32 minY; + }; + dDetect_c(); ~dDetect_c(); @@ -22,10 +28,14 @@ public: bool chk_quake(const cXyz*) const; void set_quake(const cXyz*); bool chk_quake_area(const cXyz*) const; - void search_tag_light(void*, void*); + static void* search_tag_light(void*, void*); bool chk_light(const cXyz*) const; bool chk_attention(cXyz*) const; + inline const Attr_c& attr() const { return M_attr; } + + static const Attr_c M_attr; + /* 0x00 */ dDetectPlace_c mPlace[1]; /* 0x10 */ s16 mTimer; }; // Size: 0x14 diff --git a/src/d/actor/d_a_bomb3.inc b/src/d/actor/d_a_bomb3.inc index 9d6315f15..3fcd98408 100644 --- a/src/d/actor/d_a_bomb3.inc +++ b/src/d/actor/d_a_bomb3.inc @@ -1,6 +1,6 @@ // daBomb_c::createHeap's asserts tell us that function is inside d_a_bomb3.inc instead of d_a_bomb.cpp. // Furthermore, the symbol maps show that d_a_bomb.o's first .text section is 0 bytes large, with everything going in -// its second .text section, which suggestions that d_a_bomb.cpp is empty except including d_a_bomb3.inc. +// its second .text section, which suggests that d_a_bomb.cpp is empty except including d_a_bomb3.inc. #include "d/actor/d_a_bomb.h" #include "SSystem/SComponent/c_counter.h" diff --git a/src/d/d_detect.cpp b/src/d/d_detect.cpp index 17afd407d..8b27dcd2e 100644 --- a/src/d/d_detect.cpp +++ b/src/d/d_detect.cpp @@ -4,12 +4,21 @@ // #include "d/d_detect.h" -#include "dolphin/types.h" +#include "d/d_com_inf_game.h" +#include "d/actor/d_a_player.h" +#include "d/actor/d_a_tag_light.h" +#include "d/d_procname.h" + +const dDetect_c::Attr_c dDetect_c::M_attr = { + /* maxDistXZ */ 500.0f, + /* maxY */ 500.0f, + /* minY */ -200.0f +}; /* 8009BFD4-8009BFFC .text __ct__14dDetectPlace_cFv */ dDetectPlace_c::dDetectPlace_c() { mPos = cXyz::Zero; - mEnable = 0; + mTimer = 0; } /* 8009BFFC-8009C038 .text __dt__14dDetectPlace_cFv */ @@ -17,7 +26,7 @@ dDetectPlace_c::~dDetectPlace_c() {} /* 8009C038-8009C048 .text chk_enable__14dDetectPlace_cCFv */ bool dDetectPlace_c::chk_enable() const { - return mEnable != 0; + return mTimer != 0; } /* 8009C048-8009C098 .text __ct__9dDetect_cFv */ @@ -30,35 +39,91 @@ dDetect_c::~dDetect_c() {} /* 8009C0F8-8009C14C .text proc__9dDetect_cFv */ void dDetect_c::proc() { - /* Nonmatching */ + /* Nonmatching - 1 literal load order */ + if (mPlace[0].mTimer > 0) { + mPlace[0].mTimer--; + } else if (mPlace[0].mTimer < 0) { + mPlace[0].mTimer = 1; + } + if (mTimer > 0) { + mTimer--; + } else if (mTimer < 0) { + mTimer = 1; + } } /* 8009C14C-8009C1E0 .text chk_quake__9dDetect_cCFPC4cXyz */ -bool dDetect_c::chk_quake(const cXyz*) const { - /* Nonmatching */ +bool dDetect_c::chk_quake(const cXyz* pos) const { + daPy_py_c* player = daPy_getPlayerActorClass(); + bool ret = false; + if (mTimer > 0) { + ret = true; + } else { + if (player->checkFrontRollCrash()) { + if (pos) { + if (chk_quake_area(pos)) { + ret = true; + } + } else { + ret = true; + } + } + if (mPlace[0].mTimer > 0) { + ret = true; + } + } + return ret; } /* 8009C1E0-8009C254 .text set_quake__9dDetect_cFPC4cXyz */ -void dDetect_c::set_quake(const cXyz*) { - /* Nonmatching */ +void dDetect_c::set_quake(const cXyz* pos) { + /* Nonmatching - regalloc, load order */ + if (pos) { + if (!mPlace[0].chk_enable()) { + mPlace[0].mTimer = -1; + mPlace[0].mPos = *pos; + } else { + // Possible fakematch: There's a double branch here that probably means something got optimized out, but + // it's not clear what it was, or if this is exactly the right spot for it. + mPlace[0].mPos.y = mPlace[0].mPos.y; + } + } else { + mTimer = -1; + } } /* 8009C254-8009C32C .text chk_quake_area__9dDetect_cCFPC4cXyz */ -bool dDetect_c::chk_quake_area(const cXyz*) const { - /* Nonmatching */ +bool dDetect_c::chk_quake_area(const cXyz* pos) const { + daPy_py_c* player = daPy_getPlayerActorClass(); + f32 maxDist2XZ = attr().maxDistXZ * attr().maxDistXZ; + f32 dist2XZ = player->current.pos.abs2XZ(*pos); + f32 diffY = pos->y - player->current.pos.y; + return dist2XZ <= maxDist2XZ && diffY <= attr().maxY && diffY >= attr().minY; } /* 8009C32C-8009C588 .text search_tag_light__9dDetect_cFPvPv */ -void dDetect_c::search_tag_light(void*, void*) { +void* dDetect_c::search_tag_light(void* i_proc, void* i_pos) { /* Nonmatching */ + if (fopAc_IsActor(i_proc) && fopAcM_GetProfName(i_proc) == PROC_Tag_Light) { + daTagLight::Act_c* light = (daTagLight::Act_c*)i_proc; + const cXyz* pos = (const cXyz*)i_pos; + light->chk_inside(pos); // TODO + return light; + } + return NULL; } /* 8009C588-8009C5B8 .text chk_light__9dDetect_cCFPC4cXyz */ -bool dDetect_c::chk_light(const cXyz*) const { - /* Nonmatching */ +bool dDetect_c::chk_light(const cXyz* pos) const { + return fopAcIt_Judge(&dDetect_c::search_tag_light, (void*)pos) != NULL; } /* 8009C5B8-8009C620 .text chk_attention__9dDetect_cCFP4cXyz */ -bool dDetect_c::chk_attention(cXyz*) const { - /* Nonmatching */ +bool dDetect_c::chk_attention(cXyz* outPos) const { + fopAc_ac_c* target = dComIfGp_getAttention().getLook2Target(); + if (target == NULL) + return false; + + *outPos = target->mEyePos; + return true; }