Files
tww/src/d/d_npc.cpp
T
2023-11-08 22:36:53 -05:00

777 lines
20 KiB
C++

//
// Generated by dtk
// Translation Unit: d_npc.cpp
//
#include "d/d_npc.h"
#include "d/d_com_inf_game.h"
#include "d/actor/d_a_player.h"
#include "f_op/f_op_actor_mng.h"
#include "f_op/f_op_msg_mng.h"
#include "SSystem/SComponent/c_math.h"
#include "JSystem/JGeometry.h"
#include "m_Do/m_Do_mtx.h"
// Needed for the .data section to match.
static Vec dummy_2100 = {1.0f, 1.0f, 1.0f};
static Vec dummy_2080 = {1.0f, 1.0f, 1.0f};
bool dNpc_JntCtrl_c::angCalcS(s16* out, s16 targetY, s16 speed, s16 maxVel) {
s16 diff = *out - targetY;
int origDiff = diff;
cLib_addCalcAngleS(&diff, 0, speed, maxVel, 0x60);
if(abs(diff) > speed) {
*out += diff - origDiff;
}
else {
*out = targetY;
}
return (s16)targetY - *out == 0;
}
void dNpc_JntCtrl_c::limitter(s16* targetDiff, s16 maxDiff, s16 minDiff) {
if(*targetDiff > maxDiff) {
*targetDiff = maxDiff;
}
if(*targetDiff < minDiff) {
*targetDiff = minDiff;
}
}
/* 8021A884-8021A97C .text follow__14dNpc_JntCtrl_cFPsssi */
bool dNpc_JntCtrl_c::follow(s16* outY, s16 targetY, s16 maxVel, int param_4) {
s16 origY = *outY;
angCalcS(outY, targetY, 4, maxVel);
s16 deltaY = *outY - origY;
s16 sVar6 = 0;
s16 sVar5 = 0;
s16 sVar1 = targetY - *outY;
for (int i = 1; i >= 0; i--) {
sVar5 += mAngles[i][param_4];
if ((deltaY > 0 && sVar5 > sVar1) || (deltaY < 0 && sVar5 < sVar1)) {
mAngles[i][param_4] = sVar1 - sVar6;
limitter(&mAngles[i][param_4], mMaxAngles[i][param_4], mMinAngles[i][param_4]);
}
sVar6 += mAngles[i][param_4];
}
return targetY != *outY;
}
/* 8021A97C-8021AABC .text move__14dNpc_JntCtrl_cFsi */
void dNpc_JntCtrl_c::move(short, int) {
/* Nonmatching */
}
/* 8021AABC-8021AC6C .text lookAtTarget__14dNpc_JntCtrl_cFPsP4cXyz4cXyzssb */
void dNpc_JntCtrl_c::lookAtTarget(short*, cXyz*, cXyz, short, short, bool) {
/* Nonmatching */
}
void dNpc_JntCtrl_c::setParam(s16 param_1, s16 maxSpineRot, s16 param_3, s16 minSpineRot, s16 param_5, s16 maxHeadRot, s16 param_7, s16 minHeadRot, s16 param_9) {
mMaxAngles[1][0] = param_1;
mMaxAngles[1][1] = maxSpineRot;
mMinAngles[1][0] = param_3;
mMinAngles[1][1] = minSpineRot;
mMaxAngles[0][0] = param_5;
mMaxAngles[0][1] = maxHeadRot;
mMinAngles[0][0] = param_7;
mMinAngles[0][1] = minHeadRot;
field_0x22 = param_9;
field_0x24 = param_9;
field_0x1E = param_9;
field_0x20 = param_9;
}
bool dNpc_PathRun_c::setInfDrct(dPath* pPath) {
mPath = pPath;
mCurrPointIndex = 0;
return true;
}
bool dNpc_PathRun_c::setInf(u8 pathIdx, s8 roomNo, u8 forwards) {
bool setPath = false;
mPath = 0;
mbGoingForwards = forwards;
if(pathIdx != 0xFF) {
mPath = dPath_GetRoomPath(pathIdx, roomNo);
mCurrPointIndex = 0;
setPath = true;
}
return setPath;
}
dPath* dNpc_PathRun_c::nextPath(s8 roomNo) {
dPath* pPath = 0;
if(mPath != 0) {
pPath = dPath_GetNextRoomPath(mPath, roomNo);
}
return pPath;
}
cXyz dNpc_PathRun_c::getPoint(u8 pointIdx) {
cXyz point(0.0f, 0.0f, 0.0f);
if(mPath != 0 && pointIdx < mPath->m_num) {
point = mPath->mpPnt[pointIdx].mPos;
}
return point;
}
/* 8021ADD0-8021AFA8 .text chkPointPass__14dNpc_PathRun_cF4cXyzb */
bool dNpc_PathRun_c::chkPointPass(cXyz currPos, bool goingForwards) {
bool passed = false;
if (mPath) {
cXyz target;
target.x = mPath->mpPnt[mCurrPointIndex].mPos.x;
target.z = mPath->mpPnt[mCurrPointIndex].mPos.z;
f32 deltaX;
f32 deltaZ;
if (mCurrPointIndex == 0) {
deltaX = mPath->mpPnt[1].mPos.x - mPath->mpPnt[0].mPos.x;
deltaZ = mPath->mpPnt[1].mPos.z - mPath->mpPnt[0].mPos.z;
} else if (mCurrPointIndex == mPath->m_num - 1) {
deltaX = mPath->mpPnt[mPath->m_num - 1].mPos.x - mPath->mpPnt[mPath->m_num - 2].mPos.x;
deltaZ = mPath->mpPnt[mPath->m_num - 1].mPos.z - mPath->mpPnt[mPath->m_num - 2].mPos.z;
} else {
deltaX = mPath->mpPnt[mCurrPointIndex + 1].mPos.x - mPath->mpPnt[mCurrPointIndex - 1].mPos.x;
deltaZ = mPath->mpPnt[mCurrPointIndex + 1].mPos.z - mPath->mpPnt[mCurrPointIndex - 1].mPos.z;
}
f32 f29 = cM_ssin(cM_atan2s(deltaX, deltaZ)) * (f32)0x7FFF;
f32 f2 = cM_scos(cM_atan2s(deltaX, deltaZ)) * (f32)0x7FFF;
f32 f3 = -(f29 * target.x + f2 * target.z);
if (goingForwards) {
passed = f29 * currPos.x + f2 * currPos.z + f3 > 0.0f;
} else {
passed = f29 * currPos.x + f2 * currPos.z + f3 <= 0.0f;
}
}
return passed;
}
bool dNpc_PathRun_c::incIdx() {
bool ret = true;
if(mPath != 0) {
mCurrPointIndex += 1;
if(mCurrPointIndex >= mPath->m_num) {
mCurrPointIndex = mPath->m_num - 1;
ret = false;
}
}
return ret;
}
bool dNpc_PathRun_c::incIdxLoop() {
bool ret = true;
if(mPath != 0) {
mCurrPointIndex += 1;
if(mCurrPointIndex >= mPath->m_num) {
mCurrPointIndex = 0;
ret = false;
}
}
return ret;
}
bool dNpc_PathRun_c::incIdxAuto() {
bool hitEnd = true;
if(mPath != 0) {
if(mPath->mLoops & 1) {
mCurrPointIndex += 1;
if(mCurrPointIndex >= mPath->m_num) {
mCurrPointIndex = 0;
}
}
else {
mCurrPointIndex += 1;
if(mCurrPointIndex >= mPath->m_num) {
mCurrPointIndex = mPath->m_num - 1;
hitEnd = false;
}
}
}
return hitEnd;
}
bool dNpc_PathRun_c::decIdx() {
bool ret = true;
if(mPath != 0) {
mCurrPointIndex -= 1;
if(mCurrPointIndex >= mPath->m_num) {
mCurrPointIndex = 0;
ret = false;
}
}
return ret;
}
bool dNpc_PathRun_c::decIdxLoop() {
bool ret = true;
if(mPath != 0) {
mCurrPointIndex -= 1;
if(mCurrPointIndex >= mPath->m_num) {
mCurrPointIndex = mPath->m_num - 1;
ret = false;
}
}
return ret;
}
bool dNpc_PathRun_c::decIdxAuto() {
bool hitEnd = true;
if(mPath != 0) {
if(mPath->mLoops & 1) {
mCurrPointIndex -= 1;
if(mCurrPointIndex >= mPath->m_num) {
mCurrPointIndex = mPath->m_num - 1;
}
}
else {
mCurrPointIndex -= 1;
if(mCurrPointIndex >= mPath->m_num) {
mCurrPointIndex = 0;
hitEnd = false;
}
}
}
return hitEnd;
}
bool dNpc_PathRun_c::nextIdx() {
bool hitEnd;
if(mbGoingForwards) {
hitEnd = incIdx();
if(hitEnd == false) {
decIdx();
}
}
else {
hitEnd = decIdx();
if(hitEnd == false) {
incIdx();
}
}
return hitEnd;
}
bool dNpc_PathRun_c::nextIdxAuto() {
bool hitEnd;
if(mbGoingForwards) {
hitEnd = incIdxAuto();
if(hitEnd == 0) {
decIdx();
}
}
else {
hitEnd = decIdxAuto();
if(hitEnd == 0) {
incIdx();
}
}
return hitEnd;
}
s32 dNpc_PathRun_c::absIdx(u8 startIdx, u8 lastIdx) {
if(mPath == 0) {
return 0;
}
s32 diff_1 = startIdx - lastIdx;
s32 diff_2 = lastIdx - startIdx;
if(diff_1 < 0) {
diff_1 += maxPoint();
}
if(diff_2 < 0) {
diff_2 += maxPoint();
}
if(diff_1 > diff_2) {
return diff_2;
}
return diff_1;
}
u8 dNpc_PathRun_c::maxPoint() {
u8 max = 0xFF;
if(mPath != 0) {
max = mPath->m_num;
}
return max;
}
u8 dNpc_PathRun_c::pointArg(u8 idx) {
u8 arg = 0;
if(mPath != 0 && idx < (u8)mPath->m_num) {
arg = mPath->mpPnt[idx].mArg3;
}
return arg;
}
bool dNpc_PathRun_c::setNearPathIndx(cXyz* param_1, f32 param_2) {
bool set = false;
if(mPath != 0) {
f32 max_dist = 1000000000.0f;
u8 pointIdx = 0;
for(int i = 0; i < maxPoint(); i++) {
cXyz point = getPoint(i);
cXyz diff = (*param_1 - point);
f32 xz_mag = diff.getMagXZ();
f32 y_mag = param_2 * (diff.y * diff.y);
f32 dist = sqrtf(y_mag + xz_mag);
if(max_dist > dist) {
max_dist = dist;
pointIdx = i;
}
}
mCurrPointIndex = pointIdx;
set = true;
}
return set;
}
f32 dNpc_PathRun_c::setNearPathIndxMk(cXyz* param_1) {
f32 max_dist;
if(mPath != 0) {
max_dist = 1000000000.0f;
u8 pointIdx = 0;
for(int i = 0; i < maxPoint(); i++) {
cXyz point = getPoint(i);
cXyz diff = (*param_1 - point);
f32 temp = diff.getSquareMag();
f32 dist = sqrtf(temp);
if(max_dist > dist) {
max_dist = dist;
pointIdx = i;
}
}
mCurrPointIndex = pointIdx;
}
return max_dist;
}
bool dNpc_PathRun_c::setNearPathIndxMk2(cXyz* param_1, u8 param_2, u8 param_3) {
u8 pointIdx;
bool set = false;
if(mPath != 0) {
f32 max_dist = 1000000000.0f;
pointIdx = param_2;
for(int i = 0; i < maxPoint(); i++) {
cXyz point = getPoint(i);
cXyz diff = (*param_1 - point);
f32 temp = diff.getSquareMag();
f32 dist = sqrtf(temp);
s32 idx = absIdx(param_2, i);
if(idx <= param_3 && param_2 != i && max_dist > dist) {
max_dist = dist;
pointIdx = i;
set = true;
}
}
mCurrPointIndex = pointIdx;
}
return set;
}
bool dNpc_PathRun_c::chkInside(cXyz* param_1) {
cXyz point, point2, point3;
setNearPathIndx(param_1, 0.0f);
point2 = getPoint(mCurrPointIndex);
decIdxLoop();
point = getPoint(mCurrPointIndex);
incIdxLoop();
incIdxLoop();
point3 = getPoint(mCurrPointIndex);
s16 angle1 = cLib_targetAngleY(&point2, &point);
s16 angle2 = cLib_targetAngleY(&point2, param_1);
s16 angle3 = cLib_targetAngleY(&point2, &point3);
s16 diff1 = angle2 - angle3;
s16 diff2 = angle1 - angle3;
if(diff1 > 0) {
if(diff2 < 0 || diff1 < diff2) {
return true;
}
}
else if(diff2 < 0 && diff1 < diff2) {
return true;
}
return false;
}
#include "d/d_npc_event_cut.inc"
void dNpc_EventCut_c::setActorInfo(char* staffName, fopAc_ac_c* pActor) {
mpEvtStaffName = staffName;
mpActor = pActor;
mTargetActorPos.set(0.0f, 0.0f, 0.0f);
mOffsetPos.set(0.0f, 0.0f, 0.0f);
mPos.set(0.0f, 0.0f, 0.0f);
mCurActIdx = -1;
}
void dNpc_EventCut_c::setActorInfo2(char* staffName, fopNpc_npc_c* pActor) {
mpEvtStaffName = staffName;
mpActor = pActor;
mpTalkActor = pActor;
mTargetActorPos.set(0.0f, 0.0f, 0.0f);
mOffsetPos.set(0.0f, 0.0f, 0.0f);
mPos.set(0.0f, 0.0f, 0.0f);
mCurActIdx = -1;
}
bool dNpc_setAnmIDRes(mDoExt_McaMorf* pMorf, int loopMode, float morf, float speed, int animResId, int soundResId, const char* arcName) {
void* pSoundAnimRes = 0;
bool ret = false;
if(pMorf != 0) {
if(0 <= soundResId) {
pSoundAnimRes = dComIfG_getObjectIDRes(arcName, soundResId);
}
void* pAnimRes = dComIfG_getObjectIDRes(arcName, animResId);
pMorf->setAnm((J3DAnmTransform*)pAnimRes, loopMode, morf, speed, 0.0f, -1.0f, pSoundAnimRes);
ret = true;
}
return ret;
}
bool dNpc_setAnmFNDirect(mDoExt_McaMorf* pMorf, int loopMode, f32 morf, f32 speed, char* animFilename, char* soundFilename, const char* arcName) {
bool ret = false;
if(pMorf != 0 && animFilename != 0 && arcName != 0) {
void* pAnimRes = dComIfG_getObjectRes(arcName, animFilename);
void* pSoundAnimRes = 0;
if(soundFilename != 0) {
pSoundAnimRes = dComIfG_getObjectRes(arcName, soundFilename);
}
pMorf->setAnm((J3DAnmTransform*)pAnimRes, loopMode, morf, speed, 0.0f, -1.0f, pSoundAnimRes);
ret = true;
}
return ret;
}
bool dNpc_setAnm(mDoExt_McaMorf* pMorf, int loopMode, f32 morf, f32 speed, int animFileIdx, int soundFileIdx, const char* arcName) {
void* pSoundAnimRes = 0;
bool ret = false;
if(pMorf != 0) {
if(0 <= soundFileIdx) {
pSoundAnimRes = dComIfG_getObjectRes(arcName, soundFileIdx);
}
void* pAnimRes = dComIfG_getObjectRes(arcName, animFileIdx);
pMorf->setAnm((J3DAnmTransform*)pAnimRes, loopMode, morf, speed, 0.0f, -1.0f, pSoundAnimRes);
ret = true;
}
return ret;
}
void dNpc_setShadowModel(J3DModel* param_1, J3DModelData* param_2, J3DModel* param_3) {
for(int i = 0; i < param_2->getWEvlpMtxNum(); i++) {
mDoMtx_copy(param_3->mpWeightEnvMtx[i], param_1->mpWeightEnvMtx[i]);
}
for(int i = 0; i < param_2->getJointNum(); i++) {
mDoMtx_copy(param_3->mpNodeMtx[i], param_1->mpNodeMtx[i]);
}
}
cXyz dNpc_playerEyePos(f32 param_1) {
daPy_py_c* pPlayer = daPy_getPlayerActorClass();
cXyz pos = pPlayer->getHeadTopPos();
cXyz out;
MtxTrans(pos.x, pos.y, pos.z, false);
pos.set(0.0f, param_1, 0.0f);
MtxPosition(&pos, &out);
out.x = pPlayer->current.pos.x;
out.z = pPlayer->current.pos.z;
return out;
}
void dNpc_calc_DisXZ_AngY(cXyz param_1, cXyz param_2, float* param_3, short* param_4) {
cXyz diff;
diff.x = param_2.x - param_1.x;
diff.z = param_2.z - param_1.z;
if(param_3 != 0) {
f32 dist = sqrtf(diff.x * diff.x + diff.z * diff.z);
*param_3 = dist;
}
if(param_4 != 0) {
*param_4 = cM_atan2s(diff.x, diff.z);
}
}
bool dNpc_chkArasoi() {
return dComIfGs_isEventBit(0x1220) && !dComIfGs_isEventBit(0x1808);
}
BOOL dNpc_chkLetterPassed() {
BOOL ret = false;
if(dComIfGs_isGetItemReserve(0xC)) {
ret = dComIfGs_checkReserveItem(0x98) ? 0 : 1;
}
return ret;
}
void fopNpc_npc_c::setCollision(f32 radius, f32 height) {
mCyl.SetC(current.pos);
mCyl.SetR(radius);
mCyl.SetH(height);
dComIfG_Ccsp()->Set(&mCyl);
}
u16 fopNpc_npc_c::talk(int param_1) {
u16 mode = 0xFF;
if(mCurrMsgBsPcId == 0xFFFFFFFF) {
if(param_1 == 1) {
mCurrMsgID = getMsg();
}
mCurrMsgBsPcId = fopMsgM_messageSet(mCurrMsgID, this);
mpCurrMsg = 0;
}
else {
if(mpCurrMsg) {
mode = mpCurrMsg->mMode;
if(mode == dNpcMsgStts_MSG_DISPLAYED_e) {
mpCurrMsg->mMode = next_msgStatus(&mCurrMsgID);
if(mpCurrMsg->mMode == dNpcMsgStts_MSG_CONTINUES_e) {
fopMsgM_messageSet(mCurrMsgID);
}
}
else if (mode == dNpcMsgStts_BOX_CLOSED_e) {
mpCurrMsg->mMode = dNpcMsgStts_MSG_DESTROYED_e;
mCurrMsgBsPcId = -1;
}
anmAtr(mode);
}
else {
mpCurrMsg = fopMsgM_SearchByID(mCurrMsgBsPcId);
}
}
return mode;
}
bool dNpc_setAnm_2(mDoExt_McaMorf* pMorf, int loopMode, f32 morf, f32 speed, int animFileIdx, int soundFileIdx, const char* arcName) {
if(0 <= soundFileIdx) {
void* pSoundAnimRes = dComIfG_getObjectRes(arcName, soundFileIdx);
void* pAnimRes = dComIfG_getObjectRes(arcName, animFileIdx);
pMorf->setAnm((J3DAnmTransform*)pAnimRes, loopMode, morf, speed, 0.0f, -1.0f, pSoundAnimRes);
}
else {
void* pAnimRes = dComIfG_getObjectRes(arcName, animFileIdx);
pMorf->setAnm((J3DAnmTransform*)pAnimRes, loopMode, morf, speed, 0.0f, -1.0f, 0);
}
return true;
}
void dNpc_HeadAnm_c::swing_vertical_init(s16 param_1, s16 param_2, s16 param_3, int param_4) {
if(param_4 == 0 || mFunc != &swing_horizone) {
field_0x1C = 0;
field_0x20 = param_1;
field_0x1E = param_2;
field_0x14 = param_3;
mFunc = &swing_vertical;
}
}
/* 8021C2E8-8021C3C8 .text swing_vertical__14dNpc_HeadAnm_cFv */
void dNpc_HeadAnm_c::swing_vertical() {
/* Nonmatching */
}
void dNpc_HeadAnm_c::swing_horizone_init(s16 param_1, s16 param_2, s16 param_3, int param_4) {
if(param_4 == 0 || mFunc != &swing_vertical) {
field_0x1C = 0;
field_0x20 = param_1;
field_0x1E = param_2;
field_0x18 = param_3;
mFunc = &swing_horizone;
}
}
/* 8021C478-8021C55C .text swing_horizone__14dNpc_HeadAnm_cFv */
void dNpc_HeadAnm_c::swing_horizone() {
/* Nonmatching */
}
void dNpc_HeadAnm_c::move() {
if(mFunc) {
(this->*mFunc)();
}
else {
cLib_addCalcAngleS(&field_0x00, 0, 4, 0x1000, 0x100);
cLib_addCalcAngleS(&field_0x02, 0, 4, 0x1000, 0x100);
}
}
/* 8021C5D8-8021C620 .text chkLim__14dNpc_JntCtrl_cFsii */
s32 dNpc_JntCtrl_c::chkLim(s16 param_1, int param_2, int param_3) {
param_1 = cLib_maxLimit(param_1, mMaxAngles[param_2][param_3]);
param_1 = cLib_minLimit(param_1, mMinAngles[param_2][param_3]);
return param_1;
}
void dNpc_JntCtrl_c::turn_fromBackbone2Head(s16 param_1, s16* param_2, s16* param_3, bool param_4) {
*param_3 = 0;
if(field_0x0C == 0) {
*param_3 = chkLim(param_1, 1, 1);
if(field_0x32 && *param_3 < 0) {
*param_3 = 0;
}
}
*param_2 = 0;
if(field_0x0B == 0) {
*param_2 = param_1 - *param_3;
*param_2 = chkLim(*param_2, 0, 1);
}
}
void dNpc_JntCtrl_c::turn_fromHead2Backbone(s16 param_1, s16* param_2, s16* param_3) {
*param_2 = 0;
if(field_0x0B == 0) {
*param_2 = param_1 - field_0x32;
*param_2 = chkLim(*param_2, 0, 1);
}
*param_3 = 0;
if(field_0x0C == 0) {
*param_3 = param_1 - *param_2;
*param_3 = chkLim(*param_3, 1, 1);
}
}
s16 dNpc_JntCtrl_c::follow_current(s16* orig, s16 diff) {
s16 angle = *orig;
*orig -= diff;
s16 ret = 0;
if((angle > 0 && *orig < 0) || (angle < 0 && *orig > 0)) {
ret = -*orig;
*orig = 0;
}
return ret;
}
/* 8021C7D0-8021CAB8 .text lookAtTarget_2__14dNpc_JntCtrl_cFPsP4cXyz4cXyzssb */
void dNpc_JntCtrl_c::lookAtTarget_2(short*, cXyz*, cXyz, short, short, bool) {
/* Nonmatching */
}
bool dNpc_chkAttn(fopAc_ac_c* i_this, cXyz destPos, float param_3, float param_4, float param_5, bool param_6) {
s16 angle = cLib_targetAngleY(&i_this->current.pos, &destPos);
f32 dist = sqrtf((i_this->current.pos - destPos).getMagXZ()); //this is gross but I haven't found a better way (temp destroys stack)
s16 angle_diff = angle - i_this->current.angle.y;
if(param_5 > 359.0f) {
param_5 = 359.0f;
}
if (param_5 < 0.0f) {
param_5 = 0.0f;
}
if(param_6) {
param_3 += param_4;
}
bool ret = false;
if(dist <= param_3 && abs(angle_diff) <= cM_deg2s(param_5)) {
ret = true;
}
return ret;
}
dCcD_SrcCyl dNpc_cyl_src = {
// dCcD_SrcGObjInf
{
/* Flags */ 0,
/* SrcObjAt Type */ 0,
/* SrcObjAt Atp */ 0,
/* SrcObjAt SPrm */ 0,
/* SrcObjTg Type */ ~(AT_TYPE_BOOMERANG),
/* SrcObjTg SPrm */ 0x03,
/* SrcObjCo SPrm */ 0x75,
/* SrcGObjAt Se */ 0,
/* SrcGObjAt HitMark */ 0,
/* SrcGObjAt Spl */ 0,
/* SrcGObjAt Mtrl */ 0,
/* SrcGObjAt GFlag */ 0,
/* SrcGObjTg Se */ 0,
/* SrcGObjTg HitMark */ 0,
/* SrcGObjTg Spl */ 0,
/* SrcGObjTg Mtrl */ 0,
/* SrcGObjTg GFlag */ 0x04,
/* SrcGObjCo GFlag */ 0,
},
// cM3dGCylS
{
/* Center */ 0.0f, 0.0f, 0.0f,
/* Radius */ 0.0f,
/* Height */ 0.0f,
},
};