#include "d/a/obj/d_a_obj_seat_sword.h" #include "common.h" #include "d/a/d_a_player.h" #include "d/a/obj/d_a_obj_base.h" #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_w.h" #include "d/col/cc/d_cc_d.h" #include "d/col/cc/d_cc_s.h" #include "f/f_base.h" #include "m/m_angle.h" #include "m/m_mtx.h" #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "rvl/MTX/mtx.h" #include "s/s_Math.h" #include "toBeSorted/attention.h" #include "toBeSorted/event.h" #include "toBeSorted/event_manager.h" SPECIAL_ACTOR_PROFILE(OBJ_SEAT_SWORD, dAcOSeatSword_c, fProfile::OBJ_SEAT_SWORD, 0x249, 0, 3); STATE_DEFINE(dAcOSeatSword_c, Wait); STATE_DEFINE(dAcOSeatSword_c, Get); dCcD_SrcCyl dAcOSeatSword_c::sCylSrc = { /* mObjInf */ {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, /* mObjTg */ {0, 0x311, {0, 0, 0x407}, 0x0, 0x0}, /* mObjCo */ {0xE9}}, /* mCylInf */ {20.f, 100.f} }; const char sEventName[] = "PickSwordSeat"; char *SwordSeatNames[] = {"SwordSeal", "SwordGrd"}; const InteractionTargetDef dAcOSeatSword_c::sInteractionDef = { 0, 2, 1, EXAMINE_TALK, 0, 200.f, 60.f, 0.f, -100.f, 100.f, 50.f, 1.f, }; const Vec dAcOSeatSword_c::sEffectPos = {-20.f, 260.f, 30.f}; bool dAcOSeatSword_c::createHeap() { if (mSubtype == 0) { const char *goddess_sword = daPlayerActBase_c::getSwordName(1); mRes = dAcPy_c::getItemResFile(goddess_sword, mAllocator); TRY_CREATE(mSwordMdl.create(mRes.GetResMdl(goddess_sword), &mAllocator, 0x120, 1, nullptr)); } else if (mSubtype == 1) { mRes = dAcPy_c::GetLink()->getSwordResFile(); const char *sword_name = daPlayerActBase_c::getSwordName(daPlayerActBase_c::sCurrentSword); TRY_CREATE(mSwordMdl.create(mRes.GetResMdl(sword_name), &mAllocator, 0x120, 1, nullptr)); } nw4r::g3d::ResFile mPedRes(getOarcResFile(SwordSeatNames[mSubtype])); TRY_CREATE(mPedestalMdl.create(mPedRes.GetResMdl(SwordSeatNames[mSubtype]), &mAllocator, 0x120, 1, nullptr)); void *dzb = getOarcDZB(SwordSeatNames[mSubtype], SwordSeatNames[mSubtype]); void *plc = getOarcPLC(SwordSeatNames[mSubtype], SwordSeatNames[mSubtype]); updateMatrix(); mSwordMtx.copyFrom(mWorldMtx); TRY_CREATE(!mBgW.Set((cBgD_t *)dzb, (PLC *)plc, 1, &mWorldMtx, &mScale)); if (mSubtype == 1) { TRY_CREATE(mPedestalMdl_s.create(mPedRes.GetResMdl("SwordGrd_s"), &mAllocator, 0x120, 1, nullptr)); } return true; } const s16 l_inGroundRot = {0x71C}; int dAcOSeatSword_c::create() { mSubtype = getSubtype(); if (mSubtype >= 2) { mSubtype = 0; } CREATE_ALLOCATOR(dAcOSeatSword_c); mStts.SetRank(0xD); mCyl.Set(sCylSrc); mCyl.SetStts(mStts); dBgS::GetInstance()->Regist(&mBgW, this); mPedestalMdl.setLocalMtx(mWorldMtx); if (mSubtype == 1) { mPedestalMdl_s.setLocalMtx(mWorldMtx); mPedestalMdl_s.setPriorityDraw(0x22, 0x9); } mAcceleration = 0.f; mMaxSpeed = -40.f; if (mSubtype == 1) { field_0x7E8 = l_inGroundRot; } updateSwordMdl(); mEff.init(this); mPedestalMdl.setPriorityDraw(0x1C, 0x9); if (checkPlayerHasSword()) { mStateMgr.changeState(StateID_Get); } else { mStateMgr.changeState(StateID_Wait); } mBoundingBox.Set(mVec3_c(-75.f, -10.f, -75.f), mVec3_c(75.f, 200.f, 75.f)); return SUCCEEDED; } int dAcOSeatSword_c::doDelete() { return SUCCEEDED; } int dAcOSeatSword_c::actorExecute() { mStateMgr.executeState(); if (mStateMgr.isState(StateID_Wait)) { actorExecuteCommon(); mCyl.SetC(mPosition); dCcS::GetInstance()->Set(&mCyl); } return SUCCEEDED; } int dAcOSeatSword_c::actorExecuteInEvent() { if (mbNoSword) { sLib::chase(&field_0x7E4, 255.f, 8.f); } actorExecuteCommon(); if (mEvent.isThisActorInEvent()) { switch (mEvent.getCurrentEventCommand()) { case 'act0': { mEvent.advanceNext(); } break; case 'act1': { dAcPy_c::LINK->getBodyMtx(&mSwordMtx, 0xF /* weaponR*/); mSwordMdl.setLocalMtx(mSwordMtx); mEvent.advanceNext(); } break; case 'act2': { mbNoSword = true; dAcPy_c::LINK->getBodyMtx(&mSwordMtx, 0xF /* weaponR*/); mSwordMdl.setLocalMtx(mSwordMtx); mEvent.advanceNext(); } } } return SUCCEEDED; } void dAcOSeatSword_c::doInteraction(s32 param0) { if (param0 == EXAMINE_TALK) { field_0x7EA = true; Event evt((char *)sEventName, 0x190, 0x100001, nullptr, nullptr); mEvent.scheduleEvent(evt, 0); } else { field_0x7EA = false; } } u32 someAng = 0x8000; void dAcOSeatSword_c::registerInEvent() { static const u32 rodata_stuff = {0}; if (field_0x7EA == 1 && EventManager::isCurrentEvent(sEventName)) { dAcPy_c *player = dAcPy_c::LINK; mVec3_c vec = mVec3_c::Ez * 78.f; mAng3_c ang = mRotation; ang.y += someAng; vec.rotY(mRotation.y); vec += mPosition; player->setPosRot(&vec, &ang, 0, 1, 0); field_0x7E8.set(0); updateSwordMdl(); } } int dAcOSeatSword_c::draw() { if (!mStateMgr.isState(StateID_Get)) { drawModelType1(&mSwordMdl); } drawModelType1(&mPedestalMdl); if (mSubtype == 1) { drawModelType1(&mPedestalMdl_s); } return SUCCEEDED; } void dAcOSeatSword_c::initializeState_Wait() {} void dAcOSeatSword_c::executeState_Wait() { AttentionManager::GetInstance()->addTarget(*this, sInteractionDef, 0, nullptr); if (checkPlayerHasSword()) { mbNoSword = true; } if (mbNoSword) { mStateMgr.changeState(StateID_Get); } } void dAcOSeatSword_c::finalizeState_Wait() {} // Get state to remove any interaction/effect void dAcOSeatSword_c::initializeState_Get() { mEff.remove(true); } void dAcOSeatSword_c::executeState_Get() {} void dAcOSeatSword_c::finalizeState_Get() {} void dAcOSeatSword_c::actorExecuteCommon() { if (checkPlayerHasSword()) { return; } // ??????? this func const dAcPy_c *player = dAcPy_c::LINK; mEffPos.x = sEffectPos.x; mEffPos.y = sEffectPos.y; mEffPos.z = sEffectPos.z; mEffPos.rotY(player->mRotation.y); mEffPos += player->mPosition; mEffPos.y = mPosition.y; mEff.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_76_, mEffPos, &mRotation, &mScale, nullptr, nullptr); mEff.setGlobalAlpha(field_0x7E4); } void dAcOSeatSword_c::updateSwordMdl() { updateMatrix(); mSwordMtx.copyFrom(mWorldMtx); if (mSubtype == 1) { mSwordMtx.XrotM(field_0x7E8); } mMtx_c mtx; // Weird value for y, but ok mtx.transS(0.f, 87.51f, 0.f); mSwordMtx += mtx; mSwordMtx.YrotM(0x4000); mSwordMtx.ZrotM(0xC000); mSwordMdl.setLocalMtx(mSwordMtx); } bool dAcOSeatSword_c::checkPlayerHasSword() { // the GetFlag needs to be an inline ... (using getCounterOrFlag doesnt work) return (mSubtype == 0 && StoryflagManager::sInstance->getFlag(STORYFLAG_GODDESS_SWORD)) || (mSubtype == 1 && !StoryflagManager::sInstance->getFlag(STORYFLAG_SWORD_RESTRICTED)); }