summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorElijah Thomas <42302100+elijah-thomas774@users.noreply.github.com>2026-10-02 20:32:12 -0400
committerGitHub <noreply@github.com>2026-10-02 20:32:12 -0400
commit98aba2c59b9bcd261d98cd8843bc40ae0b2d6877 (patch)
treeab75b4ec8add5790a870a9a60d158519c10e434e /src
parentaec7b6f81ab79b07cd94a7754b592bc22c231041 (diff)
parentde0fcc21dd700bf25e417147820388d194a59b33 (diff)
Merge pull request #345 from elijah-thomas774/d_a_obj_mushroom
d_a_obj_mushroom
Diffstat (limited to 'src')
-rw-r--r--src/REL/d/a/obj/d_a_obj_mushroom.cpp1161
-rw-r--r--src/d/col/c/c_m3d.cpp6
2 files changed, 1162 insertions, 5 deletions
diff --git a/src/REL/d/a/obj/d_a_obj_mushroom.cpp b/src/REL/d/a/obj/d_a_obj_mushroom.cpp
index f5900665..01ff5ba3 100644
--- a/src/REL/d/a/obj/d_a_obj_mushroom.cpp
+++ b/src/REL/d/a/obj/d_a_obj_mushroom.cpp
@@ -1,13 +1,1168 @@
#include "d/a/obj/d_a_obj_mushroom.h"
+#include "c/c_math.h"
+#include "common.h"
+#include "d/a/d_a_base.h"
+#include "d/a/d_a_player.h"
+#include "d/a/obj/d_a_obj_base.h"
+#include "d/col/bg/d_bg_s_wtr_chk.h"
+#include "d/col/c/c_cc_d.h"
+#include "d/col/c/c_m3d.h"
+#include "d/col/c/c_m3d_g_lin.h"
+#include "d/col/c/c_m3d_g_sph.h"
+#include "d/col/cc/d_cc_d.h"
+#include "d/col/cc/d_cc_s.h"
+#include "d/d_gfx.h"
+#include "d/d_light_env.h"
+#include "d/d_sc_game.h"
+#include "d/snd/d_snd_wzsound.h"
+#include "egg/gfx/eggCamera.h"
+#include "egg/gfx/eggDrawGX.h"
+#include "egg/gfx/eggLightManager.h"
+#include "egg/gfx/eggLightTexture.h"
+#include "egg/gfx/eggLightTextureMgr.h"
+#include "egg/gfx/eggTexture.h"
+#include "f/f_base.h"
+#include "f/f_profile_name.h"
+#include "m/m3d/m3d.h"
+#include "m/m_color.h"
+#include "m/m_mtx.h"
+#include "m/m_sphere.h"
+#include "m/m_vec.h"
+#include "nw4r/g3d/g3d_camera.h"
+#include "nw4r/g3d/g3d_dcc.h"
+#include "nw4r/g3d/g3d_scnobj.h"
+#include "nw4r/g3d/g3d_state.h"
+#include "nw4r/g3d/res/g3d_resanmtexsrt.h"
+#include "nw4r/math/math_types.h"
+#include "rvl/GX/GXGeometry.h"
+#include "rvl/GX/GXLight.h"
+#include "rvl/GX/GXTev.h"
+#include "rvl/GX/GXTransform.h"
+#include "rvl/GX/GXTypes.h"
+#include "rvl/GX/GXVert.h"
+#include "rvl/MTX/mtx.h"
+#include "s/s_Math.h"
+#include "toBeSorted/d_emitter.h"
+
+class dAcOMushRoom_HIO_c {
+public:
+ f32 field_0x00;
+ f32 field_0x04;
+ f32 field_0x08;
+ s32 field_0x0C;
+ u16 field_0x10;
+ f32 field_0x14;
+ f32 field_0x18;
+ f32 field_0x1C;
+ f32 field_0x20;
+ f32 field_0x24;
+ f32 field_0x28;
+ f32 mLightScaleS;
+ f32 mLightScaleT;
+ f32 mLightTransS;
+ f32 mLightTransT;
+ f32 field_0x3C;
+ f32 field_0x40;
+ f32 field_0x44;
+ f32 field_0x48;
+ u16 field_0x4C;
+ f32 field_0x50;
+ f32 field_0x54;
+ u16 field_0x58;
+ u16 field_0x5A;
+ u16 field_0x5C;
+ u16 field_0x5E;
+ u16 field_0x60;
+ u16 field_0x62;
+ u16 field_0x64;
+ u16 field_0x66;
+
+ static const dAcOMushRoom_HIO_c sInstance;
+};
+
+const dAcOMushRoom_HIO_c dAcOMushRoom_HIO_c::sInstance = {
+ 0.0f, 4500.0f, 0.0f, 10, 30, 200.0f, 100.0f, 100.0f, 100.0f, 200.0f, 100.0f, 1.25f, 0.5f, 0.5f, 0.5f,
+ 0.0f, 0.0f, 0.0f, 0.1f, 30, 6.5f, 300.0f, 180, 230, 255, 200, 12, 79, 56, 255,
+};
+
+static const Vec sRadius[4] = {
+ {105.0f, 90.0f, 210.0f},
+ {105.0f, 90.0f, 205.0f},
+ {105.0f, 135.0f, 312.0f},
+ {105.0f, 135.0f, 312.0f},
+};
+
+extern const f32 unused_ = 0.3f; // TODO - maybe still part of HIO
+
SPECIAL_ACTOR_PROFILE(OBJ_MUSHROOM, dAcOMushRoom_c, fProfile::OBJ_MUSHROOM, 0x141, 0, 7);
+static dCcD_SrcSph sSrcSph = {
+ /* mObjInf */
+ {/* mObjAt */ {AT_TYPE_NONE, 0, {0, 0, 0}, 0, 0, 0, 0, CUT_DIR_NONE, 0},
+ /* mObjTg */ {~AT_TYPE_COMMON0, 0x1000111, {0, 5, 0x407}, 0, CUT_DIR_NONE},
+ /* mObjCo */ {0xE9}},
+ /* mSphInf */
+ {110.f}
+};
+static dCcD_SrcCyl sSrcCyl = {
+ /* mObjInf */
+ {/* mObjAt */ {AT_TYPE_NONE, 0, {0, 0, 0}, 0, 0, 0, 0, CUT_DIR_NONE, 0},
+ /* mObjTg */ {~AT_TYPE_COMMON0, 0x1000110, {0, 5, 0x407}, 0, CUT_DIR_NONE},
+ /* mObjCo */ {0xE9}},
+ /* mSphInf */
+ {135.0f, 30.0f}
+};
+
+static mVec3_c sBboxMin[4] = {
+ mVec3_c(-150.0, -30.0, -150.0),
+ mVec3_c(-100.0, -30.0, -100.0),
+ mVec3_c(-100.0, -30.0, -100.0),
+ mVec3_c(-100.0, -30.0, -100.0),
+};
+static mVec3_c sBboxMax[4] = {
+ mVec3_c(150.0, 250.0, 150.0),
+ mVec3_c(100.0, 250.0, 100.0),
+ mVec3_c(100.0, 350.0, 100.0),
+ mVec3_c(100.0, 250.0, 100.0),
+};
+
STATE_DEFINE(dAcOMushRoom_c, Wait);
STATE_DEFINE(dAcOMushRoom_c, Init);
-void dAcOMushRoom_c::initializeState_Wait() {}
-void dAcOMushRoom_c::executeState_Wait() {}
+dAcOMushRoom_c::camera_c dAcOMushRoom_c::sCameras[8];
+
+dAcOMushRoom_c::camera_c::~camera_c() {}
+
+static mMtx_c fn_328_830(s8 camIdx, s8 camSubIdx) {
+ nw4r::g3d::Camera cam = m3d::getCamera(10);
+ cam.SetOrtho(
+ dGfx_c::getCurrentScreenTopF(), dGfx_c::getCurrentScreenBottomF(), dGfx_c::getCurrentScreenLeftF(),
+ dGfx_c::getCurrentScreenRightF(), 0.1f, 1000.0f
+ );
+
+ dAcOMushRoom_c::camera_c &sCam = dAcOMushRoom_c::sCameras[camIdx];
+ const dAcOMushRoom_HIO_c &sHIO = dAcOMushRoom_HIO_c::sInstance;
+
+ f32 lightScaleS, lightScaleT, lightTransS, lightTransT;
+ if (sCam.mAlpha[camSubIdx] == 0) {
+ lightScaleS = lightScaleT = lightTransS = lightTransT = 0.0f;
+ } else {
+ if (sCam.field_0x1B3[camSubIdx] == 1) {
+ lightScaleS = 3.0f;
+ } else {
+ lightScaleS = sHIO.mLightScaleS;
+ }
+ lightScaleT = sHIO.mLightScaleT;
+ lightTransS = sHIO.mLightTransS;
+ lightTransT = sHIO.mLightTransT;
+
+ lightScaleT += 1.5f * (255.0f - sCam.mAlpha[camSubIdx]) / 255.0f;
+ }
+
+ cam.SetTexMtxParam(lightScaleS, -lightScaleT, lightTransS, lightTransT);
+ sCam.mCam[camSubIdx].setG3DCamera(cam);
+ mMtx_c projMtx, camMtx;
+ cam.GetProjectionTexMtx(projMtx);
+ cam.GetCameraMtx(camMtx);
+
+ projMtx.concat(camMtx);
+
+ mMtx_c ret = projMtx;
+ return ret;
+}
+
+template <typename T>
+static inline T extract_data(void *base, size_t offset) {
+ return *reinterpret_cast<T *>(reinterpret_cast<u8 *>(base) + offset);
+}
+template <typename T>
+static inline T *offset_ptr(void *base, size_t offset) {
+ return reinterpret_cast<T *>(reinterpret_cast<u8 *>(base) + offset);
+}
+
+bool dAcOMushRoom_c::createHeap() {
+ const char *resName = getResFileName();
+ const char *mdlName = getResMdlName();
+
+ bool result = mMdl.create(getOarcResFile(resName), mdlName, &mAllocator, 0x120);
+ if (!result) {
+ return false;
+ }
+
+ mMdl.setLODDistance(0, 0.0f);
+ mMdl.setLODDistance(1, 4500.0f);
+
+ void *dat = getOarcFile(resName, getDataBinName());
+
+ u16 numIdx = extract_data<u16>(dat, 0x08);
+ int posArrOffset = extract_data<u32>(dat, 0x0C);
+ int nrmArrOffset = extract_data<u32>(dat, 0x10);
+ int posIdxArrOffset = extract_data<u32>(dat, 0x14);
+ int nrmIdxArrOffset = extract_data<u32>(dat, 0x18);
+
+ mData_IdxMax = extract_data<u16>(dat, 4);
+ mData_VecNum = numIdx / 3;
+ mData_pPosArr = offset_ptr<mVec3_c>(dat, posArrOffset);
+ mData_pNrmArr = offset_ptr<mVec3_c>(dat, nrmArrOffset);
+ mData_pPosIdxArr = offset_ptr<u16>(dat, posIdxArrOffset);
+ mData_pNrmIdxArr = offset_ptr<u16>(dat, nrmIdxArrOffset);
+ EGG::ResTIMG *pImg = reinterpret_cast<EGG::ResTIMG *>(getOarcFile(resName, "tex/MushroomACut0.bti"));
+ for (int i = 0; i < 3; ++i) {
+ if (!mProc[i].create(
+ pImg, 0x25, &mAllocator, mData_VecNum / 2 + 3, mData_pPosArr, mData_pNrmArr, mData_pPosIdxArr,
+ mData_pNrmIdxArr
+ )) {
+ return false;
+ }
+ }
+ mMdl.setPriorityDraw(0x1C, 9);
+
+ return result;
+}
+
+int dAcOMushRoom_c::create() {
+ if ((getFromParams(31, 0x1) == 1 && mActorSubtype == SPAWN_Param)) {
+ if (cM::rndF(1.0f) <= 0.3f) {
+ field_0x892 = true;
+ }
+ }
+
+ CREATE_ALLOCATOR_SIZE(dAcOMushRoom_c, 0x2000);
+ initCc();
+ mAcceleration = 0.0f;
+ mMaxSpeed = 0.0f;
+ changeState(StateID_Init);
+ mBoundingBox.Set(sBboxMin[getType()], sBboxMax[getType()]);
+ field_0x7BC = 0.0f;
+
+ mCameraIdx = -1;
+ if (getType() == TYPE_MushroomD) {
+ setLighting();
+ }
+
+ if (dScGame_c::isCurrentStage("F103") || dScGame_c::isCurrentStage("F103_1") ||
+ dScGame_c::isCurrentStage("t_tkm24")) {
+ if ((s32)getFromParams(4, 0xF) == 0xF) {
+ field_0x891 = true;
+ } else {
+ field_0x891 = false;
+ }
+ } else if (dScGame_c::isCurrentStage("F100_1")) {
+ if (mPosition.y < -300.0f) {
+ field_0x891 = true;
+ } else {
+ field_0x891 = false;
+ }
+ } else {
+ if ((s32)getFromParams(4, 0xF) == 0xF) {
+ field_0x891 = false;
+ } else {
+ field_0x891 = true;
+ }
+ }
+
+ if (isNotParamBit30()) {
+ unsetActorProperty(AC_PROP_0x1);
+ }
+
+ return SUCCEEDED;
+}
+
+int dAcOMushRoom_c::doDelete() {
+ if (mCameraIdx >= 0) {
+ sCameras[mCameraIdx].field_0x1B6 = false;
+ mCameraIdx = -1;
+ }
+
+ if (getType() == TYPE_MushroomD) {
+ cutLighting();
+ }
+
+ return SUCCEEDED;
+}
+
+int dAcOMushRoom_c::actorExecute() {
+ if (checkGlittering()) {
+ startGlitterEmitter();
+ }
+
+ executeState();
+
+ mWorldMtx.transS(mPosition);
+ mWorldMtx.ZXYrotM(mRotation);
+ mWorldMtx.YrotM(field_0x794.y);
+ mWorldMtx.XrotM(field_0x794.x);
+ mWorldMtx.YrotM(-field_0x794.y);
+ mMdl.setScale(mScale.x + field_0x7BC, mScale.y + field_0x7BC, mScale.z + field_0x7BC);
+ mMdl.setLocalMtx(mWorldMtx);
+ mMdl.calc(false);
+
+ setCc();
+ fn_328_3970();
+ if (getType() == TYPE_MushroomD) {
+ fn_328_4EF0();
+ }
+
+ return SUCCEEDED;
+}
+
+int dAcOMushRoom_c::draw() {
+ drawModelType1(mMdl.getMdl());
+ mSphere_c sph(mVec3_c(0.0f, getShadowOffsetY(), 0.0f), getRadiusX() * 2.0f);
+ if (getType() == TYPE_MushroomD) {
+ drawShadow(mShadow, nullptr, mWorldMtx, &sph, -1, 0xC8, 0xB4, 0xE6, 0xFF, 0.0f);
+ } else {
+ drawShadow(mShadow, nullptr, mWorldMtx, &sph, -1, -1, -1, -1, -1, 0.0f);
+ }
+
+ if (mCameraIdx >= 0) {
+ updateCameras();
+ for (int i = 0; i < 3; ++i) {
+ if (mProcAlpha[i] != 0) {
+ mMtx_c m = mWorldMtx;
+ m.scaleM(mScale.x + field_0x7BC, mScale.y + field_0x7BC, mScale.z + field_0x7BC);
+ mProc[i].setLocalMtx(m);
+ mProc[i].entry();
+ }
+ }
+ }
+
+ return SUCCEEDED;
+}
+
+void dAcOMushRoom_c::initializeState_Wait() {
+ field_0x7A4 = mVec3_c::Zero;
+ field_0x7B0 = mPosition;
+ field_0x7B0.y += 200.0f;
+ field_0x7C0 = 500;
+}
+void dAcOMushRoom_c::executeState_Wait() {
+ static mAng angle = 0xAAB;
+
+ const dAcPy_c *pPlayer = dAcPy_c::GetLink();
+ dCcD_Sph &cc = getMainCc();
+
+ if (cc.ChkTgHit()) {
+ if (cc.ChkTgAtHitType(AT_TYPE_BOMB)) {
+ dAcObjBase_c *pObj = cc.GetTgActor();
+ if (pObj != nullptr) {
+ mVec3_c mod = mVec3_c::Ez * 10.0f;
+ mod.rotY((mPosition - pObj->mPosition).atan2sX_Z());
+ field_0x7A4.x += mod.x;
+ field_0x7A4.z += mod.z;
+ field_0x7C0 = 0;
+ field_0x79C = 30;
+ startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x);
+ }
+ } else if (cc.ChkTgAtHitType(AT_TYPE_WHIP) || cc.ChkTgAtHitType(AT_TYPE_CLAWSHOT) ||
+ cc.ChkTgAtHitType(AT_TYPE_0x40) || cc.ChkTgAtHitType(AT_TYPE_ARROW)) {
+ mAng hitAng = (mPosition - const_cast<const dCcD_Sph &>(cc).GetTgHitPos()).atan2sX_Z();
+ mVec3_c mod = mVec3_c::Ez * (field_0x7A4.mag() + 1.5f);
+ if (cc.ChkTgAtHitType(AT_TYPE_CLAWSHOT)) {
+ mod *= 1.5f;
+ }
+ mod.rotY(hitAng);
+ field_0x7A4.x = mod.x;
+ field_0x7A4.z = mod.z;
+ startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x);
+ } else if (cc.ChkTgAtHitType(AT_TYPE_BELLOWS)) {
+ if (field_0x854 % 20 == 0) {
+ mAng hitAng = (mPosition - const_cast<const dCcD_Sph &>(cc).GetTgHitPos()).atan2sX_Z();
+ mVec3_c mod = mVec3_c::Ez * (field_0x7A4.mag() + 3.5f);
+ mod.rotY(hitAng);
+ field_0x7A4.x += mod.x;
+ field_0x7A4.z += mod.z;
+ }
+ field_0x854++;
+ } else if (cc.ChkTgAtHitType(AT_TYPE_SWORD) || cc.ChkTgAtHitType(AT_TYPE_0x800000)) {
+ if (dAcPy_c::GetLink() != nullptr) {
+ mAng hitAng = (mPosition - dAcPy_c::GetLink()->mPosition).atan2sX_Z();
+
+ switch (cc.GetTgAtCutDir()) {
+ case CUT_DIR_LU:
+ case CUT_DIR_L:
+ case CUT_DIR_LD: hitAng = hitAng + -0x4000; break;
+ case CUT_DIR_RD:
+ case CUT_DIR_R:
+ case CUT_DIR_RU: hitAng = hitAng + 0x4000; break;
+ }
+ mVec3_c mod = mVec3_c::Ez * (field_0x7A4.mag() + 3.0f);
+ mod.rotY(hitAng);
+ field_0x7A4.x = mod.x;
+ field_0x7A4.z = mod.z;
+ field_0x7C0 = 0;
+ field_0x79C = 40;
+ startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x);
+ fn_328_39C0();
+ }
+ } else if (cc.ChkTgAtHitType(AT_TYPE_BUBBLE)) {
+ if (pPlayer != nullptr) {
+ mVec3_c mod = mVec3_c::Ez * 3.0f;
+ mod.rotY(pPlayer->mRotation.y);
+ field_0x7A4.x += mod.x;
+ field_0x7A4.z += mod.z;
+ field_0x7C0 = 0;
+ field_0x79C = 30;
+ startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x);
+ }
+ }
+ } else if (pPlayer != nullptr && pPlayer->checkFlags0x350(0x2000) || pPlayer->checkFlags0x350(0x40)) {
+ if (field_0x7A0 != 0) {
+ mVec3_c mod = mVec3_c::Ez * 10.0f;
+ mod.rotY(pPlayer->mRotation.y);
+ field_0x7A4.x += mod.x;
+ field_0x7A4.z += mod.z;
+ field_0x7C0 = 0;
+ field_0x79C = 30;
+ startSoundWithFloatParam(SE_Kinoko_SHAKE, mScale.x);
+ mVec3_c bubbleSpawnPos(mPosition.x, mPosition.y + getRadiusZ() + 30.0f, mPosition.z);
+ itemDroppingAndGivingRelated(&bubbleSpawnPos, 3);
+ if (pPlayer->checkFlags0x350(0x40) && field_0x891) {
+ dAcObjBase_c::create(fProfile::OBJ_BUBBLE, mRoomID, 4, &bubbleSpawnPos, nullptr, nullptr, 0xFFFFFFFF);
+ dJEffManager_c::spawnEffect(
+ PARTICLE_RESOURCE_ID_MAPPING_727_, bubbleSpawnPos, nullptr, nullptr, nullptr, nullptr, 0, 0
+ );
+ }
+ } else {
+ mVec3_c mod = mVec3_c::Ez * 3.0f;
+ mod.rotY((mPosition - pPlayer->mPosition).atan2sX_Z());
+ field_0x7A4.x += mod.x;
+ field_0x7A4.z += mod.z;
+ }
+ }
+
+ if (cc.ChkTgHit() && !cc.ChkTgAtHitType(AT_TYPE_BELLOWS) || !cc.ChkTgHit()) {
+ field_0x854 = 0;
+ }
+ if (field_0x891 == 0) {
+ if ((cc.ChkTgHit() && (cc.ChkTgAtHitType(AT_TYPE_BOMB) || cc.ChkTgAtHitType(AT_TYPE_SWORD) ||
+ cc.ChkTgAtHitType(AT_TYPE_0x800000))) ||
+ (pPlayer != nullptr && pPlayer->checkFlags0x350(0x2000) && field_0x7A0 != 0)) {
+ if (!checkUnderWater()) {
+ u32 p1 = getSporeParams1();
+ static mVec3_c sOffsets[] = {
+ mVec3_c(0.0f, 70.0f, 0.0f),
+ mVec3_c(0.0f, 80.0f, 0.0f),
+ mVec3_c(0.0f, 120.0f, 0.0f),
+ mVec3_c(0.0f, 120.0f, 0.0f),
+ };
+ s32 type = getType();
+ mVec3_c pos = mPosition + sOffsets[type] * mScale.y;
+
+ if (dAcObjBase_c::create(this, fProfile::OBJ_SPORE, p1, &pos, nullptr, nullptr, 0, 0x3F)) {
+ field_0x892 = false;
+ }
+ startCloudEmitter();
+ }
+ }
+ }
+
+ mVec3_c v0 = (mPosition - field_0x7B0) * 0.05f;
+ v0.y = 0.0f;
+ field_0x7A4 += v0;
+ if (sLib::calcTimer(&field_0x79C) == 0) {
+ field_0x7A4.x *= 0.93f;
+ field_0x7A4.z *= 0.93f;
+ }
+ if (field_0x7A4.absXZ() > 10.0f) {
+ field_0x7A4.normalizeRS();
+ field_0x7A4 *= 10.0f;
+ }
+ field_0x7B0 += field_0x7A4;
+ mVec3_c diff = field_0x7B0 - mPosition;
+ field_0x794.x = cM::atan2s(diff.absXZ(), diff.y);
+ field_0x794.y = diff.atan2sX_Z();
+ if (field_0x794.x > angle) {
+ field_0x794.x = angle;
+ }
+ if (field_0x794.x < -(angle.mVal)) {
+ field_0x794.x = -angle;
+ }
+
+ // TODO: Figure out the const of the cc stuff
+ // The loading of the values here is off
+ static const s16 s0 = {0x2000};
+ field_0x7A0 = fn_8002eff0(mScale.x * 150.0f, s0, (cCcD_Obj *)(&cc), mScale.x * 55.0f, mScale.x * -75.0f);
+ if (field_0x7A0 == 0) {
+ static const s16 s1 = {0x4000};
+ field_0x7A0 = fn_328_4C30(mScale.x * 250.0f, s0, (cCcD_Obj *)(&cc), mScale.x * 200.0f, 0.0f);
+ }
+
+ if (field_0x7C0 < 1000) {
+ field_0x7C0++;
+ }
+
+ f32 f = (30 - field_0x7C0) / 30.0f;
+ if (f < 0.0f) {
+ f = 0.0f;
+ }
+ field_0x7BC = 0.1f * mAng(field_0x7C0 * 0x1000).cos() * f;
+
+ if (cM::isZero(field_0x7BC)) {
+ field_0x7A1 = false;
+ } else {
+ field_0x7A1 = true;
+ }
+
+ if (field_0x7A4.absXZ() > 6.5f) {
+ mVec3_c pos(mPosition.x, mPosition.y + getRadiusZ() + 30.0f, mPosition.z);
+ itemDroppingAndGivingRelated(&pos, 3);
+ }
+}
void dAcOMushRoom_c::finalizeState_Wait() {}
+
void dAcOMushRoom_c::initializeState_Init() {}
-void dAcOMushRoom_c::executeState_Init() {}
+void dAcOMushRoom_c::executeState_Init() {
+ changeState(StateID_Wait);
+}
void dAcOMushRoom_c::finalizeState_Init() {}
+
+f32 dAcOMushRoom_c::getUnscaledRadiusX() {
+ return sRadius[getType()].x;
+}
+
+f32 dAcOMushRoom_c::getUnscaledRadiusY() {
+ return sRadius[getType()].y;
+}
+
+f32 dAcOMushRoom_c::getRadiusX() {
+ return getUnscaledRadiusX() * mScale.x;
+}
+
+f32 dAcOMushRoom_c::getShadowOffsetY() {
+ return getUnscaledRadiusY() * mScale.x;
+}
+
+f32 dAcOMushRoom_c::getRadiusZ() {
+ return sRadius[getType()].z * mScale.y;
+}
+
+const char *dAcOMushRoom_c::getResFileName() {
+ if (mActorSubtype == SPAWN_Param) {
+ switch ((s32)getFromParams(0, 0xF)) {
+ case TYPE_MushroomA: return "MushroomA";
+ case TYPE_MushroomB: return "MushroomB";
+ case TYPE_MushroomC: return "MushroomC";
+ case TYPE_MushroomD: return "MushroomD";
+ }
+ return "MushroomA";
+ }
+ switch (mActorSubtype) {
+ case SPAWN_MushroomA: return "MushroomA";
+ case SPAWN_MushroomB: return "MushroomB";
+ case SPAWN_MushroomC: return "MushroomC";
+ case SPAWN_MushroomD: return "MushroomD";
+ }
+ return nullptr;
+}
+
+const char *dAcOMushRoom_c::getResMdlName() {
+ return getResFileName();
+}
+
+const char *dAcOMushRoom_c::getDataBinName() {
+ switch (getType()) {
+ case TYPE_MushroomA: return "dat/MushroomA.bin";
+ case TYPE_MushroomB: return "dat/MushroomB.bin";
+ case TYPE_MushroomC: return "dat/MushroomC.bin";
+ case TYPE_MushroomD: return "dat/MushroomD.bin";
+ }
+ return nullptr;
+}
+
+void dAcOMushRoom_c::initCc() {
+ mStts.SetRank(12);
+ mSph0.Set(sSrcSph);
+ mSph0.SetStts(mStts);
+ mCyl.Set(sSrcCyl);
+ mCyl.SetStts(mStts);
+ mSph1.Set(sSrcSph);
+ mSph1.SetStts(mStts);
+
+ mSph0.SetR(getRadiusX());
+ switch (getType()) {
+ case TYPE_MushroomA: {
+ mCyl.SetR(mScale.x * 135.0f);
+ mCyl.SetH(mScale.x * 30.0f);
+ mSph1.SetR(0.0f);
+ mSph0.SetR(getRadiusX() + 20.0f);
+ } break;
+ case TYPE_MushroomB:
+ case TYPE_MushroomD: {
+ mCyl.SetR(0.0f);
+ mCyl.SetH(0.0f);
+ mSph1.SetR(0.0f);
+ } break;
+ case TYPE_MushroomC: {
+ mCyl.SetR(0.0f);
+ mCyl.SetH(0.0f);
+ mSph1.SetR(mScale.x * 60.0f);
+ } break;
+ }
+}
+
+void dAcOMushRoom_c::setCc() {
+ s32 type = getType();
+ mVec3_c center = mVec3_c::Ey * getRadiusX();
+ mWorldMtx.multVec(center, center);
+ field_0x844 = center;
+ mSph0.SetC(center);
+ dCcS::GetInstance()->Set(&mSph0);
+ if (type == TYPE_MushroomB) {
+ mVec3_c cylC(center.x, center.y - mScale.x * 30.0f, center.z);
+ mCyl.SetC(cylC);
+ dCcS::GetInstance()->Set(&mCyl);
+ } else if (type == TYPE_MushroomC) {
+ mVec3_c sphC = mVec3_c::Ey * getRadiusX() * 1.8f;
+ mWorldMtx.multVec(sphC, sphC);
+ mSph1.SetC(sphC);
+ dCcS::GetInstance()->Set(&mSph1);
+ }
+}
+
+void dAcOMushRoom_c::startCloudEmitter() {
+ static mVec3_c sOffsets[] = {
+ mVec3_c(0.0f, 70.0f, 0.0f), // TYPE_MushroomA
+ mVec3_c(0.0f, 80.0f, 0.0f), // TYPE_MushroomB
+ mVec3_c(0.0f, 120.0f, 0.0f), // TYPE_MushroomC
+ mVec3_c(0.0f, 120.0f, 0.0f), // TYPE_MushroomD
+ };
+ mVec3_c offset = sOffsets[getType()] * mScale.y;
+
+ mMtx_c emitterLocation;
+ emitterLocation.transS(mPosition);
+ emitterLocation.ZXYrotM(mRotation);
+ emitterLocation.multVec(offset, offset);
+ emitterLocation.transS(offset);
+ emitterLocation.ZYXrotM(mRotation);
+ emitterLocation.YrotM(cM::rndRange(-0x7FFF, 0x7FFF));
+ emitterLocation.scaleM(mScale);
+ // 737 -> Blue Spores
+ // 468 -> Yellow Dust
+ // 467 -> Rainbow Dust
+ if (field_0x892) {
+ dEmitterBase_c *pEmmitter =
+ dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_467_, emitterLocation, nullptr, nullptr, 0, 0);
+ if (pEmmitter != nullptr) {
+ s32 volumeSize = 60;
+ if (getType() == TYPE_MushroomA) {
+ volumeSize = 100;
+ } else if (getType() == TYPE_MushroomB) {
+ volumeSize = 90;
+ } else if (getType() == TYPE_MushroomC) {
+ volumeSize = 80;
+ }
+ pEmmitter->setVolumeSize(volumeSize);
+ }
+ } else if (getType() == TYPE_MushroomD) {
+ dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_737_, emitterLocation, nullptr, nullptr, 0, 0);
+ } else {
+ dEmitterBase_c *pEmmitter =
+ dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_468_, emitterLocation, nullptr, nullptr, 0, 0);
+ if (pEmmitter != nullptr) {
+ s32 volumeSize = 60;
+ if (getType() == TYPE_MushroomA) {
+ volumeSize = 100;
+ } else if (getType() == TYPE_MushroomB) {
+ volumeSize = 90;
+ } else if (getType() == TYPE_MushroomC) {
+ volumeSize = 80;
+ }
+ pEmmitter->setVolumeSize(volumeSize);
+ }
+ }
+}
+
+void dAcOMushRoom_c::startGlitterEmitter() {
+ static mVec3_c sOffsets[] = {
+ mVec3_c(0.0f, 100.0f, 0.0f),
+ mVec3_c(0.0f, 110.0f, 0.0f),
+ mVec3_c(0.0f, 180.0f, 0.0f),
+ mVec3_c(0.0f, 180.0f, 0.0f),
+ };
+
+ mVec3_c offset = sOffsets[getType()] * mScale.y;
+
+ mMtx_c emitterLocation;
+ emitterLocation.transS(mPosition);
+ emitterLocation.ZXYrotM(mRotation);
+ emitterLocation.multVec(offset, offset);
+ emitterLocation.transS(offset);
+ emitterLocation.ZYXrotM(mRotation);
+ emitterLocation.YrotM(cM::rndRange(-0x7FFF, 0x7FFF));
+ emitterLocation.scaleM(mScale);
+ if (mEmitter.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_466_, emitterLocation, nullptr, nullptr)) {
+ s32 volumeSize;
+ switch (getType()) {
+ case TYPE_MushroomA:
+ case TYPE_MushroomB: volumeSize = 120; break;
+ case TYPE_MushroomC: volumeSize = 108; break;
+ default: volumeSize = 100; break;
+ }
+
+ mEmitter.setVolumeSize(volumeSize);
+ }
+}
+
+void dAcOMushRoom_c::fn_328_3970() {
+ if (mCameraIdx < 0) {
+ return;
+ }
+
+ bool bVisible = false;
+ for (int i = 0; i < 3; ++i) {
+ if (field_0x83F[i] != 0) {
+ field_0x83F[i]--;
+ bVisible = true;
+ } else {
+ if (mProcAlpha[i] == 0xFF) {
+ cM3dGSph sph;
+ cM3dGLin lin;
+ mVec3_c out0, out1;
+ mVec3_c start, end;
+ sph.Set(&field_0x844, getRadiusX());
+ start = field_0x7C4[i];
+ end = field_0x7E8[i];
+ if (field_0x83C[i] == 1) {
+ start.y += 100.0f;
+ end.y += (mScale.x + field_0x7BC) * 100.0f;
+ } else {
+ start.y += 200.0f;
+ end.y += (mScale.x + field_0x7BC) * 100.0f;
+ }
+ lin.Set(start, end);
+ if (cM3d_Cross_LinSph_CrossPos(sph, lin, out0, out1) > 0) {
+ mVec3_c src;
+ src.set(out1);
+ getSoundSource()->startSoundAtPosition2(SE_Kinoko_CURE, src);
+ }
+ }
+ sLib::chase(&mProcAlpha[i], 0, 12);
+ if (mProcAlpha[i] != 0) {
+ bVisible = true;
+ }
+ }
+ }
+
+ if (!bVisible) {
+ sCameras[mCameraIdx].field_0x1B6 = 0;
+ mCameraIdx = -1;
+ }
+}
+
+bool dAcOMushRoom_c::fn_328_39C0() {
+ if (mCameraIdx < 0) {
+ mCameraIdx = findCameraIdx();
+ }
+ if (mCameraIdx < 0) {
+ return false;
+ }
+
+ int idx = -1;
+ int alpha = 0xFF;
+ for (int i = 0; i < 3; ++i) {
+ if (mProcAlpha[i] == 0) {
+ idx = i;
+ break;
+ }
+ if (alpha >= mProcAlpha[i]) {
+ alpha = mProcAlpha[i];
+ idx = i;
+ }
+ }
+ if (idx < 0) {
+ return false;
+ }
+
+ mProcAlpha[idx] = 0xFF;
+ field_0x83F[idx] = 10;
+
+ const dCcD_Sph &cc = getMainCc();
+ field_0x7C4[idx] = dAcPy_c::GetLink()->mPosition;
+ field_0x7E8[idx] = mPosition;
+
+ mAng rot;
+ s32 cutDir = cc.GetTgAtCutDir();
+ if (cc.ChkTgAtHitType(AT_TYPE_0x800000)) {
+ switch (cutDir) {
+ case CUT_DIR_U:
+ case CUT_DIR_D:
+ case CUT_DIR_STAB: rot = 0x4000; break;
+
+ case CUT_DIR_L:
+ case CUT_DIR_R: rot = 0; break;
+
+ case CUT_DIR_LU:
+ case CUT_DIR_RD: rot = -0x2000; break;
+
+ case CUT_DIR_LD:
+ case CUT_DIR_RU: rot = 0x2000; break;
+
+ default: rot = 0; break;
+ }
+
+ field_0x7E8[idx].x = cc.GetTgHitPos().x;
+ field_0x7E8[idx].z = cc.GetTgHitPos().z;
+ } else {
+ rot = dAcPy_c::GetLink()->vt_0x258() + 0x4000;
+ }
+
+ if (cutDir == CUT_DIR_STAB) {
+ field_0x83C[idx] = 1;
+ } else {
+ field_0x83C[idx] = 0;
+ }
+ sCameras[mCameraIdx].field_0x1B3[idx] = field_0x83C[idx];
+
+ if (mRotation.x != 0 || mRotation.z != 0) {
+ mMtx_c m;
+ mVec3_c v;
+ m.ZXYrotS(mRotation);
+ m.multVecSR(mVec3_c::Ey, v);
+ C_MTXLookAt(m, field_0x7C4[idx], mVec3_c::Ey, field_0x7E8[idx]);
+ m.multVecSR(v, v);
+ s16 a = (0x4000 - cM::atan2s(v.y, v.x));
+ rot += a;
+ }
+
+ if (rot > 0x4000) {
+ rot = -(0x7FFF - rot);
+ }
+ if (rot < -0x4000) {
+ rot = rot + 0x7FFF;
+ }
+ mVec3_c v0 = field_0x7E8[idx] - field_0x7C4[idx];
+ mVec3_c v1 = mVec3_c::Ez;
+ v1.rotY(v0.atan2sX_Z());
+ mMtx_c m;
+ m.setAxisRotation(v1, -rot.radian_c());
+ m.multVec(mVec3_c::Ey, field_0x80C[idx]);
+ sCameras[mCameraIdx].mAlpha[idx] = 0xFF;
+
+ proc_c &proc = mProc[idx];
+ proc.clearIdx();
+ mProc[idx].mCameraIdx = mCameraIdx;
+
+ proc.mCameraSubIdx = idx;
+ updateCameras();
+ camera_c &cam = sCameras[mCameraIdx];
+
+ mMtx_c view = static_cast<mMtx_c &>(cam.mCam[idx].getViewMatrix());
+ mVec3_c pos = cam.mCam[idx].mPos;
+ mVec3_c at = cam.mCam[idx].mAt;
+ view.multVec(pos, pos);
+ view.multVec(at, at);
+
+ mMtx_c m1 = view;
+ m1.concat(mWorldMtx);
+
+ bool vals[200];
+ for (int i = 0; i < mData_IdxMax; ++i) {
+ mVec3_c posArr = mData_pPosArr[i];
+ vals[i] = fn_328_4B20(m1, posArr, pos.z, at.z);
+ }
+ for (int i = 0; i < mData_VecNum; i++) {
+ u16 a = mData_pPosIdxArr[3 * i + 0];
+ u16 b = mData_pPosIdxArr[3 * i + 1];
+ u16 c = mData_pPosIdxArr[3 * i + 2];
+ if (vals[a] || vals[b] || vals[c]) {
+ if (!mProc[idx].entryIdx(3 * i)) {
+ break;
+ }
+ }
+ }
+ return true;
+}
+
+bool dAcOMushRoom_c::proc_c::create(
+ EGG::ResTIMG *pImg, u32 drawOpa, mAllocator_c *pAllocator, s32 idxNum, mVec3_c *pVtx, mVec3_c *pNrm, u16 *pVtxIdx,
+ u16 *pNrmIdx
+) {
+ if (!m3d::proc_c::create(pAllocator, nullptr)) {
+ return false;
+ }
+
+ mpIdxArr = new (pAllocator->getHeap()) u16[idxNum];
+ if (mpIdxArr == nullptr) {
+ remove();
+ return false;
+ }
+
+ mpVtxArr = pVtx;
+ mpNrmArr = pNrm;
+ mpVtxIdxArr = pVtxIdx;
+ mpNrmIdxArr = pNrmIdx;
+ mIdxNum = 0;
+ mIdxMax = idxNum;
+ mpImg = pImg;
+ setPriorityDraw(drawOpa, 0);
+ setOption(nw4r::g3d::ScnObj::OPTION_DISABLE_DRAW_XLU, true);
+ return true;
+}
+
+bool dAcOMushRoom_c::proc_c::entryIdx(u16 idx) {
+ if (mIdxNum > mIdxMax) {
+ return false;
+ }
+
+ mpIdxArr[mIdxNum] = idx;
+ mIdxNum++;
+ return true;
+}
+
+void dAcOMushRoom_c::proc_c::clearIdx() {
+ mIdxNum = 0;
+}
+
+void dAcOMushRoom_c::proc_c::drawOpa() {
+ EGG::LightManager *pLightMgr = m3d::getLightMgr(0);
+ EGG::LightTexture *pLightTexture = pLightMgr->GetTextureMgr()->getTextureByName("LmBGMulti");
+ pLightTexture->load(GX_TEXMAP1);
+ EGG::DrawGX::LoadTexture(mpImg, GX_TEXMAP0);
+
+ u32 pDiffColorMask;
+ u32 pDiffAlphaMask;
+ u32 pSpecColorMask;
+ u32 pSpecAlphaMask;
+ GXColor pColor;
+ pLightMgr->LoadLightSet(1, &pDiffColorMask, &pDiffAlphaMask, &pSpecColorMask, &pSpecAlphaMask, &pColor);
+ m3d::getFogMgr(0);
+ nw4r::g3d::G3DState::LoadFog(0);
+ GXSetTevColor(GX_TEVREG0, (GXColor){0, 0, 0, mTev0Alpha});
+
+ m3d::resetMaterial();
+ GXSetNumChans(1);
+ GXSetChanCtrl(GX_COLOR0, GX_TRUE, GX_SRC_REG, GX_SRC_REG, (GXLightID)pDiffColorMask, GX_DF_CLAMP, GX_AF_SPOT);
+ GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
+ GXSetChanAmbColor(GX_COLOR0, pColor);
+ GXSetChanMatColor(GX_COLOR0, mColor(0xFFFFFFFF));
+ GXSetNumTexGens(2);
+ GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0, GX_FALSE, GX_DUALMTX0);
+ GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX3x4, GX_TG_NRM, GX_TEXMTX1, GX_TRUE, GX_DUALMTX1);
+ GXSetNumTevStages(2);
+ GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
+ GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC);
+ GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
+ GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_A0, GX_CA_ZERO);
+ GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
+ GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL);
+ GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO);
+ GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
+ GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV);
+ GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
+ GXSetZCompLoc(GX_TRUE);
+ GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
+ GXSetZMode(true, GX_LEQUAL, false);
+ GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0);
+ GXSetCullMode(GX_CULL_BACK);
+ GXClearVtxDesc();
+ GXSetVtxDesc(GX_VA_POS, GX_INDEX16);
+ GXSetVtxDesc(GX_VA_NRM, GX_INDEX16);
+ GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
+ GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_POS_XY, GX_F32, 0);
+
+ GXSetArray(GX_VA_POS, mpVtxArr, sizeof(*mpVtxArr));
+ GXSetArray(GX_VA_NRM, mpNrmArr, sizeof(*mpNrmArr));
+
+ mMtx_c view;
+ getViewMtx(view);
+ GXLoadPosMtxImm(view, GX_PNMTX0);
+ GXSetCurrentMtx(GX_PNMTX0);
+ view.inverseTransposeTo(view);
+ GXLoadNrmMtxImm(view, GX_PNMTX0);
+
+ mMtx_c tex;
+ nw4r::g3d::Camera cam = m3d::getCurrentCamera();
+ cam.GetEnvironmentTexMtx(tex);
+ GXLoadTexMtxImm(view, GX_TEXMTX1, GX_MTX3x4);
+ GXLoadTexMtxImm(tex, GX_DUALMTX1, GX_MTX3x4);
+ mMtx_c m = fn_328_830(mCameraIdx, mCameraSubIdx);
+ mMtx_c ident;
+ MTXIdentity(ident);
+ ident.concat(m);
+
+ mMtx_c texMtx;
+
+ nw4r::g3d::TexSrt srt;
+ srt.Su = 2.0f;
+ srt.Sv = 20.0f;
+ srt.R = 0.0f;
+ srt.Tu = 0.0f;
+ srt.Tv = 0.0f;
+
+ nw4r::g3d::CalcTexMtx(
+ texMtx, true, srt,
+ nw4r::g3d::TexSrt::Flag(
+ nw4r::g3d::TexSrt::FLAG_ANM_EXISTS | nw4r::g3d::TexSrt::FLAG_ROT_ZERO | nw4r::g3d::TexSrt::FLAG_TRANS_ZERO
+ ),
+ nw4r::g3d::TexSrt::TEXMATRIXMODE_3DSMAX
+ );
+ f32 xz = texMtx.m[0][2];
+ texMtx.m[0][2] = texMtx.m[0][3];
+ texMtx.m[0][3] = xz;
+ f32 yz = texMtx.m[1][2];
+ texMtx.m[1][2] = texMtx.m[1][3];
+ texMtx.m[1][3] = yz;
+ texMtx.concat(ident);
+ view = *reinterpret_cast<const mMtx_c *>(getLocalMtx());
+ GXLoadTexMtxImm(view, GX_TEXMTX0, GX_MTX3x4);
+ GXLoadTexMtxImm(texMtx, GX_DUALMTX0, GX_MTX3x4);
+ draw();
+}
+
+void dAcOMushRoom_c::proc_c::draw() {
+ GXBegin(GX_TRIANGLES, GX_VTXFMT0, mIdxNum * 3);
+ for (int i = 0; i < mIdxNum; ++i) {
+ u16 *pVtxIdx = mpVtxIdxArr + mpIdxArr[i];
+ u16 *pNrmIdx = mpNrmIdxArr + mpIdxArr[i];
+
+ u16 vx = *pVtxIdx++;
+ u16 vy = *pVtxIdx++;
+ u16 vz = *pVtxIdx++;
+ u16 nx = *pNrmIdx++;
+ u16 ny = *pNrmIdx++;
+ u16 nz = *pNrmIdx++;
+
+ GXPosition1x16(vx);
+ GXNormal1x16(nx);
+ GXPosition1x16(vy);
+ GXNormal1x16(ny);
+ GXPosition1x16(vz);
+ GXNormal1x16(nz);
+ }
+ GXEnd();
+}
+
+void dAcOMushRoom_c::updateCameras() {
+ mMtx_c m0 = mWorldMtx;
+ mMtx_c m1;
+ m1.ZXYrotS(mRotation);
+ m1.inverse();
+ m0.concat(m1);
+ for (int i = 0; i < 3; ++i) {
+ camera_c *mushCam = sCameras + mCameraIdx;
+ mProc[i].mTev0Alpha = mProcAlpha[i];
+ mushCam->mAlpha[i] = mProcAlpha[i];
+ if (mProcAlpha[i] == 0) {
+ mushCam->mCam[i].mPos = mVec3_c::Ez;
+ mushCam->mCam[i].mAt = mVec3_c::Zero;
+ mushCam->mCam[i].mUp = mVec3_c::Ey;
+ mushCam->mCam[i].EGG::LookAtCamera::doUpdateMatrix();
+ } else {
+ mVec3_c pos = field_0x7C4[i];
+ mVec3_c at = field_0x7E8[i];
+ mVec3_c up = field_0x80C[i];
+
+ pos -= mPosition;
+ at -= mPosition;
+ if (field_0x83C[i] == 1) {
+ pos.y += 100.0f;
+ at.y += (mScale.x + field_0x7BC) * 100.0f;
+ } else {
+ pos.y += 200.0f;
+ at.y += (mScale.x + field_0x7BC) * 100.0f;
+ }
+ m0.multVecSR(pos);
+ m0.multVecSR(up);
+ m0.multVecSR(at);
+ pos += mPosition;
+ at += mPosition;
+
+ mushCam->mCam[i].mPos = pos;
+ mushCam->mCam[i].mAt = at;
+ mushCam->mCam[i].mUp = up;
+ mushCam->mCam[i].EGG::LookAtCamera::doUpdateMatrix();
+ }
+ }
+}
+bool dAcOMushRoom_c::fn_328_4B20(const mMtx_c &m, const mVec3_c &vIn, f32 zHi, f32 zLo) {
+ f32 tempx = 200.0f;
+ f32 x = tempx * 0.5f;
+
+ f32 tempy = 100.0f;
+ f32 y = tempy * 0.5f;
+
+ mVec3_c v;
+ m.multVec(vIn, v);
+ if (v.x > x) {
+ return false;
+ }
+ if (v.x < -x) {
+ return false;
+ }
+ if (v.y > y) {
+ return false;
+ }
+ if (v.y < -y) {
+ return false;
+ }
+ if (v.z > zHi) {
+ return false;
+ }
+ if (v.z < zLo) {
+ return false;
+ }
+ return true;
+}
+
+// NONMATCHING - I dont feel like dealing with this one lol
+bool dAcOMushRoom_c::fn_328_4C30(const f32 &radius, const s16 &angle, cCcD_Obj *ccObj, const f32 &yHi, const f32 &yLo) {
+ if (ccObj != nullptr && ccObj->ChkTgHit() && ccObj->ChkTgAtHitType(AT_TYPE_BUBBLE)) {
+ dAcPy_c *pPlayer = dAcPy_c::GetLinkM();
+ f32 yDiff = pPlayer->mPosition.y - mPosition.y;
+ f32 rad = radius + 40.f;
+
+ if ((yLo < yDiff && yDiff < yHi) && mPosition.squareDistanceToXZ(pPlayer->mPosition) < rad * rad &&
+ labs(mAng::fromVec(mPosition - pPlayer->mPosition) - pPlayer->mAngle.y) < angle) {
+ pPlayer->onFlags_0x360(1);
+ return true;
+ }
+ }
+
+ return false;
+}
+void dAcOMushRoom_c::setLighting() {
+ mLightInfluence.mPos = mPositionCopy3;
+ mLightInfluence.mClr.Set(0xC, 0x4F, 0x38, 0xFF);
+ mLightInfluence.mScale = 0.0f;
+ mLightInfluence.field_0x18 = 0;
+ dLightEnv_c::GetPInstance()->plight_set(&mLightInfluence);
+
+ mShadowInfluence.mPos = mPositionCopy3;
+ mShadowInfluence.mPos.y += 250.0f;
+ mShadowInfluence.mRadius = 400.0f;
+ dLightEnv_c::GetPInstance()->shadow_set(&mShadowInfluence);
+}
+
+void dAcOMushRoom_c::cutLighting() {
+ dLightEnv_c::GetPInstance()->plight_cut(&mLightInfluence);
+ dLightEnv_c::GetPInstance()->shadow_cut(&mShadowInfluence);
+}
+
+void dAcOMushRoom_c::fn_328_4EF0() {
+ if (field_0x888 > 0) {
+ field_0x888--;
+ mLightInfluence.mScale = 0.0f;
+ } else {
+ if (field_0x890 != 0) {
+ if (field_0x88C > 0) {
+ field_0x88C--;
+ }
+ if (field_0x88C == 0) {
+ field_0x890--;
+ field_0x888 = 2 + cM::rndInt(10);
+ }
+ }
+ mLightInfluence.mScale = mScale.x * 300.0f;
+ mLightInfluence.mPos = mPosition;
+ }
+}
+
+bool dAcOMushRoom_c::checkUnderWater() {
+ if (!dBgS_WtrChk::CheckPos(&mPosition, true, 200.0f, 0.0f) ||
+ mPosition.y + mScale.y * 100.0f > dBgS_WtrChk::GetWaterHeight()) {
+ return false;
+ }
+ return true;
+}
diff --git a/src/d/col/c/c_m3d.cpp b/src/d/col/c/c_m3d.cpp
index 4ac33b5a..27d79d52 100644
--- a/src/d/col/c/c_m3d.cpp
+++ b/src/d/col/c/c_m3d.cpp
@@ -12,9 +12,11 @@
#include "egg/math/eggMath.h"
#include "m/m_vec.h"
#include "nw4r/math/math_types.h"
-#include "rvl/MTX.h" // IWYU pragma: export
#include "rvl/MTX/vec.h"
+#include "rvl/MTX.h" // IWYU pragma: export
+
+
using namespace nw4r::math;
using namespace EGG;
@@ -141,7 +143,7 @@ bool cM3d_Cross_LinSph(const cM3dGLin *, const cM3dGSph *, VEC3 *) {
// TODO - returns false to satisfy warning
return false;
}
-bool cM3d_Cross_LinSph_CrossPos(const cM3dGSph &, const cM3dGLin &, VEC3 *, VEC3 *) {
+BOOL cM3d_Cross_LinSph_CrossPos(const cM3dGSph &, const cM3dGLin &, VEC3 *, VEC3 *) {
// TODO - returns false to satisfy warning
return false;
}