#include "d/a/obj/d_a_obj_ivy_rope.h" #include "c/c_lib.h" #include "c/c_math.h" #include "common.h" #include "d/a/d_a_player.h" #include "d/a/obj/d_a_obj_base.h" #include "d/col/c/c_cc_d.h" #include "d/col/c/c_m3d_g_lin.h" #include "d/col/cc/d_cc_s.h" #include "d/d_vec.h" #include "d/flag/sceneflag_manager.h" #include "d/snd/d_snd_wzsound.h" #include "egg/math/eggMath.h" #include "m/m3d/m3d.h" #include "m/m_angle.h" #include "m/m_mtx.h" #include "m/m_quat.h" #include "m/m_vec.h" #include "nw4r/math/math_arithmetic.h" #include "nw4r/math/math_triangular.h" #include "rvl/MTX/mtxvec.h" #include "s/s_Math.h" #include "toBeSorted/attention.h" SPECIAL_ACTOR_PROFILE(OBJ_IVY_ROPE, dAcOivyRope_c, fProfile::OBJ_IVY_ROPE, 0x262, 0, 2); STATE_DEFINE(dAcOivyRope_c, RopeWait); STATE_DEFINE(dAcOivyRope_c, PlayerGrip); STATE_DEFINE(dAcOivyRope_c, RopeReturn); STATE_DEFINE(dAcOivyRope_c, RopeCut); STATE_DEFINE(dAcOivyRope_c, TerryRopeWait); STATE_DEFINE(dAcOivyRope_c, TerryRopeUp); STATE_DEFINE(dAcOivyRope_c, TerryRopeDown); STATE_DEFINE(dAcOivyRope_c, TerryRopeInit); STATE_DEFINE(dAcOivyRope_c, TerryRopePlayerCarry); InteractionTargetDef dAcOivyRope_c::sInteraction = { 0, 0, 1, GRAB, 0, 150.f, 60.f, 0.f, 200.f, 650.f, 50.f, 1.f, }; dCcD_SrcCps dAcOivyRope_c::sCpsSrc = { /* mObjInf */ {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, /* mObjTg */ {AT_TYPE_0x800000 | AT_TYPE_BEETLE | AT_TYPE_CLAWSHOT | AT_TYPE_ARROW | AT_TYPE_WHIP | AT_TYPE_SLINGSHOT | AT_TYPE_BOMB | AT_TYPE_SWORD, 0x111, {0, 0x19, 0x407}, 0, 0}, /* mObjCo */ {0x4029}}, /* mCpsInf */ {10.f} }; dCcD_SrcSph dAcOivyRope_c::sSphSrc = { /* mObjInf */ {/* mObjAt */ {AT_TYPE_DAMAGE, 0x11, {0, 0, 0}, 1, 0, 0, 0, 0, 0}, /* mObjTg */ {~AT_TYPE_COMMON0, 0x111, {0, 0, 0x407}, 0, 0}, /* mObjCo */ {0x29}}, /* mSphInf */ {100.f} }; dCcD_SrcCyl dAcOivyRope_c::sCylSrc = { /* mObjInf */ {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, /* mObjTg */ {AT_TYPE_BELLOWS, 0x311, {0, 0, 8}, 8, 0}, /* mObjCo */ {0x109}}, /* mCylInf */ {10.f, 750.f} }; const f32 dAcOivyRope_c::lbl_256_rodata_40 = 0.04f; dAcOivyRope_c::~dAcOivyRope_c() { if (mPnts1) { delete[] mPnts1; mPnts1 = nullptr; } if (mPnts2) { delete[] mPnts2; mPnts2 = nullptr; } } void dAcOivyRope_c::initTightRope() {} void dAcOivyRope_c::fn_256_10C0() { field_0x106C = 0.f; mVec3_c pnt; fn_256_30A0(pnt); // TODO } UNKTYPE dAcOivyRope_c::fn_256_11A0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_1240(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_1480(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_2160(UNKTYPE) {} void dAcOivyRope_c::fn_256_26B0(int, bool, f32) {} UNKTYPE dAcOivyRope_c::fn_256_2C40(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_2D00(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_2DC0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_2EA0(UNKTYPE) {} void dAcOivyRope_c::fn_256_30A0(mVec3_c &out) {} UNKTYPE dAcOivyRope_c::fn_256_33B0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_34B0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_3540(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_35E0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_36A0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_3770(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_3A20(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_3B90(UNKTYPE) {} UNKTYPE dAcOivyRope_c::calcDistance(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_3E30(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_3E70(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_3F60(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_43B0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_4520(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_4760(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_4C80(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_4CA0(UNKTYPE) {} int dAcOivyRope_c::createBase() { mRotation = 0; f32 temp = 2000.f - 750.f; mDistance = 2000.f; mOldDistance = 2000.f; mSegmentCount = 81; mDropsceneFlag = mParams >> 12; field_0xFEB = 1; if (temp < 0.f) { temp = 0.f; } temp /= 750.f; field_0x1040 = temp; if (temp > 1.f) { field_0x1040 = 1.f; } CREATE_ALLOCATOR(dAcOivyRope_c); // TODO } UNKTYPE dAcOivyRope_c::fn_256_5190(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_5590(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_57F0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_5B00(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_5B64(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_5B70(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_5DB0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_5FF0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_6100(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_61F0(UNKTYPE) {} void dAcOivyRope_c::initializeState_TerryRopeInit() {} void dAcOivyRope_c::executeState_TerryRopeInit() {} void dAcOivyRope_c::finalizeState_TerryRopeInit() {} void dAcOivyRope_c::initializeState_TerryRopeDown() {} void dAcOivyRope_c::executeState_TerryRopeDown() {} void dAcOivyRope_c::finalizeState_TerryRopeDown() {} void dAcOivyRope_c::initializeState_TerryRopeUp() {} void dAcOivyRope_c::executeState_TerryRopeUp() {} void dAcOivyRope_c::finalizeState_TerryRopeUp() {} void dAcOivyRope_c::initializeState_TerryRopePlayerCarry() {} void dAcOivyRope_c::executeState_TerryRopePlayerCarry() {} void dAcOivyRope_c::finalizeState_TerryRopePlayerCarry() {} void dAcOivyRope_c::initializeState_TerryRopeWait() {} void dAcOivyRope_c::executeState_TerryRopeWait() {} void dAcOivyRope_c::finalizeState_TerryRopeWait() {} bool dAcOivyRope_c::createHeap() { mPnts1 = new mVec3_c[mSegmentCount]; } int dAcOivyRope_c::create() {} UNKTYPE dAcOivyRope_c::fn_256_7300(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_7310(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_73D0(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_7560(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_7680(UNKTYPE) {} void dAcOivyRope_c::initializeState_RopeWait() {} void dAcOivyRope_c::executeState_RopeWait() {} void dAcOivyRope_c::finalizeState_RopeWait() {} void dAcOivyRope_c::initializeState_PlayerGrip() {} void dAcOivyRope_c::executeState_PlayerGrip() {} void dAcOivyRope_c::finalizeState_PlayerGrip() {} void dAcOivyRope_c::initializeState_RopeReturn() {} void dAcOivyRope_c::executeState_RopeReturn() {} void dAcOivyRope_c::finalizeState_RopeReturn() {} void dAcOivyRope_c::initializeState_RopeCut() {} void dAcOivyRope_c::executeState_RopeCut() { if (field_0xFF8 != 0) { mStateMgr.changeState(StateID_PlayerGrip); } else { if (field_0xFCE != 0 && --field_0xFCE == 0) { mPosition = mTightropeEnd; } fn_256_8590(); fn_256_C740(); } } void dAcOivyRope_c::finalizeState_RopeCut() { mPosition = mTightropeEnd; field_0xFCE = 0; } UNKTYPE dAcOivyRope_c::fn_256_7D50(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_8060(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_8590(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_8990(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_8D10(UNKTYPE) {} void dAcOivyRope_c::fn_256_9120(u16) {} UNKTYPE dAcOivyRope_c::fn_256_9280(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_9450(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_9C80(UNKTYPE) {} UNKTYPE dAcOivyRope_c::fn_256_A040(UNKTYPE) { // Logically wrong i think if (field_0x1062 == 0) { mVec3_c *pnt2 = mPnts2; int idx = 1; if (mSegmentCount > idx) { f32 f1 = 5.f * field_0x1040 + 8.f; f32 f2 = -0.05f * field_0x1040 + 0.15f; mVec3_c nextPoint; mVec3_c vec; mVec3_c *pnt1 = mPnts1 + 1; while (idx < mSegmentCount) { nextPoint = pnt2[1]; vec = (pnt2[1] - pnt2[0]) + pnt1[0]; vec.y -= f1; vec.normalize(); pnt2[1] = pnt2[0] + vec * 25.f; pnt1[0] *= f2; pnt1[0] += (pnt2[1] - nextPoint) * 0.5f; idx++; pnt1++; pnt2++; } } if (mTightropeEnd.y - mDistance >= pnt2->y) { field_0x1062 = 1; } } fn_256_A2C0(false); } void dAcOivyRope_c::fn_256_A2C0(bool bool0) { mMtx_c m = mWorldMtx; f32 fVar13 = 0.f; f32 fVar14 = field_0xFAC * (mSegmentCount * 2.f) / 3.0f; f32 fVar2 = field_0xFB0 * (mSegmentCount * 2.f) / 3.0f; // TODO } bool dAcOivyRope_c::fn_256_A750(bool bool0, f32 float0) { // Logically wrong i think int idx = 1; mVec3_c *pnt = mPnts2; if (mSegmentCount >= idx) { f32 f1 = 8.f + field_0x1040 * 5.f; f32 f2 = 0.15f + field_0x1040 * -0.05f; for (; idx < mSegmentCount; idx++) { mVec3_c vec = pnt[idx + 1] - pnt[idx] + mPnts1[idx]; vec -= f1; vec.normalize(); pnt[idx] += vec * 25.f; mPnts1[idx] *= f2; mPnts1[idx] += (pnt[idx + 1] - pnt[idx]) * float0; } } if (!bool0) { for (int i = 0; i < mSegmentCount; ++i) { fn_256_D7A0(i, mPnts2[mSegmentCount - 1 - i]); } } else { for (int i = 0; i < mSegmentCount; ++i) { fn_256_D7A0(i, mPnts2[i]); } } if (mTightropeEnd.y - mDistance >= pnt->y) { return true; } else { return false; } } f32 dAcOivyRope_c::fn_256_AA40() { f32 f = field_0xFB4 / mSegmentCount * 1.5f; f32 ret = f; if (f < 0.6f) { ret = 0.6f; } else if (f > 0.9f) { ret = 0.9f; } return ret; } f32 dAcOivyRope_c::fn_256_AAB0(f32 f1, f32 f2) { if (cM::isZero(f2)) { return 1.f; } return f1 / f2; } int dAcOivyRope_c::fn_256_AAF0(f32 f1, f32 f2) { // deal with this later ;-; f32 f = f1 * f2; f32 c = -(90.f * f) + 55.f * f * f; f32 a = 0.8f * (1.f - field_0x1040); f32 b = (field_0xFB4 / mSegmentCount) * c; return field_0xFD8 * (1.f - a) * (field_0xFB4 + b); } void dAcOivyRope_c::fn_256_ABA0() { field_0xFDA = 0; field_0xFDC = 0; fn_256_BB70(); fn_256_D050(); mStateMgr.changeState(StateID_RopeWait); } void dAcOivyRope_c::fn_256_AC00() { mStateMgr.executeState(); if (mStateMgr.isState(StateID_PlayerGrip)) { fn_256_9450(); } else if (mStateMgr.isState(StateID_RopeReturn)) { if (mSubtype == 2) { fn_256_9C80(); } else { fn_256_A040(); } } else if (mStateMgr.isState(StateID_RopeCut)) { fn_256_A040(); } else if (mSubtype == 6) { fn_256_DAA0(true, false, 4.0f, 0.13f); } else if (mSubtype == 7) { fn_256_DAA0(false, false, 4.0f, 0.13f); } else { bool check = checkSubtype(0) || checkSubtype(4) || checkSubtype(3) || checkSubtype(7) || checkSubtype(6); if (check) { fn_256_DAA0(false, false, 4.0f, 0.13f); } else { fn_256_A2C0(true); } } fn_256_C410(); field_0xFF8 = 0; } void dAcOivyRope_c::fn_256_AE00() { field_0xFDA = mRotation.x; field_0xFDC = mRotation.y; mRotation.x = 0; mRotation.y = 0; int i = 0; updateMatrix(); mMtx_c m = mWorldMtx; if (mSegmentCount > i) { for (; i < mSegmentCount; ++i) { m.copyFrom(mWorldMtx); mMtx_c m_tmp; m_tmp.transS(0.f, -25.f * i, 0.f); m += m_tmp; m.getTranslation(mPnts2[i]); mVec3_c tmp = mPnts2[i]; mVec3_c tmp2 = tmp - mPosition; m.copyFrom(mWorldMtx); m.YrotM(field_0xFDC); m.XrotM(field_0xFDA); mMtx_c m_tmp2; m_tmp2.transS(tmp2); m += m_tmp2; m.getTranslation(tmp); fn_256_D7A0(i, tmp); mPnts1[i].set(0.f, 0.f, 0.f); } } mStts.SetRank(0); for (int curr_idx = 0, i = 0; i < field_0xFEB; curr_idx += 4, ++i) { int end = mSegmentCount - 1; int start_idx = curr_idx; if (start_idx > end) { start_idx = end; } int end_idx = curr_idx + 4; if (end_idx > end) { end_idx = end; } mCpsArr2[i].Set(sCpsSrc); mCpsArr2[i].SetStts(mStts); mCpsArr2[i].cM3dGLin::Set(fn_256_D730(start_idx), fn_256_D730(end_idx)); mCpsArr2[i].SetR(100.f); mCpsArr2[i].ClrTgSet(); } field_0x1083 = 0.6f * mSegmentCount; mVec3_c v = fn_256_D730(field_0x1083); v.y -= nw4r::math::FAbs(80.f / field_0xFDA.sin()); fn_256_26B0(field_0x1083, false, v.y); field_0xFE2 = -1; fn_256_D050(); mStateMgr.changeState(StateID_RopeWait); } void dAcOivyRope_c::fn_256_B2B0() { // TODO } void dAcOivyRope_c::fn_256_BAB0(mVec3_c &out, int idx, s16 xRot, s16 yRot) { int pnt2_idx = idx - 1; if (pnt2_idx < 0) { pnt2_idx = 0; } mMtx_c m; m.transS(mPnts2[pnt2_idx]); m.YrotM(yRot); m.XrotM(xRot); m.multVec(mVec3_c(0.f, -25.f, 0.f), out); } void dAcOivyRope_c::fn_256_BB70() { field_0xFDA = mRotation.x; field_0xFDC = mRotation.y; mRotation.x = 0; mRotation.y = 0; updateMatrix(); mVec3_c *pnt2; mVec3_c *pnt1; mMtx_c m = mWorldMtx; int i; for (i = 0, pnt1 = &mPnts1[i], pnt2 = &mPnts2[i]; i < mSegmentCount; ++i, pnt2++, pnt1++) { m.copyFrom(mWorldMtx); m.YrotM(field_0xFDC); m.XrotM(field_0xFDA); mMtx_c m_tmp; m_tmp.transS(0.f, -25.f * i, 0.f); m += m_tmp; m.getTranslation(*pnt2); fn_256_D7A0(i, *pnt2); pnt1->set(0.f, 0.f, 0.f); } mStts.SetRank(1); for (int curr_idx = 0, i = 0; i < field_0xFEB; curr_idx += 4, ++i) { int end = mSegmentCount - 1; int start_idx = curr_idx; if (start_idx > end) { start_idx = end; } int end_idx = curr_idx + 4; if (end_idx > end) { end_idx = end; } mCpsArr2[i].Set(sCpsSrc); mCpsArr2[i].SetStts(mStts); mCpsArr2[i].cM3dGLin::Set(fn_256_D730(start_idx), fn_256_D730(end_idx)); mCpsArr2[i].SetR(100.f); mCpsArr2[i].ClrTgSet(); } field_0xFF6 = 1; } void dAcOivyRope_c::fn_256_BE80() { f32 step = 0.f; f32 target = 30.f; mAng angle = field_0xFCC - 0x8000; f32 stepSize = 0.13f * target; if (mSegmentCount >= 0) { for (int i = 1; i < mSegmentCount; i++) { if (sLib::chase(&step, target, stepSize)) { target *= -1.f; } mPnts1[i].set(0.f, 0.f, 0.f); getXZCirclePoint(mPnts1[i], angle, step); } } } void dAcOivyRope_c::fn_256_BFF0(int ang, f32 float0, f32 float1) { f32 target = float0; f32 tmp = float0 * (0.1f - field_0x1040 * 0.03f); f32 step = 0; f32 f = ang; if (mSegmentCount >= 0) { for (int i = 1; i < mSegmentCount; i++) { if (sLib::chase(&step, target, tmp)) { target = cM::isZero(target) ? float0 : 0.f; } mAng angle = f; mPnts1[i].set(0.f, 0.f, 0.f); getXZCirclePoint(mPnts1[i], angle, step); mPnts1[i].y = float1; } } } f32 dAcOivyRope_c::fn_256_C200(int ang) { // I dont like this function // Some stuff with field_0xFB4 here f32 y = mPnts2[mSegmentCount - 1].y; f32 x = mPnts2[mSegmentCount - 1].x - mTightropeEnd.x; f32 z = mPnts2[mSegmentCount - 1].z - mTightropeEnd.z; f32 float_30 = 30.f * 1.f; f32 float_60 = 60.f * 1.f; f32 flaot_100 = 100.f * 1.f; f32 sq = EGG::Math::sqrt(x * x + z * z); f32 ab = nw4r::math::FAbs(y - mTightropeEnd.y); f32 tmp0, tmp1, tmp2, tmp3; f32 ret; s16 angle = cM::atan2s(sq, ab); tmp0 = angle / 9102.f; if (tmp0 > 0.5f) { tmp0 = 0.5f; } tmp1 = 1.0f - field_0x1040; if (tmp1 < 0.3f) { tmp1 = 0.3f; } tmp2 = field_0x1050 / 40.f; tmp3 = tmp2 * tmp1; if (tmp3 > 0.5f) { tmp3 = 0.5f; } if (tmp2 > 0.5f) { tmp2 = 0.5f; } tmp1 = tmp0 + tmp3; if (tmp1 > 1.f) { tmp1 = 1.f; } fn_256_BFF0(ang, tmp1 * (field_0x1040 * flaot_100 + float_30), tmp1 * float_60); return tmp2; } void dAcOivyRope_c::fn_256_C410() { fn_256_3E70(); if (mStateMgr.isState(StateID_RopeReturn)) { mVec3_c diff = dAcPy_c::GetLink()->mPosition - mTightropeEnd; if (diff.squareMagXZ() > 90000.f) { return; } } if (mStateMgr.isState(StateID_PlayerGrip) || field_0xFCE != 0) { return; } int count = mSegmentCount - 9; f32 f2 = dAcPy_c::GetLink()->mPosition.y - 100.f; f32 f = 150.f + dAcPy_c::GetLink()->mPosition.y; if (count < 0) { count = 0; } for (int i = 0; i < field_0xFEB; i++) { // TODO } } bool dAcOivyRope_c::fn_256_C6F0() { if (field_0x105F) { field_0x105F += field_0x105E; if (field_0x105F >= mSegmentCount - 19) { field_0x105F = mSegmentCount - 20; return true; } } return false; } void dAcOivyRope_c::fn_256_C740() { const f32 f2 = (1.f - field_0x1040) * 4.f + 1.1f; if (field_0xFA4 <= f2) { const mVec3_c &pnt = fn_256_D730(mSegmentCount - 1); const mVec3_c diff = pnt - dAcPy_c::GetLink()->mPosition; const f32 diffmag = diff.squareMagXZ(); if (diffmag < 28900.f) { fn_256_C980(450.f, 200.f); } } } void dAcOivyRope_c::fn_256_C810(mVec3_c &pOut, int idx) { if (idx > 0) { mVec3_c end = fn_256_D730(idx); mVec3_c start = fn_256_D730(idx - 1); cLib::addCalcPos(&end, pOut, 0.65f, 75.f, 1.f); mVec3_c diff = end - start; diff.normalize(); pOut = start + diff * 25.f; } } void dAcOivyRope_c::fn_256_C960() { fn_256_C980(150.f, 200.f); } void dAcOivyRope_c::fn_256_C980(f32 f0, f32 f1) { sInteraction.field_0x24 = mDistance + f1; sInteraction.field_0x14 = f0; AttentionManager::GetInstance()->addTarget(*this, sInteraction, 0, nullptr); } UNKTYPE dAcOivyRope_c::fn_256_C9B0(UNKTYPE) {} void dAcOivyRope_c::fn_256_CD40() { mPosition = mPositionCopy3 = mPositionCopy2 = fn_256_D730(mSegmentCount - 1); mCps1.Set(sCpsSrc); mCps1.SetStts(mStts); mCps1.SetR(15.f); mCps1.SetTgInfo_0x1(0xB); mVec3_c tmp = mPosition; tmp.y -= 50.f; mCps1.cM3dGLin::Set(mPosition, tmp); mCps1.OnTg_0x200000(); } void dAcOivyRope_c::fn_256_CE20(f32 *pOut1, f32 *pOut2, f32 *pOut3) { f32 f2, f3; f32 f1 = field_0xFD6; f2 = field_0xFAC * field_0xFAC + field_0xFB0 * field_0xFB0; f3 = nw4r::math::FSqrt(f2); f32 temp = f3 / f1; f2 = nw4r::math::FAbs(temp); if (f2 > 1.f) { field_0xFAC = (field_0xFD6 - 1) * field_0xFCC.cos(); field_0xFB0 = (field_0xFD6 - 1) * -field_0xFCC.sin(); f2 = 1.f; } *pOut1 = f1; *pOut2 = f3; *pOut3 = f2; } void dAcOivyRope_c::fn_256_CFA0(bool bool0) { if (bool0 && field_0x1005 != 0) { field_0x1005 = 0; field_0x105F = mSegmentCount - 24; field_0xFF7 = 1; field_0xFF6 = 1; field_0xFC4 = 0.05f; field_0xFD6 = 20; field_0xFA4 = 1.1f + (s8)field_0x1005 * 0.1f; field_0xFA8 = 1.1f + (s8)field_0x1005 * 0.1f; field_0xFD2 = 0; field_0xFD4 = 0; } } void dAcOivyRope_c::fn_256_D050() { bool check = checkSubtype(0) || checkSubtype(4) || checkSubtype(3) || checkSubtype(7) || checkSubtype(6); if (check) { mCyl.Set(sCylSrc); mCyl.SetStts(mStts); mCyl.SetH(mDistance); } } void dAcOivyRope_c::fn_256_D110() { u32 third = (mSegmentCount - 1) / 3; field_0xFF0[0] = 0; for (int i = 1; i <= 3; i++) { field_0xFF0[i] = third * i; if (field_0xFF0[i] > (mSegmentCount - 1)) { field_0xFF0[i] = (mSegmentCount - 1); } } } void dAcOivyRope_c::fn_256_D1B0() { fn_256_D110(); for (int i = 0; i < 3; i++) { mCpsArr[i].Set(sCpsSrc); mCpsArr[i].SetStts(mStts); mCpsArr[i].ClrCoSet(); mCpsArr[i].SetR(15.f); mCpsArr[i].OffTgType(AT_TYPE_BEETLE | AT_TYPE_SLINGSHOT | AT_TYPE_SWORD); mCpsArr[i].OnTgType(AT_TYPE_0x40); mCpsArr[i].cM3dGLin::Set(fn_256_D730(field_0xFF0[i]), fn_256_D730(field_0xFF0[i + 1])); } } void dAcOivyRope_c::fn_256_D2B0() { if (checkObjectProperty(OBJ_PROP_0x1)) { return; } if (mSubtype == 3 && field_0x1039 == 3) { return; } if (field_0xFEF != 0) { field_0xFEF--; } for (int i = 0; i < 3; i++) { if (mCpsArr[i].ChkTgHit()) { field_0xFEF = 2; } mCpsArr[i].cM3dGLin::Set(fn_256_D730(field_0xFF0[i]), fn_256_D730(field_0xFF0[i + 1])); dCcS::GetInstance()->Set(&mCpsArr[i]); } } void dAcOivyRope_c::fn_256_D3D0(mVec3_c &pOut1, mVec3_c &pOut2, s16 param2, bool bool0, f32 float0) { mVec3_c playerPos = dAcPy_c::GetLink()->mPosition; mVec3_c playerCenter = dAcPy_c::GetLink()->getCenterTranslation(); if (bool0) { f32 a = (playerCenter.x - playerPos.x); a *= 0.3f; f32 b = (playerCenter.z - playerPos.z); b *= 0.3f; playerCenter.x = playerPos.x + a; playerCenter.z = playerPos.z + b; } mMtx_c m; m.transS(playerCenter); mAng3_c playerRot = dAcPy_c::GetLink()->mRotation; m.ZXYrotM(playerRot.x, playerRot.y, playerRot.z); // name 100% guess mAng swingAngle = (field_0xFCC - 0x8000) - dAcPy_c::GetLink()->mRotation.y; f32 something = param2 / 5461.f; if (something > 1.f) { something = 1.f; } mVec3_c somevec(0.f, 0.f, 0.f); getXZCirclePoint(somevec, swingAngle, something); mVec3_c somevec2(0.f, -25.f, float0); MTXMultVec(m, somevec, somevec2); somevec2 += somevec; if (somevec2.z < float0) { somevec2.z = float0; } // name 100% guess mVec3_c swingTarget; MTXMultVec(m, somevec, swingTarget); cLib::addCalcPos(&pOut2, swingTarget, 0.3f, 50.f, 1.f); if (pOut2.squareDistance(somevec2) > something * something) { pOut1 = pOut2 - somevec2; pOut1.normalize(); pOut2 = somevec2 + pOut1 * something; } pOut1 = pOut2 - playerPos; pOut1.normalize(); } // Get Path Point const mVec3_c &dAcOivyRope_c::fn_256_D730(s32 idx) { if (mSubtype == 3) { return mCoilMdl.getLine(0)->getPathPoint(idx); } else { return mRopeMdl.getLine(0)->getPathPoint(idx); } } // Set Path Point void dAcOivyRope_c::fn_256_D7A0(s32 idx, const mVec3_c &pnt) { if (mSubtype == 3) { mCoilMdl.getLine(0)->getPathPoint(idx) = pnt; } else { mRopeMdl.getLine(0)->getPathPoint(idx) = pnt; } } // Draw Shadow void dAcOivyRope_c::fn_256_D850() { bool draw_shadow = false; switch (mSubtype) { case 1: case 2: break; case 4: { if (!mbField_0xFE8) { draw_shadow = true; } } break; case 6: break; case 7: { if (mbField_0x27C5) { draw_shadow = true; } } break; default: draw_shadow = true; break; } if (draw_shadow) { static mQuat_c shadow_q = mQuat_c(0.f, 0.f, 0.f, 30.f); if (mSubtype == 7) { // This section is just weird int idk; f32 f; f32 val; val = nw4r::math::FAbs(field_0xF68.y - field_0x27C0); if (!(val > 1000.f)) { f = 250.f; idk = f; if (val > 50.f) { idk = (1000.f - val) * f * (1 / 950.f); if (idk < 5.f) { f = 5.f; idk = f; } } mMtx_c m; m.transS(field_0xF68); drawShadow(mShadow, nullptr, m, &shadow_q, -1, idk, -1, -1, -1, val); } } else { mMtx_c m; m.transS(fn_256_D730(mSegmentCount - 1)); drawShadow(mShadow, nullptr, m, &shadow_q, -1, -1, -1, -1, -1, 175.f); } } } extern "C" void *getCamera(int idx); void dAcOivyRope_c::fn_256_DAA0(bool bool0, bool bool1, f32 float0, f32 float1) { bool cylHitBellows = false; if ((bool1 || field_0xFEF != 0) || (mCyl.ChkTgHit() && mCyl.ChkTgAtHitType(AT_TYPE_BELLOWS))) { mbField_0x2793 = true; cylHitBellows = true; field_0x2792 = 10; if (field_0xFEF && mSubtype != 6) { float0 = 2.5f; } } if (mbField_0x2793) { if (field_0x2790 != 0) { field_0x2790--; } // This block is a mess else if (cylHitBellows) { field_0x2790 = 30; f32 target = float0 - field_0x1040 * 1.5f; f32 chasing = 0.f; f32 step = target * float1; int ang = dAcPy_c::GetLink()->mRotation.y; u8 *cam = (u8 *)getCamera(0); if (cam) { ang = cLib::targetAngleY(*(mVec3_c *)(cam + 0x6C), mTightropeEnd) + 0x2000; } ang += cM::rndInt(0x1555); int i = 1; if (mSegmentCount > 1) { for (; i < mSegmentCount; i++) { BOOL chased = sLib::chase(&chasing, target, step); if (chased) { target *= -1.f; } mPnts1[i].set(0.f, 0.f, 0.f); // Inline? mVec3_c &v = mPnts1[i]; f32 step = chasing; v.x += step * nw4r::math::SinIdx(ang); v.z += step * nw4r::math::CosIdx(ang); }; } } if (fn_256_A750(bool1, 0.5f)) { if (!bool0) { field_0xFD8 = 1; f32 target0 = -(field_0xFD8 * field_0xFCC.cos()); f32 target1 = -(field_0xFD8 * -field_0xFCC.sin()); sLib::addCalc(&field_0xFAC, target0, 0.4f, 2.0f, 0.5f); sLib::addCalc(&field_0xFB0, target1, 0.4f, 2.0f, 0.5f); field_0xFD2 = field_0xFAC; field_0xFD4 = field_0xFB0; if (field_0x2792 != 0) { field_0x2792--; } else { mbField_0x2793 = false; } } else { mbField_0x2793 = false; } } } else { field_0x2790 = 0; if (bool0) { fn_256_9280(); } else { fn_256_A2C0(true); } } } void dAcOivyRope_c::fn_256_DE80() { field_0x1038 = mSegmentCount - 1; field_0x101C = mPnts2[field_0x1038]; field_0x102C = field_0x1028; field_0x1032 = 0x4000; field_0x1039 = 2; field_0x103D = 1; } void dAcOivyRope_c::fn_256_DEE0() { field_0x101C = mPnts2[field_0x1038]; field_0x102C = field_0x1028; field_0x1032 = 0x4000; field_0x1039 = 4; field_0x103D = 0; } u32 dAcOivyRope_c::fn_256_DF30() {} void dAcOivyRope_c::fn_256_E3E0() { static const u8 l_some_table[] = { /* [0] */ 1, 10, 2, 0, 2, 40, 2, /* [7] */ 0, 3, 25, 2, 0, 3, // has 3 more zeros, probably padding }; if (mStateMgr.isState(StateID_PlayerGrip)) { field_0x1030 = 60; } switch (field_0x1039) { case 1: { u32 var = fn_256_DF30(); if (mStateMgr.isState(StateID_PlayerGrip)) { fn_256_DEE0(); } else if (field_0x103D != 0) { if (field_0x103C != 0) { field_0x103C--; } else { field_0x103D = 0; field_0x103C = l_some_table[++field_0x103B]; } } else if (var == 0) { if (field_0x103C != 0) { field_0x103C--; } else if (field_0x103B >= 12) { fn_256_DE80(); } else { field_0x103C = l_some_table[++field_0x103B]; field_0x103D = 1; } } } break; case 2: { field_0x1039 = fn_256_DF30(); if (mStateMgr.isState(StateID_PlayerGrip)) { fn_256_DEE0(); } else { if (fn_256_E790()) { field_0x103A = 0; field_0x1030 = 60; mStateMgr.changeState(StateID_RopeReturn); fn_256_DEE0(); } } } break; case 3: { if (field_0x103A == -1) { if (fn_256_E790()) { if (mEventIdx != 0xFF && !mEvent.isThisActorInEvent()) { static volatile u32 FLAGS_1 = 0x00000001; static u32 FLAGS_2 = 0x00100001; u32 f1 = FLAGS_1; u32 f2 = FLAGS_2; Event e(mEventIdx, mRoomID, f2 & ~f1, 0, 0); mEvent.scheduleEvent(e, 0); } } } else if (field_0x103A > 0) { field_0x103A--; } else if (field_0x103A == 0) { field_0x1030 = 60; mStateMgr.changeState(StateID_RopeReturn); fn_256_DEE0(); startSound(SE_IvyRope_HANGDOWN); } } break; case 4: { field_0x1039 = fn_256_DF30(); } break; case 5: { if (checkObjectProperty(OBJ_PROP_0x1)) { field_0x1039 = 2; } else { for (int i = 0; i < 0x23; i++) { field_0x1039 = fn_256_DF30(); if (field_0x1039 != 5) { break; } } if (field_0x1039 == 5) { field_0x1039 = 2; } } } break; } if (field_0x1039 != 0) { mSph.SetC(field_0x1010); dCcS::GetInstance()->Set(&mSph); } } bool dAcOivyRope_c::fn_256_E790() { bool ret = false; if (mDropped) { field_0x103A = 0xF; ret = true; } if (mSph.ChkTgHit()) { field_0x103A = 0x1; ret = true; } if (ret) { SceneflagManager::sInstance->setFlag(mRoomID, mWoodTagSceneflag); } return ret; } bool dAcOivyRope_c::canBeLinkedToWoodTag() { if (mSubtype == 3) { return !SceneflagManager::sInstance->checkBoolFlag(mRoomID, mWoodTagSceneflag); } return false; } bool dAcOivyRope_c::drop() { bool dropFlag; if (mDropsceneFlag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, mDropsceneFlag)) { dropFlag = false; } else { dropFlag = true; } if (dropFlag) { mDropped = true; return true; } else { return false; } }