diff --git a/include/SSystem/SComponent/c_lib.h b/include/SSystem/SComponent/c_lib.h index d2680e86e..c34deb48b 100644 --- a/include/SSystem/SComponent/c_lib.h +++ b/include/SSystem/SComponent/c_lib.h @@ -73,17 +73,12 @@ inline T cLib_minMaxLimit(T val, T min, T max) { template inline T cLib_maxLimit(T val, T max) { - T ret; - T var_r30; + return (T)((T)val > (T)max ? (T)max : (T)val); +} - if (val > max) { - var_r30 = max; - } else { - var_r30 = val; - } - - ret = var_r30; - return (T)ret; +template +inline T cLib_minLimit(T val, T min) { + return (T)((T)val < (T)min ? (T)min : (T)val); } template diff --git a/include/d/d_npc.h b/include/d/d_npc.h index 6fa9b11ac..5137030c5 100644 --- a/include/d/d_npc.h +++ b/include/d/d_npc.h @@ -34,24 +34,27 @@ public: }; class dNpc_JntCtrl_c { - /* 0x00 */ s16 mHeadUpDownRot; - /* 0x02 */ s16 mHeadLeftRightRot; - /* 0x04 */ s16 mBackboneUpDownRot; - /* 0x06 */ s16 mBackboneLeftRightRot; + /* 0x0E */ s16 mAngles[2][2]; + // /* 0x00 */ s16 mHeadUpDownRot; + // /* 0x02 */ s16 mHeadLeftRightRot; + // /* 0x04 */ s16 mBackboneUpDownRot; + // /* 0x06 */ s16 mBackboneLeftRightRot; /* 0x08 */ u8 mHeadJntNum; /* 0x09 */ u8 mBackboneJntNum; /* 0x0A */ bool field_0x0A; /* 0x0B */ u8 field_0x0B; /* 0x0C */ u8 field_0x0C; /* 0x0D */ u8 field_0x0D; - /* 0x0E */ s16 field_0x0E; - /* 0x10 */ s16 mMinHeadRot; - /* 0x12 */ s16 field_0x12; - /* 0x14 */ s16 mMinSpineRot; - /* 0x16 */ s16 field_0x16; - /* 0x18 */ s16 mMaxHeadRot; - /* 0x1A */ s16 field_0x1A; - /* 0x1C */ s16 mMaxSpineRot; + // /* 0x0E */ s16 field_0x0E; + // /* 0x10 */ s16 mMinHeadRot; + // /* 0x12 */ s16 field_0x12; + // /* 0x14 */ s16 mMinSpineRot; + // /* 0x16 */ s16 field_0x16; + // /* 0x18 */ s16 mMaxHeadRot; + // /* 0x1A */ s16 field_0x1A; + // /* 0x1C */ s16 mMaxSpineRot; + /* 0x0E */ s16 mMinAngles[2][2]; + /* 0x16 */ s16 mMaxAngles[2][2]; /* 0x1E */ s16 field_0x1E; /* 0x20 */ s16 field_0x20; /* 0x22 */ s16 field_0x22; @@ -139,7 +142,7 @@ public: bool setInf(u8 pathIdx, s8 roomNo, u8 forwards); dPath* nextPath(s8 roomNo); cXyz getPoint(u8 pointIdx); - void chkPointPass(cXyz, bool); + bool chkPointPass(cXyz, bool); bool incIdx(); bool incIdxLoop(); bool incIdxAuto(); diff --git a/src/d/d_npc.cpp b/src/d/d_npc.cpp index f861e186b..fe2d19e2b 100644 --- a/src/d/d_npc.cpp +++ b/src/d/d_npc.cpp @@ -16,14 +16,12 @@ static Vec dummy_2100 = {1.0f, 1.0f, 1.0f}; static Vec dummy_2080 = {1.0f, 1.0f, 1.0f}; -#include "d/d_npc_event_cut.inc" - bool dNpc_JntCtrl_c::angCalcS(s16* out, s16 targetY, s16 speed, s16 maxVel) { - s16 origY = *out; - s16 diff = origY - targetY; + s16 diff = *out - targetY; + int origDiff = diff; cLib_addCalcAngleS(&diff, 0, speed, maxVel, 0x60); if(abs(diff) > speed) { - *out += (diff - (origY - targetY)); + *out += diff - origDiff; } else { *out = targetY; @@ -41,10 +39,25 @@ void dNpc_JntCtrl_c::limitter(s16* targetDiff, s16 maxDiff, s16 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); - - return *outY != targetY; + 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 */ @@ -58,14 +71,14 @@ void dNpc_JntCtrl_c::lookAtTarget(short*, cXyz*, cXyz, short, short, bool) { } 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) { - field_0x1A = param_1; - mMaxSpineRot = maxSpineRot; - field_0x12 = param_3; - mMinSpineRot = minSpineRot; - field_0x16 = param_5; - mMaxHeadRot = maxHeadRot; - field_0x0E = param_7; - mMinHeadRot = minHeadRot; + 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; @@ -115,8 +128,36 @@ cXyz dNpc_PathRun_c::getPoint(u8 pointIdx) { } /* 8021ADD0-8021AFA8 .text chkPointPass__14dNpc_PathRun_cF4cXyzb */ -void dNpc_PathRun_c::chkPointPass(cXyz, bool) { - /* Nonmatching */ +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() { @@ -398,6 +439,8 @@ bool dNpc_PathRun_c::chkInside(cXyz* param_1) { return false; } +#include "d/d_npc_event_cut.inc" + void dNpc_EventCut_c::setActorInfo(char* staffName, fopAc_ac_c* pActor) { mpEvtStaffName = staffName; mpActor = pActor; @@ -623,15 +666,12 @@ void dNpc_HeadAnm_c::move() { } } +/* 8021C5D8-8021C620 .text chkLim__14dNpc_JntCtrl_cFsii */ s32 dNpc_JntCtrl_c::chkLim(s16 param_1, int param_2, int param_3) { - //if(maxRotations[param_2][param_3] > param_1) { - // param_1 = maxRotations[param_2][param_3]; - //} - //if(param_1 < minRotations[param_2][param_3]) { - // param_1 = minRotations[param_2][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; + return param_1; } void dNpc_JntCtrl_c::turn_fromBackbone2Head(s16 param_1, s16* param_2, s16* param_3, bool param_4) { diff --git a/src/d/d_npc_event_cut.inc b/src/d/d_npc_event_cut.inc index eb6f8914a..ebe032a33 100644 --- a/src/d/d_npc_event_cut.inc +++ b/src/d/d_npc_event_cut.inc @@ -203,9 +203,8 @@ void dNpc_EventCut_c::cutTurnToActorProc() { mPos = dNpc_playerEyePos(0.0f) + mOffsetPos; } else { - s16 addAngle = mAddAngle; - if(addAngle && pDelDistance) { - u16 angle = mpTargetActor->shape_angle.y + addAngle; + if(mAddAngle && pDelDistance) { + u16 angle = mpTargetActor->shape_angle.y + mAddAngle; mPos = mpTargetActor->current.pos; mPos.x -= pDelDistance * cM_ssin(angle); mPos.z -= pDelDistance * cM_scos(angle); @@ -218,8 +217,9 @@ void dNpc_EventCut_c::cutTurnToActorProc() { mbAttention = 1; s16 tAngle = cLib_targetAngleY(&mpActor->current.pos, &mPos); - u32 temp = abs(tAngle - fopAcM_GetAngle_p(mpActor).y); - if(fabsf2(field_0x44) == temp && temp < 5376.0f) { + int temp2 = tAngle - mpActor->current.angle.y; + f32 temp = fabsf(temp2); + if(field_0x44 == temp && fabsf(temp2) < 5376.0f) { cLib_calcTimer(&mTimer); } @@ -228,7 +228,7 @@ void dNpc_EventCut_c::cutTurnToActorProc() { dComIfGp_evmng_cutEnd(mEvtStaffId); } - field_0x44 = fabsf2(tAngle - mpActor->current.angle.y); + field_0x44 = fabsf(tAngle - mpActor->current.angle.y); } void dNpc_EventCut_c::cutMoveToActorStart() { @@ -454,9 +454,9 @@ void dNpc_EventCut_c::cutTurnToPosProc() { } } - //not sure what this section is doing - u32 temp = abs(tAngle - fopAcM_GetAngle_p(mpActor).y); - if(fabsf2(field_0x44) == temp && temp < 5376.0f) { + int temp2 = tAngle - mpActor->current.angle.y; + f32 temp = fabsf(temp2); + if(field_0x44 == temp && fabsf(temp2) < 5376.0f) { cLib_calcTimer(&mTimer); } @@ -465,7 +465,7 @@ void dNpc_EventCut_c::cutTurnToPosProc() { dComIfGp_evmng_cutEnd(mEvtStaffId); } - field_0x44 = fabsf2(tAngle - mpActor->current.angle.y); + field_0x44 = fabsf(tAngle - mpActor->current.angle.y); } void dNpc_EventCut_c::cutMoveToPosStart() {