#include "d/a/npc/d_a_npc_saltalk.h" #include "common.h" #include "d/a/d_a_base.h" #include "d/a/d_a_player.h" #include "f/f_base.h" #include "f/f_manager.h" #include "f/f_profile_name.h" #include "m/m_angle.h" #include "m/m_vec.h" #include "s/s_State.hpp" #include "toBeSorted/area_utils.h" #include "toBeSorted/event_manager.h" SPECIAL_ACTOR_PROFILE(NPC_SLTK, dAcNpcSltk_c, fProfile::NPC_SLTK, 0x63, 0, 0); STATE_VIRTUAL_DEFINE(dAcNpcSltk_c, Wait); int dAcNpcSltk_c::create() { return dAcBase_c::create(); } int dAcNpcSltk_c::actorCreate() { field_0x748 = getParam4(); if (isSomething0()) { field_0x754 = getParam0_0(); field_0x74C = 0xFF; field_0x750 = 0xFF; } else if (isSomething1()) { field_0x754 = 0xFF; field_0x74C = getParam0_1(); field_0x750 = getParam1(); } else { field_0x754 = 0xFF; field_0x74C = 0xFF; field_0x750 = 0xFF; } mAreaIndex = mRotation.z & 0xFF; if (mAreaIndex < 0xFF) { mpArea = getAreaForIndexInRoom(mAreaIndex, mRoomID); if (mpArea == nullptr) { return FAILED; } } mRotation.set(0, 0, 0); field_0x758 = getParam2() * 100; field_0x75C = getParam3() * 100; setState(StateID_Wait); field_0x76C = 0; mBoundingBox.Set(mVec3_c(-0.0f, -0.0f, -0.0f), mVec3_c(0.0f, 0.0f, 0.0f)); return SUCCEEDED; } int dAcNpcSltk_c::actorPostCreate() { mLinkPos = getLinkPos(); mRef.unlink(); f32 closestDistance = FLOAT_MAX; dAcNpcSlb2_c *cursor = nullptr; dAcNpcSlb2_c *closest = nullptr; do { cursor = static_cast(fManager_c::searchBaseByProfName(fProfile::NPC_SLB2, cursor)); if (cursor != nullptr) { if (cursor->acNpc_vt_0x1F4()) { f32 thisDist = cursor->getSquareDistanceTo(mPosition); if (thisDist < closestDistance) { closest = cursor; closestDistance = cursor->getSquareDistanceTo(mPosition); } } } } while (cursor != nullptr); if (closest != nullptr) { mRef.link(closest); } return SUCCEEDED; } int dAcNpcSltk_c::actorExecute() { npcExecute(); return SUCCEEDED; } int dAcNpcSltk_c::acNpc_vt_0xDC() { return 0; } int dAcNpcSltk_c::draw() { return SUCCEEDED; } int dAcNpcSltk_c::getParam0_0() const { return mParams & 0xFF; } int dAcNpcSltk_c::getParam0_1() const { return mParams & 0xFF; } int dAcNpcSltk_c::getParam1() const { return (mParams >> 8) & 0xFF; } int dAcNpcSltk_c::getParam2() const { return (mParams >> 16) & 0xFF; } int dAcNpcSltk_c::getParam3() const { return (mParams >> 24) & 0xFF; } int dAcNpcSltk_c::getParam4() const { return getParams2Lower() & 0xF; } int dAcNpcSltk_c::getSomething() const { return field_0x748; } bool dAcNpcSltk_c::isSomething0() const { return getSomething() == 0; } bool dAcNpcSltk_c::isSomething1() const { return getSomething() == 1; } bool dAcNpcSltk_c::checkSomething(mVec3_c pos) const { if (mAreaIndex != 0xFF) { return checkPosInArea(mAreaIndex, mRoomID, pos, &mpArea) == 1; } else { mVec3_c dist = pos - mPosition; if (dist.squareMagXZ() <= field_0x758 * field_0x758) { f32 fDist = field_0x75C + mPosition.y; f32 fDist2 = mPosition.y; if (fDist <= fDist2) { fDist2 = fDist; fDist = mPosition.y; } return pos.y <= fDist && pos.y >= fDist2; } else { return false; } } } void dAcNpcSltk_c::initializeState_Wait() {} void dAcNpcSltk_c::executeState_Wait() { bool checkResult = false; const dAcPy_c *link = dAcPy_c::GetLink(); dAcNpcSlb2_c *slb = mRef.get(); if (slb != nullptr) { if (isSomething0()) { checkResult = checkSomething(link->mPosition); if (field_0x76C != 0) { field_0x76C = checkResult; } else if (!EventManager::isInEvent() && !slb->fn_61_6A10() && checkResult) { mAng3_c ang = mAng3_c(0, mpArea->mAngleY, 0); mVec3_c proj = mVec3_c::createProjectionXZ(ang, 1.0f); mVec3_c dist = mLinkPos - mpArea->mPos; dist.y = 0.0f; dist.normalize(); slb->fn_61_68D0(field_0x754); field_0x76C = 1; } if (!checkResult) { if (!link->checkActionFlags(0xC70852) || link->checkActionFlags(0x40000)) { mLinkPos = link->mPosition; } } } else if (isSomething1()) { checkResult = checkSomething(slb->mPosition); if (field_0x76C == 0 && checkResult) { slb->fn_61_58C0(field_0x74C, field_0x750); } } field_0x76C = checkResult; } } void dAcNpcSltk_c::finalizeState_Wait() {}