From 4d1cb33cd856f8c439859ae4bc4547bd7ac58ba3 Mon Sep 17 00:00:00 2001 From: Mm2PL Date: Sun, 27 Apr 2025 21:12:46 +0200 Subject: [PATCH] d_attention 100% (#701) * Add helper functions for d_attention * Copy and adapt code from TP * Move for better matching layout * Clean up includes for d_attention.cpp * Give dAttention_c::nextAttention a return * Use enums in dAttention_c::getActionBtnB and slight reformat * Change return types for comparison code to match I don't love this * Implement dAttList_c::calcWeight * Implement dAttention_c::sortList * Implement dAttDraw_c::draw * Implement dAttDraw_c::setAnm * Implement dAttention_c::chaseAttention * Implement judgement related functions * Implement dAttention_c::Run and runDrawProc * Implement dAttention_c::Draw Actually finish Draw * Looks like dAttention_c::stockAttention had an unused return value * Give d_Attention_c::mLockOnState an enum * Rename field_0x02c to mDrawAttnPos based on TP * Add comments for fields of d_attention * Give d_attention's flags an enum (although without names) * Undo type change for dAttention_c::{chk,set,clr}Flag Co-Authored-By: LagoLunatic * Do not spell the `this` pointer Co-Authored-By: LagoLunatic * Deal with resource enums and inlines * Move PLAYER_STATUS_FLAG_MAGIC_JUDGEMENT to daPy__PlayerStatus0 enum * Use inlines and macros * Add mDoCPd_L_LOCK_BUTTON inline, debug maps claim it exists Nothing else uses it * Update TODO comments * Debug maps claim runXyCheckCB was used but it only makes sense if modified * Use dComIfGp_getPlayer instead of directly indexing the array * Locate a few more inlines * Do not cast to AttentionFlags enum type * Update configure script --------- Co-authored-by: LagoLunatic --- configure.py | 2 +- include/d/d_attention.h | 102 ++-- include/d/d_com_inf_game.h | 10 +- include/f_op/f_op_actor.h | 2 +- include/m_Do/m_Do_controller_pad.h | 4 + src/d/d_attention.cpp | 779 +++++++++++++++++++++++++---- 6 files changed, 774 insertions(+), 125 deletions(-) diff --git a/configure.py b/configure.py index 6cc83697e..2bb86d3d1 100755 --- a/configure.py +++ b/configure.py @@ -484,7 +484,7 @@ config.libs = [ Object(NonMatching, "d/d_detect.cpp"), Object(Matching, "d/d_vibration.cpp"), Object(Matching, "d/d_vib_pattern.cpp"), - Object(NonMatching, "d/d_attention.cpp"), + Object(Matching, "d/d_attention.cpp"), Object(Matching, "d/d_att_dist.cpp"), Object(Matching, "d/d_bg_s.cpp"), Object(Matching, "d/d_bg_s_acch.cpp"), diff --git a/include/d/d_attention.h b/include/d/d_attention.h index bc1aab926..839b1ea3a 100644 --- a/include/d/d_attention.h +++ b/include/d/d_attention.h @@ -41,16 +41,16 @@ public: fopAc_ac_c* convPId(fpc_ProcID); void init(); void proc(); - void request(fopAc_ac_c*, u8, f32, f32, f32, s16, int); + bool request(fopAc_ac_c*, u8, f32, f32, f32, s16, int); fopAc_ac_c* getCatghTarget() { return convPId(mCatghTargetID); } u8 getChangeItem() { return mChangeItem; } private: - /* 0x00 */ fpc_ProcID field_0x0; + /* 0x00 */ fpc_ProcID mRequestActorID; /* 0x04 */ int field_0x4; - /* 0x08 */ f32 field_0x8; - /* 0x0C */ u8 field_0xc; + /* 0x08 */ f32 mDistance; + /* 0x0C */ u8 mCatchItemNo; /* 0x0D */ u8 field_0xd; /* 0x0E */ u8 field_0xe; /* 0x0F */ u8 field_0xf; @@ -60,14 +60,14 @@ private: class dAttParam_c { public: - /* 0x00 */ u16 field_0x00; + /* 0x00 */ u16 mFlags; /* 0x02 */ u8 field_0x02[0x04 - 0x02]; /* 0x04 */ f32 field_0x04; /* 0x08 */ f32 field_0x08; /* 0x0C */ f32 field_0x0c; - /* 0x10 */ f32 field_0x10; - /* 0x14 */ f32 field_0x14; - /* 0x18 */ f32 field_0x18; + /* 0x10 */ f32 mDangerBGMDistance; + /* 0x14 */ f32 mBGMDistMargin; + /* 0x18 */ f32 mSWModeDisable; public: dAttParam_c() {} @@ -83,15 +83,15 @@ public: fopAc_ac_c* convPId(fpc_ProcID); void init(); void proc(); - void request(fopAc_ac_c*, f32, f32, f32, s16, int); - void requestF(fopAc_ac_c*, s16, int); + bool request(fopAc_ac_c*, f32, f32, f32, s16, int); + bool requestF(fopAc_ac_c*, s16, int); fpc_ProcID getLookTarget() { return mLookTargetID; } private: - /* 0x0 */ fpc_ProcID field_0x0; - /* 0x4 */ u32 field_0x4; - /* 0x8 */ f32 field_0x8; + /* 0x0 */ fpc_ProcID mRequestActorID; + /* 0x4 */ s32 field_0x4; + /* 0x8 */ f32 mDistance; /* 0xC */ fpc_ProcID mLookTargetID; }; // Size: 0x10 @@ -115,7 +115,46 @@ public: class daPy_lk_c; +enum AttentionFlags { + AttnFlag_00000001 = 0x00000001, + AttnFlag_00000002 = 0x00000002, + AttnFlag_00000004 = 0x00000004, + AttnFlag_00000008 = 0x00000008, + AttnFlag_00000010 = 0x00000010, + AttnFlag_00000020 = 0x00000020, + AttnFlag_00000040 = 0x00000040, + AttnFlag_00000080 = 0x00000080, + AttnFlag_00000100 = 0x00000100, + AttnFlag_00000200 = 0x00000200, + AttnFlag_00000400 = 0x00000400, + AttnFlag_00000800 = 0x00000800, + AttnFlag_00001000 = 0x00001000, + AttnFlag_00002000 = 0x00002000, + AttnFlag_00004000 = 0x00004000, + AttnFlag_00008000 = 0x00008000, + AttnFlag_00010000 = 0x00010000, + AttnFlag_00020000 = 0x00020000, + AttnFlag_00040000 = 0x00040000, + AttnFlag_00080000 = 0x00080000, + AttnFlag_00100000 = 0x00100000, + AttnFlag_00200000 = 0x00200000, + AttnFlag_00400000 = 0x00400000, + AttnFlag_00800000 = 0x00800000, + AttnFlag_01000000 = 0x01000000, + AttnFlag_02000000 = 0x02000000, + AttnFlag_04000000 = 0x04000000, + AttnFlag_08000000 = 0x08000000, + AttnFlag_10000000 = 0x10000000, + AttnFlag_20000000 = 0x20000000, + AttnFlag_40000000 = 0x40000000, + AttnFlag_80000000 = 0x80000000, +}; class dAttention_c { + enum LockState { + LockState_NONE = 0, + LockState_LOCK = 1, + LockState_RELEASE = 2, + }; public: dAttention_c() {} @@ -129,7 +168,7 @@ public: dAttList_c* getActionBtnX(); dAttList_c* getActionBtnY(); dAttList_c* getActionBtnZ(); - u32 chkAttMask(u32, u32); + s32 chkAttMask(u32, u32); f32 calcWeight(int, fopAc_ac_c*, f32, s16, s16, u32*); void setLList(fopAc_ac_c*, f32, f32, u32); void setAList(fopAc_ac_c*, f32, f32, u32); @@ -137,10 +176,10 @@ public: s32 makeList(); int SelectAttention(fopAc_ac_c*); void sortList(); - void stockAttention(u32); - void nextAttention(u32); + fopAc_ac_c *stockAttention(u32); + fopAc_ac_c *nextAttention(u32); s32 freeAttention(); - void chaseAttention(); + bool chaseAttention(); f32 EnemyDistance(fopAc_ac_c*); void runSoundProc(); void runDrawProc(); @@ -148,13 +187,13 @@ public: void runDebugDisp(); void judgementButton(); void judgementTriggerProc(); - void judgementLostCheck(); + int judgementLostCheck(); void judgementStatusSw(u32); void judgementStatusHd(u32); - void Run(u32); + bool Run(u32 interactMask); void Draw(); fopAc_ac_c* LockonTarget(s32); - void LockonReleaseDistanse(); + f32 LockonReleaseDistanse(); fpc_ProcID LockonTargetPId(s32); fopAc_ac_c* ActionTarget(s32); bool LockonTruth(); @@ -169,12 +208,12 @@ public: bool chkFlag(u32 flag) { return (mFlags & flag) ? true : false; } void setFlag(u32 flag) { mFlags |= flag; } void clrFlag(u32 flag) { mFlags &= ~flag; } - bool Lockon() { return LockonTruth() || chkFlag(0x20000000); } // regswap + bool Lockon() { return LockonTruth() || chkFlag(AttnFlag_20000000); } // regswap void offAleart() { - setFlag(0x80000000); + setFlag(AttnFlag_80000000); } void revivalAleart() { - clrFlag(0x80000000); + clrFlag(AttnFlag_80000000); } void CatchRequest(fopAc_ac_c* param_0, u8 param_1, f32 param_2, f32 param_3, @@ -194,10 +233,12 @@ public: static s32 loc_type_num; static u32 act_type_num; - static struct LocTbl { + struct LocTbl { s16 mType; u16 mMask; - } loc_type_tbl[3]; + }; + static LocTbl loc_type_tbl[3]; + static LocTbl act_type_tbl[5]; static struct DistTbl { f32 mDistXZMax; f32 mDistXZMaxRelease; @@ -222,19 +263,18 @@ public: /* 0x008 */ dAttDraw_CallBack_c mCallBack; /* 0x00C */ int mPlayerNo; /* 0x010 */ u32 mFlagMask; - /* 0x014 */ u8 field_0x014[0x018 - 0x014]; + /* 0x014 */ u8 field_0x014[0x018 - 0x014]; // seemingly unused but removing this yields a smaller structure /* 0x018 */ u8 mLockOnState; - /* 0x019 */ u8 field_0x019; + /* 0x019 */ u8 field_0x019; // data copied from mLockState, looks to be same as TP's dAttention_c::field_0x32a /* 0x01A */ u8 field_0x01a; /* 0x01B */ u8 field_0x01b; /* 0x01C */ s16 field_0x01c; - /* 0x01E */ u8 field_0x01E[0x020 - 0x01E]; /* 0x020 */ u32 mFlags; /* 0x024 */ JKRSolidHeap* heap; - /* 0x028 */ s8 field_0x028; - /* 0x02C */ cXyz field_0x02c; + /* 0x028 */ s8 field_0x028; // looks to be same as TP's dAttention_c::field_0x328 + /* 0x02C */ cXyz mDrawAttnPos; /* 0x038 */ dAttDraw_c draw[2]; - /* 0x050 */ u32 field_0x050; + /* 0x050 */ u32 mlockedOnPId; /* 0x054 */ dAttList_c mLockOnList[8]; /* 0x0D4 */ int mLockOnNum; /* 0x0D8 */ int mLockOnOffs; diff --git a/include/d/d_com_inf_game.h b/include/d/d_com_inf_game.h index 959ca5265..bacab29f6 100644 --- a/include/d/d_com_inf_game.h +++ b/include/d/d_com_inf_game.h @@ -66,6 +66,14 @@ enum daPy__PlayerStatus0 { daPyStts0_UNK20000000_e = 0x20000000, daPyStts0_SPIN_ATTACK_e = 0x40000000, daPyStts0_UNK80000000_e = 0x80000000, + + // This is some combination of flags which is seemingly related to "judgement", used in dAttention_c + daPyStts0_UNK37a02371_e = daPyStts0_UNK1_e | daPyStts0_UNK10_e | daPyStts0_UNK20_e + | daPyStts0_UNK40_e | daPyStts0_UNK100_e | daPyStts0_UNK200_e + | daPyStts0_UNK2000_e| daPyStts0_TELESCOPE_LOOK_e + | daPyStts0_UNK800000_e | daPyStts0_UNK1000000_e + | daPyStts0_UNK2000000_e | daPyStts0_UNK4000000_e + | daPyStts0_UNK10000000_e | daPyStts0_UNK20000000_e }; enum daPy__PlayerStatus1 { @@ -3855,7 +3863,7 @@ inline fopAc_ac_c* dComIfGp_att_getCatghTarget() { } inline void dComIfGp_att_ChangeOwner() { - dComIfGp_getAttention().setFlag(0x80); + dComIfGp_getAttention().setFlag(AttnFlag_00000080); } inline fopAc_ac_c* dComIfGp_att_getLookTarget() { diff --git a/include/f_op/f_op_actor.h b/include/f_op/f_op_actor.h index 6a76f7353..6198d8ae2 100644 --- a/include/f_op/f_op_actor.h +++ b/include/f_op/f_op_actor.h @@ -188,7 +188,7 @@ public: void setXyCheckCB(CallbackFunc cb) { mpCheckCB = cb; } s16 runXyCheckCB(void* ac, int i_itemBtn) { if (mpCheckCB == NULL) - return -1; + return 1; return mpCheckCB(ac, i_itemBtn); } void setPhotoEventCB(CallbackFunc cb) { mpPhotoCB = cb; } diff --git a/include/m_Do/m_Do_controller_pad.h b/include/m_Do/m_Do_controller_pad.h index f835f630e..443d17253 100644 --- a/include/m_Do/m_Do_controller_pad.h +++ b/include/m_Do/m_Do_controller_pad.h @@ -36,4 +36,8 @@ extern interface_of_controller_pad g_mDoCPd_cpadInfo[4]; int mDoCPd_Create(); int mDoCPd_Read(); +inline bool mDoCPd_L_LOCK_BUTTON(unsigned long i_playerNo) { + return g_mDoCPd_cpadInfo[i_playerNo].mHoldLockL; +} + #endif diff --git a/src/d/d_attention.cpp b/src/d/d_attention.cpp index a59b6f19c..9a79de5c7 100644 --- a/src/d/d_attention.cpp +++ b/src/d/d_attention.cpp @@ -4,27 +4,41 @@ // #include "d/d_attention.h" -#include "f_op/f_op_actor_mng.h" -#include "d/d_com_inf_game.h" #include "d/d_procname.h" #include "d/actor/d_a_player_main.h" #include "d/d_s_play.h" -#include "m_Do/m_Do_ext.h" -#include "JSystem/JKernel/JKRSolidHeap.h" #include "SSystem/SComponent/c_angle.h" +#include "d/res/res_always.h" +#include "f_op/f_op_camera.h" +#include "m_Do/m_Do_controller_pad.h" +#include "m_Do/m_Do_graphic.h" s32 dAttention_c::loc_type_num = 3; u32 dAttention_c::act_type_num = 5; +dAttention_c::LocTbl dAttention_c::loc_type_tbl[3] = { + { 0, 1 }, + { 1, 2 }, + { 2, 4 }, +}; + +dAttention_c::LocTbl dAttention_c::act_type_tbl[5] = { + { 3, 0x08 }, + { 4, 0x10 }, + { 5, 0x20 }, + { 6, 0x40 }, + { 7, 0x80 }, +}; + /* 8009D220-8009D268 .text __ct__11dAttParam_cFl */ dAttParam_c::dAttParam_c(s32) { field_0x04 = 45.0f; field_0x08 = 30.0f; field_0x0c = 90.0f; - field_0x00 = 1; - field_0x18 = -0.9f; - field_0x10 = 3000.0f; - field_0x14 = 1000.0f; + mFlags = 1; + mSWModeDisable = -0.9f; + mDangerBGMDistance = 3000.0f; + mBGMDistMargin = 1000.0f; } /* 8009D268-8009D2B0 .text __dt__11dAttParam_cFv */ @@ -46,8 +60,8 @@ dAttention_c::dAttention_c(fopAc_ac_c* player, u32 playerNo) { initList(0xFFFFFFFF); mFlagMask = 0; field_0x01c = -1; - field_0x019 = 0; - mLockOnState = 0; + field_0x019 = LockState_NONE; + mLockOnState = LockState_NONE; field_0x01a = 0; field_0x01b = 0; mLockOnTargetBsPcID = fpcM_ERROR_PROCESS_ID_e; @@ -126,7 +140,10 @@ dAttList_c* dAttention_c::GetLockonList(s32 idx) { dAttList_c* dAttention_c::getActionBtnB() { int i; dAttList_c* list = GetLockonList(0); - if (list != NULL && list->getActor() != NULL && list->mType == fopAc_Attn_TYPE_TALK_e && LockonTruth() != 0 && !(list->getActor()->attention_info.flags & fopAc_Attn_TALKFLAG_NOTALK_e)) + if (list != NULL && list->getActor() != NULL && + list->mType == fopAc_Attn_TYPE_TALK_e && + LockonTruth() != 0 && + !(list->getActor()->attention_info.flags & fopAc_Attn_TALKFLAG_NOTALK_e)) return list; if (mActionNum == 0) @@ -151,13 +168,7 @@ dAttList_c* dAttention_c::getActionBtnXYZ_local(int button) { if (list != NULL && list->getActor() != NULL && list->mType == fopAc_Attn_TYPE_TALK_e && LockonTruth()) { fopAc_ac_c* actor = list->getActor(); if (actor->eventInfo.chkCondition(dEvtCnd_CANTALKITEM_e)) { - s16 rt; - if (actor->eventInfo.mpCheckCB == NULL) - rt = 1; - else - rt = actor->eventInfo.mpCheckCB(actor, button); - - if (rt) + if (actor->eventInfo.runXyCheckCB(actor, button)) return list; } @@ -170,13 +181,7 @@ dAttList_c* dAttention_c::getActionBtnXYZ_local(int button) { if (mActionList[i].mType == fopAc_Attn_TYPE_SPEAK_e) { fopAc_ac_c* actor = mActionList[i].getActor(); if (actor->eventInfo.chkCondition(dEvtCnd_CANTALKITEM_e)) { - s16 rt; - if (actor->eventInfo.mpCheckCB == NULL) - rt = 1; - else - rt = actor->eventInfo.mpCheckCB(actor, button); - - if (rt) + if (actor->eventInfo.runXyCheckCB(actor, button)) return &mActionList[i]; } } @@ -210,14 +215,8 @@ dAttList_c* dAttention_c::getActionBtnZ() { return getActionBtnXYZ_local(2); } -dAttention_c::LocTbl dAttention_c::loc_type_tbl[3] = { - { 0, 1 }, - { 1, 2 }, - { 2, 4 }, -}; - /* 8009DAA4-8009DAF4 .text chkAttMask__12dAttention_cFUlUl */ -u32 dAttention_c::chkAttMask(u32 type, u32 mask) { +s32 dAttention_c::chkAttMask(u32 type, u32 mask) { for (s32 i = 0; i < loc_type_num; i++) { if (type == loc_type_tbl[i].mType) { return mask & loc_type_tbl[i].mMask; @@ -228,33 +227,157 @@ u32 dAttention_c::chkAttMask(u32 type, u32 mask) { } /* 8009DAF4-8009DB60 .text check_event_condition__FUlUs */ -void check_event_condition(u32, u16) { - /* Nonmatching */ +s32 check_event_condition(u32 attnType, u16 flags) { + switch(attnType) { + case fopAc_Attn_TYPE_SPEAK_e: + case fopAc_Attn_TYPE_TALK_e: + if ((flags & dEvtCnd_CANTALK_e) != dEvtCnd_NONE_e) { + break; + } + return true; + + case fopAc_Attn_TYPE_DOOR_e: + if ((flags & dEvtCnd_CANDOOR_e) != dEvtCnd_NONE_e) { + break; + } + return true; + case fopAc_Attn_TYPE_TREASURE_e: + if ((flags & dEvtCnd_CANDOOR_e) != dEvtCnd_NONE_e) { + break; + } + return true; + } + return false; } + /* 8009DB60-8009DC28 .text check_flontofplayer__FUlss */ -void check_flontofplayer(u32, s16, s16) { - /* Nonmatching */ +s32 check_flontofplayer(u32 checkMask, s16 angle1, s16 angle2) { + /// merged from TP + static uint ftp_table[] = { + 0x04, 0x01, 0x02, 0x08, 0x10, 0x20, 0x40, 0x80, 0x100, + }; + static s16 ang_table[3] = { + 0x4000, + 0x2000, + 0x0AAA, + }; + static s16 ang_table2[] = { + 0x0AAA, 0x2000, 0x2AAA, 0x4000, 0x4E38, 0x6000, + }; + + if (angle1 < 0) { + angle1 = -angle1; + } + + if (angle2 < 0) { + angle2 = -angle2; + } + + for (int i = 0; i < 3; i++) { + if (checkMask & ftp_table[i]) { + if (angle1 > ang_table[i]) { + return true; + } + } + } + + for (int i = 8; i > 2; i--) { + if (checkMask & ftp_table[i]) { + if (angle2 > ang_table2[i - 3]) { + return true; + } + } + } + + return false; } /* 8009DC28-8009DC74 .text distace_weight__Ffsf */ -void distace_weight(f32, s16, f32) { - /* Nonmatching */ +f32 distace_weight(f32 distance, s16 angle, f32 ratio) { + f32 turns = (f32)angle / 32768.0F; + return distance * (f32)((1.0F - ratio) + (f32)(ratio * (turns * turns))); } /* 8009DC74-8009DCD4 .text distace_angle_adjust__Ffsf */ -void distace_angle_adjust(f32, s16, f32) { - /* Nonmatching */ +f32 distace_angle_adjust(f32 distance, s16 angle, f32 ratio) { + f32 turns = angle / (f32)0x8000; + if (turns < 0.0f) { + turns = -turns; + } + + return distance * ((1.0f - ratio) + (ratio * ((1.0f - turns) * (1.0f - turns)))); } /* 8009DCD4-8009DE44 .text check_distace__FP4cXyzsP4cXyzffff */ -void check_distace(cXyz*, s16, cXyz*, f32, f32, f32, f32) { - /* Nonmatching */ +s32 check_distace(cXyz* playerPos, s16 angle, cXyz* actorPos, f32 maxDistXZBase, f32 maxDistAngleMul, f32 maxDeltaY, f32 minDeltaY) { + cXyz dist = *actorPos - *playerPos; + + if (dist.y <= minDeltaY || dist.y >= maxDeltaY) { + return false; + } + + f32 adjust = maxDistXZBase + distace_angle_adjust(maxDistAngleMul, angle, 1.0f); + if (adjust < dist.absXZ()) { + return false; + } + + return true; } /* 8009DE44-8009E03C .text calcWeight__12dAttention_cFiP10fopAc_ac_cfssPUl */ -f32 dAttention_c::calcWeight(int, fopAc_ac_c*, f32, s16, s16, u32*) { - /* Nonmatching */ +f32 dAttention_c::calcWeight(int listType, fopAc_ac_c* actor, f32 distance, s16 angle, s16 invAngle, u32* attnType) { + int i; + int num; + LocTbl* table; + + num = (listType == 'L') ? loc_type_num : act_type_num; + table = (listType == 'L') ? loc_type_tbl : act_type_tbl; + + f32 weight = 0.0f; + f32 max_weight = 0.0f; + + daPy_py_c* player = daPy_getPlayerActorClass(); + if (player != NULL) { + if (actor == fopAcM_SearchByID(player->getGrabActorID())) { + return 0.0f; + } + } + + for (i = 0; i < num; i++) { + f32 dist_weight; + LocTbl* locEntry = &table[i]; + + if (mFlagMask & locEntry->mMask & actor->attention_info.flags) { + DistTbl* distEntry; + u8 dist_index = actor->attention_info.distances[locEntry->mType]; + + if (check_event_condition(locEntry->mType, actor->eventInfo.getCondition())) { + dist_weight = 0.0f; + } else { + distEntry = &dist_table[dist_index]; + if (check_flontofplayer(distEntry->mFrontAngleCheckBits, angle, invAngle)) { + dist_weight = 0.0f; + } else if (!check_distace(&mpPlayer->attention_info.position, angle, &actor->attention_info.position, + distEntry->mDistXZMax, distEntry->mDistXZAngleAdjust, distEntry->mDeltaYMax, + distEntry->mDeltaYMin)) { + dist_weight = 0.0f; + } else { + dist_weight = distace_weight(distance, angle, 0.5f); + } + } + if (dist_weight > 0.0f) { + f32 dist_tbl_weight = dist_table[dist_index].mWeightDivisor; + if (dist_tbl_weight > max_weight) { + max_weight = dist_tbl_weight; + weight = dist_weight / dist_tbl_weight; + *attnType = locEntry->mType; + } + } + } + } + + return weight; } /* 8009E03C-8009E128 .text setLList__12dAttention_cFP10fopAc_ac_cffUl */ @@ -367,12 +490,37 @@ int dAttention_c::SelectAttention(fopAc_ac_c* ac) { /* 8009E474-8009E5C4 .text sortList__12dAttention_cFv */ void dAttention_c::sortList() { - /* Nonmatching */ + int i; + int j; + dAttList_c swap; + dAttList_c* list; + + list = mLockOnList; + for (i = 0; i < mLockOnNum - 1; i++) { + for (j = i + 1; j < mLockOnNum; j++) { + if (list[i].mWeight > list[j].mWeight) { + memcpy(&swap, &list[j], sizeof(dAttList_c)); + memcpy(&list[j], &list[i], sizeof(dAttList_c)); + memcpy(&list[i], &swap, sizeof(dAttList_c)); + } + } + } + + list = mActionList; + for (i = 0; i < mActionNum - 1; i++) { + for (j = i + 1; j < mActionNum; j++) { + if (list[i].mWeight > list[j].mWeight) { + memcpy(&swap, &list[j], sizeof(dAttList_c)); + memcpy(&list[j], &list[i], sizeof(dAttList_c)); + memcpy(&list[i], &swap, sizeof(dAttList_c)); + } + } + } } /* 8009E5C4-8009E684 .text stockAttention__12dAttention_cFUl */ -void dAttention_c::stockAttention(u32 interactMask) { - fopAc_ac_c * pTarget = LockonTarget(0); +fopAc_ac_c* dAttention_c::stockAttention(u32 interactMask) { + fopAc_ac_c *pTarget = LockonTarget(0); initList(interactMask); if (makeList()) sortList(); @@ -380,19 +528,19 @@ void dAttention_c::stockAttention(u32 interactMask) { if (pTarget != mLockOnList[0].getActor()) { if (pTarget != NULL) { if (mLockOnList[0].getActor() != NULL) - setFlag(0x02); + setFlag(AttnFlag_00000002); } else { - setFlag(0x01); + setFlag(AttnFlag_00000001); } - setFlag(0x04); + setFlag(AttnFlag_00000004); } - LockonTarget(0); + return LockonTarget(0); } /* 8009E684-8009E728 .text nextAttention__12dAttention_cFUl */ -void dAttention_c::nextAttention(u32 interactMask) { +fopAc_ac_c *dAttention_c::nextAttention(u32 interactMask) { fopAc_ac_c * pTarget = fopAcM_SearchByID(mLockOnTargetBsPcID); initList(interactMask); if (makeList()) @@ -401,7 +549,7 @@ void dAttention_c::nextAttention(u32 interactMask) { if (pTarget == mLockOnList[0].getActor() && mLockOnNum > 1) mLockOnOffs = 1; - LockonTarget(0); + return LockonTarget(0); } /* 8009E728-8009E764 .text freeAttention__12dAttention_cFv */ @@ -415,8 +563,51 @@ s32 dAttention_c::freeAttention() { } /* 8009E764-8009E978 .text chaseAttention__12dAttention_cFv */ -void dAttention_c::chaseAttention() { - /* Nonmatching */ +bool dAttention_c::chaseAttention() { + int offset = mLockOnOffs; + fopAc_ac_c* actor = mLockOnList[offset].getActor(); + + if (actor == NULL) { + return false; + } + + cSGlobe globe1 = actor->attention_info.position - mpPlayer->attention_info.position; + cSAngle angle1; + angle1 = globe1.U() - fopAcM_GetShapeAngle_p(mpPlayer)->y; + + cSGlobe globe2(mpPlayer->attention_info.position - actor->attention_info.position); + cSAngle angle2; + angle2 = globe2.U() - fopAcM_GetShapeAngle_p(actor)->y; + + u32 type; + f32 weight = calcWeight('L', actor, globe1.R(), angle1.Val(), angle2.Val(), &type); + if (weight <= 0.0f) { + type = mLockOnList[offset].mType; + int tbl_idx = actor->attention_info.distances[type]; + + if (!chkAttMask(type, actor->attention_info.flags)) { + return false; + } else if (check_event_condition(type, actor->eventInfo.getCondition()) != 0) { + return false; + } else if (check_flontofplayer(dist_table[tbl_idx].mFrontAngleCheckBits, angle1.Val(), angle2.Val())) { + return false; + } else if (check_distace(&mpPlayer->attention_info.position, angle1.Val(), &actor->attention_info.position, + dist_table[tbl_idx].mDistXZMaxRelease, + dist_table[tbl_idx].mDistXZAngleAdjust, + dist_table[tbl_idx].mDeltaYMax, dist_table[tbl_idx].mDeltaYMin)) { + mLockOnList[offset].mWeight = distace_weight(globe1.R(), angle1.Val(), 0.5f); + return true; + } + + return false; + } + + mLockOnList[offset].setActor(actor); + mLockOnList[offset].mWeight = weight; + mLockOnList[offset].mDistance = globe1.R(); + mLockOnList[offset].mType = type; + return true; + } /* 8009E978-8009EA24 .text EnemyDistance__12dAttention_cFP10fopAc_ac_c */ @@ -453,19 +644,67 @@ BOOL sound_attention(fopAc_ac_c* actor, void* userWork) { void dAttention_c::runSoundProc() { mEnemyBsPcId = fpcM_ERROR_PROCESS_ID_e; mEnemyDistance = 10000.0f; - if (!chkFlag(0x80000000)) { + if (!chkFlag(AttnFlag_80000000)) { fopAcIt_Executor((fopAcIt_ExecutorFunc)sound_attention, this); fopAc_ac_c* actor = fopAcM_SearchByID(mEnemyBsPcId); if (actor != NULL) { mDoAud_bgmNowBattle(mEnemyDistance * 0.1f); - setFlag(0x100); + setFlag(AttnFlag_00000100); } } } /* 8009EB38-8009EDB8 .text runDrawProc__12dAttention_cFv */ void dAttention_c::runDrawProc() { - /* Nonmatching */ + if (chkFlag(AttnFlag_00000008)) { + draw[0].setAnm(ALWAYS_BCK_YJ_SCALE, ALWAYS_BPK_YJ_SCALE, J3DFrameCtrl::EMode_NONE); + if (!dComIfGp_checkPlayerStatus0(0, daPyStts0_UNK37a02371_e) + || dComIfGp_checkPlayerStatus1(0, daPyStts1_WIND_WAKER_CONDUCT_e | daPyStts1_UNK10_e)) { + mDoAud_seStart(JA_SE_L_FOCUS_SET); + } + } else if (chkFlag(AttnFlag_00000010)) { + draw[0].setAnm(ALWAYS_BCK_YJ_DELETE, ALWAYS_BPK_YJ_DELETE, J3DFrameCtrl::EMode_NONE); + if (field_0x028 >= 0) { + field_0x028 = 1; + setFlag(AttnFlag_40000000); + } + + if (!dComIfGp_checkPlayerStatus0(0, daPyStts0_UNK37a02371_e) + || dComIfGp_checkPlayerStatus1(0, daPyStts1_WIND_WAKER_CONDUCT_e | daPyStts1_UNK10_e)) { + mDoAud_seStart(JA_SE_L_FOCUS_RESET); + } + } else if (chkFlag(AttnFlag_00000001)) { + draw[0].setAnm(ALWAYS_BCK_YJ_IN, ALWAYS_BPK_YJ_IN, J3DFrameCtrl::EMode_NONE); + setFlag(AttnFlag_40000000); + } else if (chkFlag(AttnFlag_00000002)) { + draw[0].setAnm(ALWAYS_BCK_YJ_IN, ALWAYS_BPK_YJ_IN, J3DFrameCtrl::EMode_NONE); + draw[1].setAnm(ALWAYS_BCK_YJ_OUT, ALWAYS_BPK_YJ_OUT, J3DFrameCtrl::EMode_NONE); + setFlag(AttnFlag_40000000); + } else if (mLockOnNum <= 0 && field_0x028 == 0) { + draw[0].setAnm(ALWAYS_BCK_YJ_OUT, ALWAYS_BPK_YJ_OUT, J3DFrameCtrl::EMode_NONE); + field_0x028 = 1; + setFlag(AttnFlag_40000000); + } + + int result; + if (mLockOnState == LockState_LOCK) { + result = draw[0].anm->play(NULL, 0, 0); + if (result) { + draw[0].setAnm(ALWAYS_BCK_YJ_LOOP, -1, J3DFrameCtrl::EMode_LOOP); + clrFlag(AttnFlag_40000000); + } + } else { + result = draw[0].anm->play(NULL, 0, 0); + if (result) { + clrFlag(AttnFlag_40000000); + field_0x028 = 0xff; + } + } + + result = draw[1].anm->play(NULL, 0, 0); + if (result) { + draw[1].mpAnmClr = NULL; + } } /* 8009EDB8-8009EDBC .text runDebugDisp0__12dAttention_cFv */ @@ -478,47 +717,293 @@ void dAttention_c::runDebugDisp() { /* 8009EDC0-8009EE90 .text judgementButton__12dAttention_cFv */ void dAttention_c::judgementButton() { - /* Nonmatching */ + if (dComIfGp_checkPlayerStatus0(0, daPyStts0_UNK37a02371_e) + || dComIfGp_checkPlayerStatus1(0, daPyStts1_WIND_WAKER_CONDUCT_e | daPyStts1_UNK10_e)) { + if ((int)field_0x01a >= 3) + return; + if ((int)field_0x01a < 1) + return; + field_0x01a = 0; + } else { + switch(field_0x01a) { + case 0: + if (!mDoCPd_L_LOCK_BUTTON(mPlayerNo)) { + break; + } + field_0x01a = 1; + break; + case 1: + field_0x01a = 2; + case 2: + if (!mDoCPd_L_LOCK_BUTTON(mPlayerNo)) { + field_0x01a = 0; + } + break; + } + } } /* 8009EE90-8009EED8 .text judgementTriggerProc__12dAttention_cFv */ void dAttention_c::judgementTriggerProc() { - /* Nonmatching */ + bool haveTarget = chaseAttention(); + if (haveTarget) { + setFlag(AttnFlag_00000008); + mLockOnState = LockState_LOCK; + } } /* 8009EED8-8009EF40 .text judgementLostCheck__12dAttention_cFv */ -void dAttention_c::judgementLostCheck() { - /* Nonmatching */ +int dAttention_c::judgementLostCheck() { + bool haveTarget = chaseAttention(); + if (haveTarget) { + return false; + } + mLockOnState = LockState_NONE; + setFlag(AttnFlag_00000010); + freeAttention(); + setFlag(AttnFlag_00000040); + return true; } /* 8009EF40-8009F0A4 .text judgementStatusSw__12dAttention_cFUl */ -void dAttention_c::judgementStatusSw(u32) { - /* Nonmatching */ +void dAttention_c::judgementStatusSw(u32 interactMask) { + fpc_ProcID target; + fopAc_ac_c *actor; + + switch(mLockOnState) { + case LockState_NONE: + mLockOnTargetBsPcID = -1; + stockAttention(interactMask); + if (field_0x01a == 1) { + judgementTriggerProc(); + } + break; + case LockState_LOCK: + target = LockonTargetPId(0); + mLockOnTargetBsPcID = target; + if (field_0x01a == 1) { + f32 stickY = g_mDoCPd_cpadInfo[mPlayerNo].mMainStickPosY; + if (-0.9f < stickY && + (actor = nextAttention(interactMask), actor != 0) && + mLockOnNum > 1) { + setFlag(AttnFlag_00000008); + } else { + mLockOnState = LockState_RELEASE; + setFlag(AttnFlag_00000010); + } + } else { + judgementLostCheck(); + } + break; + case LockState_RELEASE: + setFlag(AttnFlag_00000040); + if (field_0x01a == 1) { + mLockOnState = LockState_NONE; + judgementTriggerProc(); + } + else { + actor = LockonTarget(0); + if (actor == NULL || !chkFlag(AttnFlag_40000000)) { + mLockOnState = LockState_NONE; + freeAttention(); + } + } + break; + } } /* 8009F0A4-8009F1D4 .text judgementStatusHd__12dAttention_cFUl */ -void dAttention_c::judgementStatusHd(u32) { - /* Nonmatching */ +void dAttention_c::judgementStatusHd(u32 interactMask) { + switch(mLockOnState) { + case LockState_NONE: + mLockOnTargetBsPcID = -1; + stockAttention(interactMask); + if (field_0x01a == 1) { + judgementTriggerProc(); + } + break; + case LockState_LOCK: { + fpc_ProcID target = LockonTargetPId(0); + mLockOnTargetBsPcID = target; + s32 result = judgementLostCheck(); + if (result == 0 && field_0x01a == 0) { + mLockOnState = LockState_RELEASE; + setFlag(AttnFlag_00000010); + } + break; + } + case LockState_RELEASE: + setFlag(AttnFlag_00000040); + if (field_0x01a == 1) { + fopAc_ac_c *actor = nextAttention(interactMask); + if (actor != NULL) { + setFlag(AttnFlag_00000008); + mLockOnState = LockState_LOCK; + } else { + mLockOnState = LockState_NONE; + freeAttention(); + } + } + else { + fopAc_ac_c *actor = LockonTarget(0); + if (actor == NULL || !chkFlag(AttnFlag_40000000)) { + mLockOnState = LockState_NONE; + freeAttention(); + } + } + break; + } } /* 8009F1D4-8009F460 .text Run__12dAttention_cFUl */ -void dAttention_c::Run(u32) { - /* Nonmatching */ +bool dAttention_c::Run(u32 interactMask) { + bool var = dComIfGs_getOptAttentionType() == 0; + if (chkFlag(AttnFlag_00000080)) { + mpPlayer = (daPy_lk_c*)dComIfGp_getPlayer(0); + mPlayerNo = 0; + } + runDebugDisp0(); + clrFlag(~(AttnFlag_80000000 | AttnFlag_40000000 | AttnFlag_20000000 | AttnFlag_10000000 | AttnFlag_08000000)); + if (dComIfGp_event_getMode() != 0) { + mLockOnState = LockState_NONE; + field_0x01a = 0; + field_0x01b = 0; + clrFlag(AttnFlag_20000000); + clrFlag(AttnFlag_10000000); + clrFlag(~(AttnFlag_80000000 | AttnFlag_40000000 | AttnFlag_20000000 | AttnFlag_10000000 | AttnFlag_08000000)); + mLockOnTargetBsPcID = -1; + freeAttention(); + } else { + judgementButton(); + if (var) { + judgementStatusHd(interactMask); + } else { + judgementStatusSw(interactMask); + } + + if (chkFlag(AttnFlag_10000000)) { + if (!mDoCPd_L_LOCK_BUTTON(mPlayerNo)) { + if (chkFlag(AttnFlag_20000000)) { + mDoAud_seStart(JA_SE_CAMERA_L_CANCEL); + clrFlag(AttnFlag_20000000); + } + clrFlag(AttnFlag_10000000); + } + } else if (mDoCPd_L_LOCK_BUTTON(mPlayerNo)) { + fopAc_ac_c *target = LockonTarget(0); + if (target == NULL) { + setFlag(AttnFlag_20000000 | AttnFlag_00000020); + mDoAud_seStart(JA_SE_CAMERA_L_MOVE); + } + setFlag(AttnFlag_10000000); + } + } + field_0x019 = mLockOnState; + runSoundProc(); + runDrawProc(); + runDebugDisp(); + if (mLockOnState == LockState_LOCK) { + dComIfGp_onCameraAttentionStatus(mPlayerNo, 1); + } else { + dComIfGp_offCameraAttentionStatus(mPlayerNo, 1); + } + + mHint.proc(); + mCatch.proc(); + mLook[0].proc(); + mLook[1].proc(); + return true; } /* 8009F460-8009F5FC .text Draw__12dAttention_cFv */ void dAttention_c::Draw() { - /* Nonmatching */ + Mtx invCamera; + MTXInverse(dComIfGd_getViewRotMtx(), invCamera); + fopAc_ac_c *target = LockonTarget(0); + if (dComIfGp_event_runCheck() || dComIfGp_getScopeMesgStatus() != 0) + return; + if (target != NULL) { + if (target != NULL) { + draw[0].draw(target->attention_info.position, invCamera); + } + + if (mLockOnNum >= 2 && draw[1].mpAnmClr != NULL) { + int listIdx = mLockOnOffs; + + if (mLockOnOffs == 0) { + listIdx = mLockOnNum - 1; + } else { + listIdx--; + } + + if (mLockOnList[listIdx].getActor() != NULL) { + fopAc_ac_c* target = mLockOnList[listIdx].getActor(); + draw[1].draw(target->attention_info.position, invCamera); + } + } + + fpc_ProcID id = LockonTargetPId(0); + mlockedOnPId = id; + mDrawAttnPos = target->attention_info.position; + field_0x028 = 0; + } else { + if (field_0x028 > 0) { + target = fopAcM_SearchByID(mlockedOnPId); + if (target != NULL) { + draw[0].draw(target->attention_info.position, invCamera); + mDrawAttnPos = target->attention_info.position; + } else { + draw[0].draw(mDrawAttnPos, invCamera); + } + } + } } /* 8009F5FC-8009F6B4 .text setAnm__10dAttDraw_cFiii */ -void dAttDraw_c::setAnm(int, int, int) { - /* Nonmatching */ +void dAttDraw_c::setAnm(int resIdxTransform, int resIdxColor, int loopMode) { + J3DAnmTransform *pAnimRes; + J3DAnmColor *color; + + pAnimRes = (J3DAnmTransform *)dComIfG_getObjectRes("Always", resIdxTransform); + anm->setAnm(pAnimRes, loopMode, 0.0, 1.0, 0.0, -1.0, NULL); + if (resIdxColor < 0) { + mpAnmClr = NULL; + } + else { + color = (J3DAnmColor *)dComIfG_getObjectRes("Always", resIdxColor); + mpAnmClr = color; + } } /* 8009F6B4-8009F834 .text draw__10dAttDraw_cFR4cXyzPA4_f */ -void dAttDraw_c::draw(cXyz&, Mtx) { - /* Nonmatching */ +void dAttDraw_c::draw(cXyz &pos, Mtx mtx) { + J3DModel *model = anm->mpModel; + mDoMtx_stack_c::transS(pos); + mDoMtx_stack_c::concat(mtx); + model->setBaseTRMtx(mDoMtx_stack_c::get()); + + J3DModelData *modeldata = model->getModelData(); + if (mpAnmClr == NULL) { + J3DAnmColor *color = (J3DAnmColor*)dComIfG_getObjectRes("Always", ALWAYS_BPK_YJ_IN); + modeldata->getMaterialTable().removeMatColorAnimator(color); + } else { + mpAnmClr->setFrame(anm->mFrameCtrl.getFrame()); + J3DMatColorAnm *p = mpAnmMatClr; + for(u16 i = 0; i < mpAnmClr->getUpdateMaterialNum(); i++) { + p->setAnmColor(mpAnmClr); + p->setAnmIndex(i); + p++; + } + modeldata->getMaterialTable().setMatColorAnimator(mpAnmClr, mpAnmMatClr); + } + + if (mDoGph_gInf_c::isMonotone()) { + dComIfGd_setListP1(); + } else { + dComIfGd_setListMaskOff(); + } + anm->updateDL(); + dComIfGd_setList(); } /* 8009F834-8009F88C .text LockonTarget__12dAttention_cFl */ @@ -534,8 +1019,21 @@ fopAc_ac_c* dAttention_c::LockonTarget(s32 idx) { } /* 8009F88C-8009F980 .text LockonReleaseDistanse__12dAttention_cFv */ -void dAttention_c::LockonReleaseDistanse() { - /* Nonmatching */ +f32 dAttention_c::LockonReleaseDistanse() { + if (!LockonTruth()) { + return 0.0f; + } + + fopAc_ac_c* actor = mLockOnList[mLockOnOffs].getActor(); + if (actor == NULL) { + return 0.0f; + } + + int idx = actor->attention_info.distances[mLockOnList[mLockOnOffs].mType]; + cSGlobe globe(actor->attention_info.position - mpPlayer->attention_info.position); + cSAngle angle(globe.U() - fopAcM_GetShapeAngle_p(mpPlayer)->y); + + return distace_angle_adjust(dist_table[idx].mDistXZAngleAdjust, angle, 1.0f) + dist_table[idx].mDistXZMaxRelease; } /* 8009F980-8009F9B8 .text LockonTargetPId__12dAttention_cFl */ @@ -564,7 +1062,7 @@ fopAc_ac_c* dAttention_c::ActionTarget(s32 idx) { /* 8009FA10-8009FA64 .text LockonTruth__12dAttention_cFv */ bool dAttention_c::LockonTruth() { - return mLockOnState == 1 || (mLockOnState == 2 && LockonTarget(0)); + return mLockOnState == LockState_LOCK || (mLockOnState == LockState_RELEASE && LockonTarget(0)); } /* 8009FA64-8009FA98 .text getActor__10dAttList_cFv */ @@ -621,24 +1119,62 @@ fopAc_ac_c* dAttCatch_c::convPId(fpc_ProcID i_procID) { /* 8009FBBC-8009FBDC .text init__11dAttCatch_cFv */ void dAttCatch_c::init() { - field_0xc = 0x56; - field_0x0 = fpcM_ERROR_PROCESS_ID_e; + mCatchItemNo = 0x56; + mRequestActorID = fpcM_ERROR_PROCESS_ID_e; mCatghTargetID = fpcM_ERROR_PROCESS_ID_e; field_0x4 = 3; } /* 8009FBDC-8009FC08 .text proc__11dAttCatch_cFv */ void dAttCatch_c::proc() { - mCatghTargetID = field_0x0; - mChangeItem = field_0xc; - field_0x0 = fpcM_ERROR_PROCESS_ID_e; + mCatghTargetID = mRequestActorID; + mChangeItem = mCatchItemNo; + mRequestActorID = fpcM_ERROR_PROCESS_ID_e; field_0x4 = 3; - field_0xc = 0x56; + mCatchItemNo = 0x56; } + /* 8009FC08-8009FE10 .text request__11dAttCatch_cFP10fopAc_ac_cUcfffsi */ -void dAttCatch_c::request(fopAc_ac_c*, u8, f32, f32, f32, s16, int) { - /* Nonmatching */ +bool dAttCatch_c::request(fopAc_ac_c* reqActor, u8 itemNo, f32 horizontalDist, f32 upDist, f32 downDist, s16 angle, int param_7) { + // TODO: what is param_7? + fopAc_ac_c* player = dComIfGp_getPlayer(0); + if (param_7 > field_0x4) { + return false; + } + + cXyz vec_to_player = reqActor->attention_info.position - player->attention_info.position; + if (vec_to_player.y < downDist || vec_to_player.y > upDist) { + return false; + } + + f32 player_xz_dist = vec_to_player.absXZ(); + if (player_xz_dist > horizontalDist) { + return false; + } + + if (angle != 0) { + cSGlobe globe(vec_to_player); + csXyz* player_angle_p = fopAcM_GetShapeAngle_p(player); + + s16 angle2 = globe.U() - player_angle_p->y; + if (angle2 < 0) { + angle2 = -angle2; + } + if (angle2 > angle) { + return false; + } + } + + if (param_7 < field_0x4 || player_xz_dist < mDistance) { + field_0x4 = param_7; + mCatchItemNo = itemNo; + mRequestActorID = fopAcM_GetID(reqActor); + mDistance = player_xz_dist; + return true; + } + + return false; } /* 8009FE10-8009FE40 .text convPId__10dAttLook_cFUi */ @@ -648,24 +1184,85 @@ fopAc_ac_c* dAttLook_c::convPId(fpc_ProcID i_procID) { /* 8009FE40-8009FE58 .text init__10dAttLook_cFv */ void dAttLook_c::init() { - field_0x0 = fpcM_ERROR_PROCESS_ID_e; + mRequestActorID = fpcM_ERROR_PROCESS_ID_e; mLookTargetID = fpcM_ERROR_PROCESS_ID_e; field_0x4 = 3; } /* 8009FE58-8009FE74 .text proc__10dAttLook_cFv */ void dAttLook_c::proc() { - mLookTargetID = field_0x0; - field_0x0 = fpcM_ERROR_PROCESS_ID_e; + mLookTargetID = mRequestActorID ; + mRequestActorID = fpcM_ERROR_PROCESS_ID_e; field_0x4 = 3; } /* 8009FE74-800A009C .text request__10dAttLook_cFP10fopAc_ac_cfffsi */ -void dAttLook_c::request(fopAc_ac_c*, f32, f32, f32, s16, int) { - /* Nonmatching */ +bool dAttLook_c::request(fopAc_ac_c* reqActor, f32 horizontalDist, f32 upDist, f32 downDist, s16 angle, int param_6) { + // TODO: what is param_6 + fopAc_ac_c* player = dComIfGp_getPlayer(0); + if (param_6 > field_0x4) { + return false; + } + + cXyz vec_to_player = reqActor->eyePos - player->eyePos; + if (vec_to_player.y < downDist || vec_to_player.y > upDist) { + return false; + } + + f32 player_xz_dist = vec_to_player.absXZ(); + if (player_xz_dist > horizontalDist) { + return false; + } + + if (angle != 0) { + vec_to_player = reqActor->current.pos - player->current.pos; + cSGlobe globe(vec_to_player); + s16 angle2 = globe.U() - fopAcM_GetShapeAngle_p(player)->y; + if (angle2 < 0) { + angle2 = -angle2; + } + if (angle2 > angle) { + return false; + } + } + + if (param_6 < field_0x4 || player_xz_dist < mDistance) { + field_0x4 = param_6; + mRequestActorID = fopAcM_GetID(reqActor); + mDistance = player_xz_dist; + return true; + } + + return false; } /* 800A009C-800A0270 .text requestF__10dAttLook_cFP10fopAc_ac_csi */ -void dAttLook_c::requestF(fopAc_ac_c*, s16, int) { - /* Nonmatching */ +bool dAttLook_c::requestF(fopAc_ac_c* reqActor, s16 angle, int param_3) { + // TODO: what is param_3? + fopAc_ac_c* player = g_dComIfG_gameInfo.play.mpPlayer[0]; + if (param_3 > field_0x4) { + return false; + } + cXyz vec_to_player = reqActor->eyePos - player->eyePos; + f32 player_xz_dist = vec_to_player.absXZ(); + + if (angle != 0) { + vec_to_player = reqActor->current.pos - player->current.pos; + cSGlobe globe(vec_to_player); + s16 angle2 = globe.U() - fopAcM_GetShapeAngle_p(player)->y; + if (angle2 < 0) { + angle2 = -angle2; + } + if (angle2 > angle) { + return false; + } + } + if (param_3 < field_0x4 || player_xz_dist < mDistance) { + field_0x4 = param_3; + mRequestActorID = fopAcM_GetID(reqActor); + mDistance = player_xz_dist; + return true; + } + + return false; }