#include "d/a/obj/d_a_obj_underground_switch.h" #include "common.h" #include "d/a/d_a_player.h" #include "d/a/obj/d_a_obj_base.h" #include "d/flag/sceneflag_manager.h" #include "d/snd/d_snd_wzsound.h" #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resanmclr.h" #include "nw4r/g3d/res/g3d_resmdl.h" #include "toBeSorted/event_manager.h" SPECIAL_ACTOR_PROFILE(OBJ_UG_SWITCH, dAcOUgSwitch_c, fProfile::OBJ_UG_SWITCH, 0x15A, 0, 3); STATE_DEFINE(dAcOUgSwitch_c, Off); STATE_DEFINE(dAcOUgSwitch_c, Active); STATE_DEFINE(dAcOUgSwitch_c, On); const f32 dAcOUgSwitch_c::sActivationRadius = 40.0f; const u8 dAcOUgSwitch_c::sEventTimer = 15; bool dAcOUgSwitch_c::createHeap() { void *data = getOarcResFile("SwitchPass"); mRes = nw4r::g3d::ResFile(data); nw4r::g3d::ResMdl mdl = mRes.GetResMdl("SwitchPass"); TRY_CREATE(mMdl.create(mdl, &mAllocator, 0x120)); mRes = nw4r::g3d::ResFile(data); mdl = mRes.GetResMdl("SwitchPass"); nw4r::g3d::ResAnmClr clr = mRes.GetResAnmClr("SwitchPass_Light"); TRY_CREATE(mAnmClr.create(mdl, clr, &mAllocator, nullptr, 1)); mMdl.setAnm(mAnmClr); return true; } int dAcOUgSwitch_c::create() { mActiveSceneFlag = mParams & 0xFF; field_0x3BD = (mParams >> 8) & 0xFF; setVariant((mParams >> 16) & 0xF); CREATE_ALLOCATOR_SIZE(dAcOUgSwitch_c, 0x1000); mOnEventTimer = 0; updateMatrix(); mMdl.setLocalMtx(mWorldMtx); mMdl.setPriorityDraw(0x82, 0x7F); if (!SceneflagManager::sInstance->checkBoolFlag(mRoomID, mActiveSceneFlag)) { if (mVariant == 0) { mStateMgr.changeState(StateID_Active); } else { mStateMgr.changeState(StateID_Off); } } else { mStateMgr.changeState(StateID_On); } mBoundingBox.Set(mVec3_c(-50.0f, -20.0f, -50.0f), mVec3_c(50.0f, 20.0f, 50.0f)); return SUCCEEDED; } int dAcOUgSwitch_c::doDelete() { return SUCCEEDED; } int dAcOUgSwitch_c::actorExecute() { mStateMgr.executeState(); return SUCCEEDED; } int dAcOUgSwitch_c::actorExecuteInEvent() { if (EventManager::isInEvent(this, "OnSwitchCount")) { if (mOnEventTimer != 0 && --mOnEventTimer == 0) { if (mVariant == 0 && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, mActiveSceneFlag)) { SceneflagManager::sInstance->setFlag(mRoomID, mActiveSceneFlag); } else { if (mVariant == 1 && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, field_0x3BD)) { SceneflagManager::sInstance->setFlag(mRoomID, field_0x3BD); } } EventManager::finishEvent(this, "OnSwitchCount"); } return SUCCEEDED; } return NOT_READY; } int dAcOUgSwitch_c::draw() { drawModelType1(&mMdl); return SUCCEEDED; } void dAcOUgSwitch_c::initializeState_Off() { mAnmClr.setFrame(0.0f, 0); } void dAcOUgSwitch_c::executeState_Off() { if (mVariant == 1 && SceneflagManager::sInstance->checkBoolFlag(mRoomID, mActiveSceneFlag)) { mStateMgr.changeState(StateID_Active); } } void dAcOUgSwitch_c::finalizeState_Off() {} void dAcOUgSwitch_c::initializeState_Active() { mAnmClr.setFrame(1.0f, 0); } void dAcOUgSwitch_c::executeState_Active() { if (mVariant == 0 && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, mActiveSceneFlag)) { if (isWithinPlayerRadius(sActivationRadius) && dAcPy_c::LINK->checkActionFlags(dAcPy_c::FLG0_CRAWLING)) { mOnEventTimer = sEventTimer; startSound(SE_UgSwitc_ON_ZERO); mStateMgr.changeState(StateID_On); } } if (mVariant == 1) { if (!SceneflagManager::sInstance->checkBoolFlag(mRoomID, field_0x3BD)) { if (isWithinPlayerRadius(sActivationRadius) && dAcPy_c::LINK->checkActionFlags(dAcPy_c::FLG0_CRAWLING)) { mOnEventTimer = sEventTimer; startSound(SE_UgSwitc_ON); mStateMgr.changeState(StateID_On); } } if (!SceneflagManager::sInstance->checkBoolFlag(mRoomID, mActiveSceneFlag)) { mStateMgr.changeState(StateID_Off); } } } void dAcOUgSwitch_c::finalizeState_Active() {} void dAcOUgSwitch_c::initializeState_On() { mAnmClr.setFrame(2.0f, 0); static volatile u32 FLAGS_1 = 0x00000001; static u32 FLAGS_2 = 0x00100001; u32 f1 = FLAGS_1; u32 f2 = FLAGS_2; Event event = Event("OnSwitchCount", 100, f2 & ~f1, nullptr, nullptr); EventManager::alsoSetAsCurrentEvent(this, &event, nullptr); } void dAcOUgSwitch_c::executeState_On() { if (!SceneflagManager::sInstance->checkBoolFlag(mRoomID, mActiveSceneFlag)) { if (mVariant == 0) { mStateMgr.changeState(StateID_Active); } else { mStateMgr.changeState(StateID_Off); } } } void dAcOUgSwitch_c::finalizeState_On() {} void dAcOUgSwitch_c::setVariant(int variant) { if (variant == 0) { mVariant = 0; } else { mVariant = 1; } }