/** * d_a_alink_crawl.inc * Player Crawl action handling */ #include "d/actor/d_a_alink.h" f32 daAlink_c::getCrawlMoveAnmSpeed() { return getAnmSpeedStickRate(mpHIO->mCrouch.m.mCrawlAnmSpeedMin, mpHIO->mCrouch.m.mCrawlAnmSpeedMax); } f32 daAlink_c::getCrawlMoveSpeed() { daPy_frameCtrl_c* frame_ctrl = mUnderFrameCtrl; f32 frame; if (frame_ctrl->getFrame() >= 17.0f) { frame = frame_ctrl->getFrame() - 17.0f; } else { frame = frame_ctrl->getFrame(); } return (mpHIO->mCrouch.m.mCrawlMoveRate * frame_ctrl->getRate()) * cM_fsin(frame * 0.18479956686496735f); } void daAlink_c::setCrawlMoveDirectionArrow() { static const u8 data_80452F38 = 1; static const u8 data_80452F39 = 4; u8 direction = 0; BOOL bvar; if (cLib_distanceAngleS(fopCamM_GetAngleY(dComIfGp_getCamera(field_0x317c)), shape_angle.y) > 0x4000) { bvar = TRUE; } else { bvar = FALSE; } if (field_0x3198 & 4) { if (!bvar) { direction |= data_80452F38; } else { direction |= data_80452F39; } } if (field_0x3198 & 8) { if (!bvar) { direction |= data_80452F39; } else { direction |= data_80452F38; } } if (field_0x3198 & 1) { if (shape_angle.y == current.angle.y) { if (!bvar) { direction |= 8; } else { direction |= 2; } } else if (!bvar) { direction |= 2; } else { direction |= 8; } } if (shape_angle.y == current.angle.y) { if (!bvar) { direction |= 2; } else { direction |= 8; } } else if (!bvar) { direction |= 8; } else { direction |= 2; } dComIfGp_setAdvanceDirection(direction); } BOOL daAlink_c::changeCrawlAutoMoveProc(cXyz* param_0) { cXyz sp70; cXyz sp64; cXyz sp58; cXyz sp4C; cXyz sp40; cXyz sp34; cXyz sp28; f32 spC; s16 spA; s16 sp8; f32 temp_f31 = cM_ssin(current.angle.y); f32 temp_f30 = cM_scos(current.angle.y); f32 temp_f29 = cM_ssin(shape_angle.y); f32 temp_f28 = cM_scos(shape_angle.y); int var_r29 = 0; sp70.x = param_0->x + (95.0f * temp_f31); sp70.y = param_0->y; sp70.z = param_0->z + (95.0f * temp_f30); if (!commonLineCheck(param_0, &sp70) || (!checkWolf() && dComIfG_Bgsp().GetWallCode(mLinkLinChk) == 6)) { sp4C.x = sp70.x + (55.0f * temp_f30); sp4C.y = sp70.y; sp4C.z = sp70.z - (55.0f * temp_f31); if (checkCrawlSideWall(&sp70, &sp4C, &sp34, &sp28, &spA, &sp8)) { var_r29 |= 1; } else { return 0; } } sp4C.x = param_0->x + (55.0f * temp_f28); sp4C.y = param_0->y; sp4C.z = param_0->z - (55.0f * temp_f29); sp40 = (*param_0 * 2.0f) - sp4C; if (commonLineCheck(param_0, &sp4C)) { var_r29 |= 8; sp58.x = sp40.x + (95.0f * temp_f29); sp58.y = sp40.y; sp58.z = sp40.z + (95.0f * temp_f28); if (!checkCrawlSideWall(&sp40, &sp58, &sp34, &sp28, &spA, &sp8)) { return 0; } } else { var_r29 |= 4; sp58.x = sp4C.x - (95.0f * temp_f29); sp58.y = sp4C.y; sp58.z = sp4C.z - (95.0f * temp_f28); if (!checkCrawlSideWall(&sp4C, &sp58, &sp34, &sp28, &spA, &sp8)) { return 0; } if (!commonLineCheck(param_0, &sp40)) { var_r29 |= 8; } } f32 var_f27 = param_0->x - (95.0f * temp_f31); f32 var_f26 = param_0->z - (95.0f * temp_f30); if (cM3d_Len2dSqPntAndSegLine(0.5f * (sp34.x + sp28.x), 0.5f * (sp34.z + sp28.z), sp70.x, sp70.z, var_f27, var_f26, &sp64.x, &sp64.z, &spC)) { sp64.y = current.pos.y; if (checkWolf()) { return procWolfLieAutoMoveInit(var_r29, &sp64); } else { return procCrawlAutoMoveInit(var_r29, &sp64); } } return 0; } int daAlink_c::getCrawlMoveVec(cXyz* param_0, cXyz* param_1, cXyz* param_2, int param_3, int param_4, u8* param_5) { if (commonLineCheck(param_0, param_1) && ((param_4 == 0 && (!checkWolf() || !dComIfGp_checkPlayerStatus0(0, 0x08000000))) || dComIfG_Bgsp().GetWallCode(mLinkLinChk) != 6) && (!checkWolf() || dComIfG_Bgsp().GetWallCode(mLinkLinChk) != 7)) { cM3dGPla tripla; dComIfG_Bgsp().GetTriPla(mLinkLinChk, &tripla); int temp_r27 = dComIfG_Bgsp().GetSpecialCode(mLinkLinChk); if (cBgW_CheckBWall(tripla.mNormal.y) || (param_3 == 2 && cBgW_CheckBGround(tripla.mNormal.y))) { cXyz sp1C = *param_1 - mLinkLinChk.GetCross(); s16 temp_r26 = tripla.mNormal.atan2sX_Z(); s16 temp_r3 = sp1C.atan2sX_Z(); if (abs((s16)((temp_r3 + 0x8000) - temp_r26)) > 0x3000) { return 0; } f32 temp_f31 = -sp1C.absXZ() * cM_scos(((temp_r3 - temp_r26) - 0x8000)); param_2->x = temp_f31 * tripla.mNormal.x; if (param_3 != 1) { param_2->y = 0.0f; } else { param_2->y = sp1C.y; } param_2->z = temp_f31 * tripla.mNormal.z; if (param_5 != NULL && (dKy_pol_argument_get(&mLinkLinChk) & 0x60)) { *param_5 = 3; cM3dGPla tripla; dComIfG_Bgsp().GetTriPla(mLinkLinChk, &tripla); field_0x311e = tripla.mNormal.atan2sX_Z(); if (checkIcePolygonDamage(&mLinkLinChk)) { *param_5 |= (u8)0x80; } if (dKy_pol_argument_get(&mLinkLinChk) & 0x20) { *param_5 |= (u8)0x40; } } return 1; } if (param_3 == 1 && (temp_r27 == 1 || (tripla.mNormal.y < field_0x3470 && temp_r27 == 2))) { *param_2 = *param_1 - mLinkLinChk.GetCross(); return 1; } } return 0; } void daAlink_c::crawlBgCheck(cXyz* param_0, cXyz* param_1, int param_2) { cXyz sp28; cXyz sp34; cXyz sp40; cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlTopOffset, &sp28); int temp_r30 = getCrawlMoveVec(&sp28, param_0, &sp34, 1, param_2, NULL); cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlTopUpOffset, &sp28); int temp_r29 = getCrawlMoveVec(&sp28, param_1, &sp40, 1, param_2, NULL); if (temp_r30 != 0 && temp_r29 != 0) { if (sp34.abs2() > sp40.abs2()) { current.pos -= sp34; } else { current.pos -= sp40; } } else if (temp_r30 != 0) { current.pos -= sp34; } else if (temp_r29 != 0) { current.pos -= sp40; } } BOOL daAlink_c::checkCrawlSideWall(cXyz* param_0, cXyz* param_1, cXyz* param_2, cXyz* param_3, s16* param_4, s16* param_5) { cXyz sp58; cXyz sp4C; if (commonLineCheck(param_0, param_1)) { cM3dGPla tripla; *param_2 = mLinkLinChk.GetCross(); dComIfG_Bgsp().GetTriPla(mLinkLinChk, &tripla); *param_4 = tripla.mNormal.atan2sX_Z(); sp4C = *param_2 + (tripla.mNormal * 95.0f); sp58 = (sp4C + *param_2) * 0.5f; if (commonLineCheck(&sp58, &sp4C)) { *param_3 = mLinkLinChk.GetCross(); dComIfG_Bgsp().GetTriPla(mLinkLinChk, &tripla); *param_5 = tripla.mNormal.atan2sX_Z(); cXyz sp40 = *param_2 - *param_3; f32 temp_f31 = sp40.abs2XZ(); if (cLib_distanceAngleS(*param_4, *param_5) > 0x7F00 && temp_f31 < 9025.0f && temp_f31 > 4900.0f) { return 1; } } } return 0; } void daAlink_c::decideCrawlDoStatus() { if (dComIfGp_checkCameraAttentionStatus(field_0x317c, 0x80)) { if (checkSubjectEnd(TRUE) || mWaterY > current.pos.y) { dComIfGp_clearPlayerStatus0(0, 0x2000); } } else if (dCam_getBody()->ChangeModeOK(4) && mWaterY <= current.pos.y) { onResetFlg0(RFLG0_UNK_4000000); if (dComIfGp_checkCameraAttentionStatus(field_0x317c, 0x1000) && !checkEventRun()) { setSubjectMode(); } } } BOOL daAlink_c::checkNotCrawlStand(cXyz* param_0) { mLinkRoofChk.SetPos(*param_0); if (dComIfG_Bgsp().RoofChk(&mLinkRoofChk) - current.pos.y <= mHeight) { return TRUE; } return FALSE; } BOOL daAlink_c::checkNotCrawlStand(cXyz* param_0, cXyz* param_1) { cXyz sp20; sp20 = *param_0 + *param_1; if (checkNotCrawlStand(&sp20)) { return true; } sp20 = *param_0 - *param_1; if (checkNotCrawlStand(&sp20)) { return true; } return false; } BOOL daAlink_c::checkCrawlInHoll(cXyz* param_0, cXyz* param_1, cXyz* param_2, int param_3) { UNUSED(param_3); cXyz spC0; cXyz spB4; cXyz spA8; cXyz sp9C; cXyz sp90; cXyz sp84; s16 sp16; s16 sp14; cMtx_multVec(mpLinkModel->getBaseTRMtx(), field_0x2f50, &spC0); cMtx_multVec(mpLinkModel->getBaseTRMtx(), field_0x2f54, param_2); if (mUnderFrameCtrl[0].getRate() >= 0.0f) { sp90 = (*param_0 - *param_2) * 0.5f; } else if (mUnderFrameCtrl[0].getRate() < 0.0f) { sp90 = (*param_1 - *param_2) * 0.5f; } spC0 += sp90; *param_2 += sp90; spB4 = (*param_2 * 2.0f) - spC0; if (checkCrawlSideWall(param_2, &spC0, &spA8, &sp9C, &sp16, &sp14) || checkCrawlSideWall(param_2, &spB4, &sp9C, &spA8, &sp14, &sp16)) { field_0x3198 = 1; field_0x37c8 = ((spA8 + sp9C) * 0.5f) - sp90; mProcVar2.field_0x300c = sp16 + 0x4000; return 1; } return 0; } void daAlink_c::setCrawlMoveHoll() { if (mUnderFrameCtrl[0].getRate()) { cLib_addCalcAngleS(&shape_angle.y, mProcVar2.field_0x300c, 5, 0x1000, 0x800); current.angle.y = shape_angle.y; } if (fabsf(current.pos.x - field_0x37c8.x) > 1.0f) { cLib_addCalc(¤t.pos.x, field_0x37c8.x, 0.5f, 10.0f, 1.0f); } if (fabsf(current.pos.z - field_0x37c8.z) > 1.0f) { cLib_addCalc(¤t.pos.z, field_0x37c8.z, 0.5f, 10.0f, 1.0f); } } void daAlink_c::setCrawlMoveAngle() { cXyz sp20; cXyz sp2C; cXyz sp38; cLib_addCalcAngleS(&shape_angle.y, mMoveAngle, mpHIO->mCrouch.m.mCrawlTurnRate, mpHIO->mCrouch.m.mCrawlTurnMax, mpHIO->mCrouch.m.mCrawlTurnMin); if (shape_angle.y != current.angle.y) { if ((s16)(shape_angle.y - current.angle.y) > 0) { cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlLSideFrontOffset, &sp20); cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlLSideOffset, &sp38); } else { cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlRSideFrontOffset, &sp20); cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlRSideOffset, &sp38); } mLinkGndChk.SetPos(&sp20); #if PLATFORM_SHIELD sp2C.set(sp20.x - sp38.x, dComIfG_Bgsp().GroundCross(&mLinkGndChk) - sp38.y, sp20.z - sp38.z); #else // Fakematch: // dBgS::GroundCross is implicitly inlined to cBgS::GroundCross, but for some // reason here that breaks instruction ordering. See also daHorse_c::checkHorseNoMove. sp2C.set(sp20.x - sp38.x, ((cBgS&)dComIfG_Bgsp()).GroundCross(&mLinkGndChk) - sp38.y, sp20.z - sp38.z); #endif if (cLib_distanceAngleS(sp2C.atan2sY_XZ(), shape_angle.x) > 0x800) { shape_angle.y = current.angle.y; } else { current.angle.y = shape_angle.y; } } } void daAlink_c::stopHalfMoveAnime(f32 i_frame) { daPy_frameCtrl_c* frame_ctrl = mUnderFrameCtrl; f32 frame; if (frame_ctrl->checkPass(0.0f)) { frame = 0.0f; } else { frame = i_frame; } frame_ctrl->setRate(0.0f); frame_ctrl->setFrame(frame); getNowAnmPackUnder(UNDER_0)->setFrame(frame); } void daAlink_c::setCrawlAutoMoveAimPos() { int direction = getDirectionFromShapeAngle(); f32 temp_f31 = cM_ssin(shape_angle.y); f32 temp_f30 = cM_scos(shape_angle.y); if (direction == DIR_LEFT && (field_0x3198 & 4)) { field_0x37c8.x += 1.5f * (95.0f * temp_f30); field_0x37c8.z -= 1.5f * (95.0f * temp_f31); mProcVar2.field_0x300c = current.angle.y + 0x4000; if (current.angle.y == shape_angle.y) { mProcVar3.field_0x300e = 1; } else { mProcVar3.field_0x300e = -1; } mProcVar0.field_0x3008 = -1; } else if (direction == DIR_RIGHT && (field_0x3198 & 8)) { field_0x37c8.x -= 1.5f * (95.0f * temp_f30); field_0x37c8.z += 1.5f * (95.0f * temp_f31); mProcVar2.field_0x300c = current.angle.y - 0x4000; if (current.angle.y == shape_angle.y) { mProcVar3.field_0x300e = 1; } else { mProcVar3.field_0x300e = -1; } mProcVar0.field_0x3008 = -1; } else if ((field_0x3198 & 1) && ((shape_angle.y == current.angle.y && direction == DIR_FORWARD) || (shape_angle.y != current.angle.y && direction == DIR_BACKWARD))) { field_0x37c8.x += 1.5f * (95.0f * cM_ssin(current.angle.y)); field_0x37c8.z += 1.5f * (95.0f * cM_scos(current.angle.y)); mProcVar2.field_0x300c = shape_angle.y; mProcVar3.field_0x300e = 0; mProcVar0.field_0x3008 = -1; } else if ((shape_angle.y == current.angle.y && direction == DIR_BACKWARD) || (shape_angle.y != current.angle.y && direction == DIR_FORWARD)) { ANGLE_ADD_2(current.angle.y, 0x8000); field_0x37c8.x -= 1.5f * (95.0f * cM_ssin(current.angle.y)); field_0x37c8.z -= 1.5f * (95.0f * cM_scos(current.angle.y)); mProcVar2.field_0x300c = shape_angle.y; mProcVar3.field_0x300e = 0; mProcVar0.field_0x3008 = -1; } } int daAlink_c::procCrawlStartInit() { if (mEquipItem != dItemNo_NONE_e) { return procPreActionUnequipInit(PROC_CRAWL_START, NULL); } commonProcInit(PROC_CRAWL_START); field_0x3588 = l_waitBaseAnime; setSingleAnimeParam(ANM_CRAWL_START, &mpHIO->mCrouch.m.mCrawlStartAnm); mNormalSpeed = 0.0f; shape_angle.y = field_0x306e + 0x8000; current.angle.y = shape_angle.y; current.pos.x = field_0x34ec.x + (35.0f * cM_ssin(field_0x306e)); current.pos.z = field_0x34ec.z + (35.0f * cM_scos(field_0x306e)); if (mpHIO->mCrouch.m.mCrawlStartAnm.mCancelFrame > mpHIO->mCrouch.m.mCrawlStartAnm.mEndFrame) { field_0x347c = mpHIO->mCrouch.m.mCrawlStartAnm.mEndFrame; } else { field_0x347c = mpHIO->mCrouch.m.mCrawlStartAnm.mCancelFrame; } field_0x3478 = 1.0f / (field_0x347c - mpHIO->mCrouch.m.mCrawlStartAnm.mStartFrame); field_0x33cc = 0.0f; dComIfGp_setPlayerStatus0(0, 0x08000000); return 1; } int daAlink_c::procCrawlStart() { daPy_frameCtrl_c* frame_ctrl = mUnderFrameCtrl; decideCrawlDoStatus(); field_0x33cc = 1.0f - field_0x3478 * (field_0x347c - frame_ctrl->getFrame()); cXyz sp20(l_crawlFrontOffset.x, l_crawlFrontOffset.y, l_crawlFrontOffset.z * field_0x33cc); cXyz sp2C; cXyz sp38; cMtx_multVec(mpLinkModel->getBaseTRMtx(), &sp20, &sp2C); sp20.y = 80.0f; cMtx_multVec(mpLinkModel->getBaseTRMtx(), &sp20, &sp38); crawlBgCheck(&sp2C, &sp38, 0); field_0x2f99 = 4; if (checkAnmEnd(frame_ctrl)) { procCrawlMoveInit(shape_angle.x, shape_angle.z); } return 1; } int daAlink_c::procCrawlMoveInit(s16 i_angleX, s16 i_angleZ) { BOOL var_r29; BOOL var_r28 = FALSE; if (mProcID == PROC_CRAWL_AUTO_MOVE) { var_r29 = FALSE; } else { var_r29 = TRUE; if (mProcID == PROC_CRAWL_START) { var_r28 = TRUE; } } BOOL var_r27; if (dComIfGp_checkPlayerStatus0(0, 0x2000)) { var_r27 = TRUE; } else { var_r27 = FALSE; } commonProcInit(PROC_CRAWL_MOVE); mProcVar3.field_0x300e = 0; if (var_r29) { f32 anm_speed = getCrawlMoveAnmSpeed(); if (var_r28) { mProcVar3.field_0x300e = 1; } else if (getDirectionFromShapeAngle() == DIR_BACKWARD) { anm_speed *= -1.0f; } current.angle.y = shape_angle.y; setSingleAnimeBaseSpeed(ANM_CRAWL, anm_speed, mpHIO->mCrouch.m.mCrawlInterpolation); } field_0x3198 = var_r29 ^ 1; shape_angle.x = i_angleX; shape_angle.z = i_angleZ; field_0x33cc = 1.0f; field_0x2f99 = 0xC; dComIfGp_setPlayerStatus0(0, 0x08000000); if (var_r27) { dComIfGp_setPlayerStatus0(0, 0x2000); } return 1; } int daAlink_c::procCrawlMove() { daPy_frameCtrl_c* framectrl = &mUnderFrameCtrl[0]; cXyz sp54; cXyz sp48; cXyz sp3C; field_0x2f99 = 0xC; decideCrawlDoStatus(); cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlStandUpOffset, &sp48); cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlFrontUpOffset, &sp54); cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlBackUpOffset, &sp3C); cXyz sp30; cXyz sp24; cMtx_multVecSR(mpLinkModel->getBaseTRMtx(), &l_crawlMinSideOffset, &sp24); BOOL temp_r25 = checkNotCrawlStand(&sp48); BOOL temp_r24 = checkNotCrawlStand(&sp54); BOOL temp_r23 = checkNotCrawlStand(&sp3C); BOOL var_r27; if (temp_r25 || temp_r24 || temp_r23 || checkNotCrawlStand(&sp54, &sp24) || checkNotCrawlStand(&sp3C, &sp24) || checkNotCrawlStand(&sp48, &sp24)) { var_r27 = 0; onModeFlg(0x04000000); } else { var_r27 = 1; offModeFlg(0x04000000); } cM3dGPla sp60; if ((var_r27 != 0 && mProcVar3.field_0x300e == 0) || getSlidePolygon(&sp60) || checkCrawlWaterIn()) { procCrawlEndInit(1, shape_angle.x, shape_angle.z); } else { BOOL var_r26 = FALSE; f32 temp_f31 = getCrawlMoveAnmSpeed(); if (framectrl->getRate() > 0.0f) { setWaterInAnmRate(framectrl, temp_f31); } else if (framectrl->getRate() < 0.0f) { setWaterInAnmRate(framectrl, -temp_f31); } else { var_r26 = TRUE; } if (var_r26 == TRUE || framectrl->checkPass(0.0f) || framectrl->checkPass(17.0f)) { if (mProcVar3.field_0x300e != 0) { mProcVar3.field_0x300e--; setWaterInAnmRate(framectrl, temp_f31); framectrl->setLoop(0); } else if (checkInputOnR()) { if (getDirectionFromShapeAngle() != DIR_BACKWARD) { setWaterInAnmRate(framectrl, temp_f31); framectrl->setLoop(0); } else { setWaterInAnmRate(framectrl, -temp_f31); framectrl->setLoop(framectrl->getEnd()); } initBasAnime(); } else if (var_r26 == FALSE) { stopHalfMoveAnime(17.0f); } } int sp8 = field_0x3198; cXyz sp18; field_0x3198 = 0; if (checkCrawlInHoll(&sp54, &sp3C, &sp18, var_r27)) { setCrawlMoveHoll(); } else if (sp8 != 0 && temp_r25 && temp_r24 && temp_r23 && !var_r27 && changeCrawlAutoMoveProc(&sp18) ) { return 1; } else if (mProcVar3.field_0x300e == 0 && checkInputOnR() && framectrl->getRate() > 0.0f) { setCrawlMoveAngle(); } mNormalSpeed = getCrawlMoveSpeed(); cXyz spC; if (mNormalSpeed < 0.0f) { mNormalSpeed *= -1.0f; current.angle.y = shape_angle.y + 0x8000; cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlBackOffset, &spC); crawlBgCheck(&spC, &sp3C, 1); } else { cMtx_multVec(mpLinkModel->getBaseTRMtx(), &l_crawlFrontOffset, &spC); crawlBgCheck(&spC, &sp54, 1); } } return 1; } int daAlink_c::procCrawlAutoMoveInit(int param_0, cXyz* param_1) { BOOL var_r30; if (dComIfGp_checkPlayerStatus0(0, 0x2000)) { var_r30 = TRUE; } else { var_r30 = FALSE; } commonProcInit(PROC_CRAWL_AUTO_MOVE); field_0x37c8 = *param_1; field_0x33cc = 1.0f; field_0x3198 = param_0; mProcVar0.field_0x3008 = 20; mProcVar1.field_0x300a = 300; dComIfGp_setPlayerStatus0(0, 0x8000000); setCrawlMoveDirectionArrow(); mNormalSpeed = 0.0f; field_0x2f99 = 12; if (var_r30) { dComIfGp_setPlayerStatus0(0, 0x2000); } return 1; } int daAlink_c::procCrawlAutoMove() { field_0x2f99 = 0xC; daPy_frameCtrl_c* framectrl = &mUnderFrameCtrl[0]; s16 prev_shapeangle = shape_angle.y; s16 prev_angle = current.angle.y; if (mProcVar0.field_0x3008 > 0) { if (framectrl->checkPass(0.0f) || framectrl->checkPass(17.0f)) { stopHalfMoveAnime(17.0f); mNormalSpeed = 0.0f; } else if (checkAnmEnd(framectrl)) { mNormalSpeed = 0.0f; mProcVar0.field_0x3008--; } setCrawlMoveDirectionArrow(); decideCrawlDoStatus(); shape_angle.y = prev_shapeangle; current.angle.y = prev_angle; } else if (mProcVar0.field_0x3008 == 0) { setCrawlMoveDirectionArrow(); if (checkInputOnR()) { setCrawlAutoMoveAimPos(); if (mProcVar0.field_0x3008 == -1) { dComIfGp_setAdvanceDirection(0); if (shape_angle.y == current.angle.y) { setWaterInAnmRate(framectrl, 2.0f); framectrl->setLoop(0); } else { setWaterInAnmRate(framectrl, -2.0f); framectrl->setLoop(framectrl->getEnd()); } initBasAnime(); } } else { decideCrawlDoStatus(); shape_angle.y = prev_shapeangle; current.angle.y = prev_angle; } } else { int var_r28 = 1; if (mProcVar1.field_0x300a > 0) { mProcVar1.field_0x300a--; } if (mProcVar3.field_0x300e != 0) { if (cLib_addCalcAngleS(&shape_angle.y, mProcVar2.field_0x300c, 5, 0x480, 0x80)) { var_r28 = 0; } if (mProcVar3.field_0x300e < 0) { current.angle.y = shape_angle.y + 0x8000; } else { current.angle.y = shape_angle.y; } cLib_addCalc(¤t.pos.x, field_0x37c8.x, 0.5f, 3.0f, 1.0f); cLib_addCalc(¤t.pos.z, field_0x37c8.z, 0.5f, 3.0f, 1.0f); } cXyz sp8 = field_0x37c8 - current.pos; if (cLib_distanceAngleS(sp8.atan2sX_Z(), current.angle.y) < 0x6000) { var_r28 = 0; } mNormalSpeed = getCrawlMoveSpeed(); if (mNormalSpeed < 0.0f) { mNormalSpeed *= -1.0f; current.angle.y = shape_angle.y + 0x8000; } if (var_r28 != 0 || mProcVar1.field_0x300a == 0) { procCrawlMoveInit(shape_angle.x, shape_angle.z); } } mCameraAngleY = shape_angle.y; return 1; } int daAlink_c::procCrawlEndInit(int param_0, s16 i_angleX, s16 i_angleZ) { daPy_frameCtrl_c* framectrl = &mUnderFrameCtrl[0]; f32 frame = framectrl->getFrame(); commonProcInit(PROC_CRAWL_END); current.angle.y = shape_angle.y; field_0x2f99 = 0xC; const daAlinkHIO_anm_c* anmParams = &mpHIO->mCrouch.m.mCrawlEndAnm; f32 morf; if (param_0 != 0) { morf = anmParams->mInterpolation; } else { morf = -1.0f; } setSingleAnime(ANM_CRAWL_START, anmParams->mSpeed, anmParams->mStartFrame, anmParams->mEndFrame, morf); if (param_0 == 0) { if (anmParams->mStartFrame > frame) { frame = anmParams->mStartFrame; } else if (anmParams->mEndFrame <= frame) { frame = anmParams->mEndFrame; } framectrl->setFrame(frame); getNowAnmPackUnder(UNDER_0)->setFrame(frame); } J3DTransformInfo transinfo; getNowAnmPackUnder(UNDER_0)->getTransform(0, &transinfo); field_0x34d4.x = transinfo.mTranslate.x; field_0x34d4.y = transinfo.mTranslate.y; field_0x34d4.z = transinfo.mTranslate.z; mNormalSpeed = 0.0f; shape_angle.x = i_angleX; shape_angle.z = i_angleZ; if (anmParams->mCancelFrame > anmParams->mStartFrame) { field_0x347c = anmParams->mCancelFrame; } else { field_0x347c = anmParams->mStartFrame; } field_0x3478 = 1.0f / (anmParams->mEndFrame - field_0x347c); field_0x3588 = l_waitBaseAnime; return 1; } int daAlink_c::procCrawlEnd() { daPy_frameCtrl_c* frame_ctrl = mUnderFrameCtrl; field_0x33cc = field_0x3478 * (frame_ctrl->getFrame() - field_0x347c); field_0x2f99 = 4; if (checkAnmEnd(frame_ctrl)) { if (!checkNextActionFromCrouch(0)) { procWaitInit(); } } else if (frame_ctrl->getFrame() < mpHIO->mCrouch.m.mCrawlEndAnm.mCancelFrame) { checkNextActionFromCrouch(1); } return 1; }