rename EffectsStruct -> dEmitter_c

This commit is contained in:
robojumper
2025-09-27 15:25:37 +02:00
parent 532e06a35a
commit ab5be7e133
36 changed files with 153 additions and 151 deletions
+1 -1
View File
@@ -1334,7 +1334,7 @@ void dAcEsm_c::fn_187_61B0(u8 param0) {
MTXScale(mtx_scale, mScaleTarget.x, mScaleTarget.y, mScaleTarget.z);
mtx_trans += mtx_scale;
if (mEffArr[0].createEffect(sEmitterResArr[3], mtx_trans, &clr1, &clr2)) {
if (mEffArr[0].startEffect(sEmitterResArr[3], mtx_trans, &clr1, &clr2)) {
if (checkSize(SM_LARGE)) {
mEffArr[0].setRate(12.0f);
scale.set(1.7f, 1.7f, 1.7f);
+2 -2
View File
@@ -190,7 +190,7 @@ int dAcODungeonShip_c::actorExecute() {
mAnmMatClr.play();
mMdl.calc(false);
if (field_0x8D8) {
mEffects[0].createContinuousEffect(
mEffects[0].holdEffect(
PARTICLE_RESOURCE_ID_MAPPING_682_, mPosition, &mRotation, nullptr, nullptr, nullptr
);
}
@@ -201,7 +201,7 @@ int dAcODungeonShip_c::actorExecute() {
if (mEffects[1].hasEmitters()) {
mEffects[1].setTransform(tmpMtx);
} else if (field_0x8DA == 0) {
mEffects[1].createEffect(PARTICLE_RESOURCE_ID_MAPPING_683_, tmpMtx, nullptr, nullptr);
mEffects[1].startEffect(PARTICLE_RESOURCE_ID_MAPPING_683_, tmpMtx, nullptr, nullptr);
field_0x8DA = 1;
}
}
+1 -1
View File
@@ -228,7 +228,7 @@ void dAcOSeatSword_c::actorExecuteCommon() {
mEffPos += player->mPosition;
mEffPos.y = mPosition.y;
mEff.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_76_, mEffPos, &mRotation, &mScale, nullptr, nullptr);
mEff.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_76_, mEffPos, &mRotation, &mScale, nullptr, nullptr);
mEff.setGlobalAlpha(field_0x7E4);
}
+1 -1
View File
@@ -128,7 +128,7 @@ void dAcOTowerGearD101_c::initTransform() {
}
void dAcOTowerGearD101_c::playVisualEffect() {
mEffects.createContinuousEffect(
mEffects.holdEffect(
PARTICLE_RESOURCE_ID_MAPPING_572_, field_0x3F4, &mRotation, nullptr, nullptr, nullptr
);
}
+1 -1
View File
@@ -597,7 +597,7 @@ void dAcOTowerHandD101_c::finalizeState_RemainOpen() {}
void dAcOTowerHandD101_c::initializeState_Close() {
mMdl.getAnm().setPlayState(m3d::PLAY_MODE_1);
mMdl.setRate(getCloseRate());
mEffects.createEffect(PARTICLE_RESOURCE_ID_MAPPING_573_, mPosition, nullptr, nullptr, nullptr, nullptr);
mEffects.startEffect(PARTICLE_RESOURCE_ID_MAPPING_573_, mPosition, nullptr, nullptr, nullptr, nullptr);
startSound(SE_TowerHa_CLENCH);
}
void dAcOTowerHandD101_c::executeState_Close() {
+1 -1
View File
@@ -72,7 +72,7 @@ int dAcOtriforce_c::actorExecute() {
PSMTXConcat(mWorldMtx.m, m, mWorldMtx.m);
mMdl.setLocalMtx(mWorldMtx);
mAnm.play();
mEffects.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_967_, mWorldMtx, nullptr, nullptr);
mEffects.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_967_, mWorldMtx, nullptr, nullptr);
return 1;
}
+2 -2
View File
@@ -57,7 +57,7 @@ int dAcOwarpHole_c::actorExecute() {
dCcS::GetInstance()->Set(&mCcCyl);
updateMatrix();
mEff.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_914_, mWorldMtx, nullptr, nullptr);
mEff.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_914_, mWorldMtx, nullptr, nullptr);
holdSound(SE_WarpH_Wait);
return SUCCEEDED;
@@ -70,7 +70,7 @@ inline static void vecCylCalc(mVec3_c &target, const mAng &rot, f32 factor) {
}
int dAcOwarpHole_c::actorExecuteInEvent() {
mEff.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_914_, mWorldMtx, nullptr, nullptr);
mEff.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_914_, mWorldMtx, nullptr, nullptr);
holdSound(SE_WarpH_Wait);
int retVal = NOT_READY;
bool advance = mEvent.isAdvance();
+3 -3
View File
@@ -532,7 +532,7 @@ int dAcBoomerang_c::actorExecute() {
mPositionCopy3 = mPositionCopy2;
if (checkField_0x8CC(FLAG_WING_EFFECT_ACTIVE)) {
mEff0.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_6_, mWorldMtx, nullptr, nullptr);
mEff0.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_6_, mWorldMtx, nullptr, nullptr);
mEff1.setTransform(mWorldMtx);
f32 ang = field_0x8E4.angle(mVelocity);
@@ -544,7 +544,7 @@ int dAcBoomerang_c::actorExecute() {
}
if (field_0x8B1 == 0 && (mStateMgr.isState(StateID_Move) || mStateMgr.isState(StateID_MoveCancelWait))) {
mEff2.createContinuousEffect(
mEff2.holdEffect(
PARTICLE_RESOURCE_ID_MAPPING_5_, player->getPosition(), nullptr, nullptr, nullptr, nullptr
);
} else {
@@ -553,7 +553,7 @@ int dAcBoomerang_c::actorExecute() {
if (checkField_0x8CC(FLAG_0x20) && !checkField_0x8CC(FLAG_CANCEL)) {
if (mStateMgr.isState(StateID_Move) || mStateMgr.isState(StateID_MoveCancelWait)) {
mEff3.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_7_, mWorldMtx, nullptr, nullptr);
mEff3.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_7_, mWorldMtx, nullptr, nullptr);
holdSound(SE_BE_HIT_LEAVES_LV);
}
}
+2 -2
View File
@@ -213,7 +213,7 @@ int dAcOFairy_c::actorExecute() {
}
if (!field_0xB89) {
mEffects[0].createContinuousEffect(
mEffects[0].holdEffect(
PARTICLE_RESOURCE_ID_MAPPING_331_, mPosition, nullptr, nullptr, nullptr, nullptr
);
if (!isCuring() && !dAcPy_c::GetLink()->checkActionFlagsCont(0x400000)) {
@@ -240,7 +240,7 @@ int dAcOFairy_c::actorExecute() {
}
if (isCuring() && !field_0xB89) {
mEffects[1].createContinuousEffect(
mEffects[1].holdEffect(
PARTICLE_RESOURCE_ID_MAPPING_327_, mPosition, nullptr, nullptr, nullptr, nullptr
);
}
+3 -3
View File
@@ -633,7 +633,7 @@ bool dCsGame_c::lytItemCursor_c::execute() {
f32 sqDist = mPositionThisFrame.squareDistance(mPositionLastFrame);
if (sqDist > sHio.field_0x34 * sHio.field_0x34 ||
(mEffects.hasEmitters() && sqDist > sHio.field_0x38 * sHio.field_0x38)) {
mEffects.createContinuousUIEffect(
mEffects.holdUIEffect(
PARTICLE_RESOURCE_ID_MAPPING_31_, mPositionThisFrame, nullptr, nullptr, nullptr, nullptr
);
}
@@ -770,10 +770,10 @@ void dCsGame_c::lytItemCursor_c::lytDowsingCsr_c::updateEffects() {
mVec2_c csPos = dPad::getDpdPosScreen();
mVec3_c effectPos(csPos.x, csPos.y, 0.0f);
mVec3_c effectScale(sHio.field_0x3C, sHio.field_0x3C, 1.0f);
mEffects1.createContinuousUIEffect(
mEffects1.holdUIEffect(
PARTICLE_RESOURCE_ID_MAPPING_725_, mVec3_c::Zero, nullptr, nullptr, nullptr, nullptr
);
mEffects2.createContinuousUIEffect(
mEffects2.holdUIEffect(
PARTICLE_RESOURCE_ID_MAPPING_726_, effectPos, &mAng3_c::Zero, &effectScale, nullptr, nullptr
);
mEffects1.setGlobalAlpha(alpha);
+1 -1
View File
@@ -2245,7 +2245,7 @@ void dLytMeterItemSelect_c::fn_800EF580() {
nw4r::math::MTX34 mtx = mpPanes[11]->GetGlobalMtx();
mVec3_c pos(mtx._03, mtx._13, 0.0f);
mVec3_c scale(mEffectScale, mEffectScale, mEffectScale);
mEffects.createContinuousUIEffect(PARTICLE_RESOURCE_ID_MAPPING_717_, pos, nullptr, &scale, nullptr, nullptr);
mEffects.holdUIEffect(PARTICLE_RESOURCE_ID_MAPPING_717_, pos, nullptr, &scale, nullptr, nullptr);
if (field_0x57C0 != 0) {
mEffects.stopDrawParticles();
+3 -3
View File
@@ -627,7 +627,7 @@ void dLytMeterMinusBtn_c::initializeState_DemoMove() {
nw4r::math::MTX34 mtx = mpPanes[i + MINUS_BTN_PANE_ITEM_OFFSET]->GetGlobalMtx();
mVec3_c pos(mtx._03, mtx._13, 0.0f);
mSlotForEffect[numPlayingEffects] = i;
mEffects[numPlayingEffects].createUIEffect(
mEffects[numPlayingEffects].startUIEffect(
PARTICLE_RESOURCE_ID_MAPPING_971_, pos, &mEffectsRot[numPlayingEffects], nullptr, nullptr, nullptr
);
numPlayingEffects++;
@@ -666,7 +666,7 @@ void dLytMeterMinusBtn_c::executeState_DemoMove() {
nw4r::math::MTX34 mtx = getPaneByIndex(mSlotToDemo + MINUS_BTN_PANE_ITEM_OFFSET)->GetGlobalMtx();
mVec3_c pos(mtx._03, mtx._13, 0.0f);
mSlotForEffect[0] = mSlotToDemo;
mEffects[0].createUIEffect(
mEffects[0].startUIEffect(
PARTICLE_RESOURCE_ID_MAPPING_971_, pos, &mEffectsRot[0], nullptr, nullptr, nullptr
);
}
@@ -825,7 +825,7 @@ bool dLytMeterMinusBtn_c::remove() {
mAnm[i].remove();
}
// Not removing our EffectsStructs I guess?
// Not removing our emitters I guess?
return true;
}
+5 -5
View File
@@ -327,7 +327,7 @@ bool LytMeterTimerPart1_c::incrementTearCount() {
if (mDisplayedTearCount < mActualTearCount && dLytDropLine_c::finishPartMaybe()) {
startNextFruitAnim();
if (!dLytMeter_c::getfn_800C9FE0()) {
createEffect(mActualTearCount - 1);
startEffect(mActualTearCount - 1);
dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SIREN_SHIZUKU_GET_IN);
}
@@ -382,7 +382,7 @@ void LytMeterTimerPart1_c::initColors() {
}
}
void LytMeterTimerPart1_c::createEffect(s32 fruitIndex) {
void LytMeterTimerPart1_c::startEffect(s32 fruitIndex) {
nw4r::math::MTX34 mtx = mpPanes[fruitIndex]->GetGlobalMtx();
mVec3_c pos;
pos.x = mtx._03;
@@ -1243,7 +1243,7 @@ void dLytMeterTimer_c::executeState_ChangeFruits() {
if (mpPart1->getField0x780() < TIMER_01_NUM_TEARS) {
mpPart1->updateDropLine(mpPart2->i_getPane());
mpPart1->startFruitAnim(fruit);
mpPart1->createEffect(fruit);
mpPart1->startEffect(fruit);
}
}
@@ -1458,7 +1458,7 @@ void dLytMeterTimer_c::gotoChangeFruits6() {
mpPart1->resetBowlNuts();
mpPart1->updateDropLine(mpPart2->i_getPane());
mpPart1->startFruitAnim(mpPart1->getField0x780());
mpPart1->createEffect(mpPart1->getField0x780());
mpPart1->startEffect(mpPart1->getField0x780());
field_0x54 = false;
field_0x56 = 6;
mStateMgr.changeState(StateID_ChangeFruits);
@@ -1506,7 +1506,7 @@ void dLytMeterTimer_c::doPickup() {
mpPart1->resetBowlNuts();
mpPart1->updateDropLine(mpPart2->i_getPane());
mpPart1->startFruitAnim(mpPart1->getField0x780());
mpPart1->createEffect(mpPart1->getField0x780());
mpPart1->startEffect(mpPart1->getField0x780());
field_0x56 = 6;
}
+46 -45
View File
@@ -316,17 +316,17 @@ void dEmitterBase_c::bindShpEmitter(s32 id, bool unused) {
}
}
EffectsStruct::EffectsStruct() : mpOwner(nullptr), mFlags(0), mEffect(0) {}
dEmitter_c::dEmitter_c() : mpOwner(nullptr), mFlags(0), mEffect(0) {}
EffectsStruct::EffectsStruct(dBase_c *base) : mpOwner(base), mFlags(0), mEffect(0) {}
dEmitter_c::dEmitter_c(dBase_c *base) : mpOwner(base), mFlags(0), mEffect(0) {}
EffectsStruct::~EffectsStruct() {
dEmitter_c::~dEmitter_c() {
mpOwner = nullptr;
remove(false);
}
void EffectsStruct::remove(bool bForceDeleteEmitters) {
offFlag(EMITTER_0x1);
void dEmitter_c::remove(bool bForceDeleteEmitters) {
offFlag(EMITTER_New);
JPABaseEmitter *emitter = bForceDeleteEmitters ? mpEmitterHead : nullptr;
deactivateEmitters();
for (; emitter != nullptr; emitter = GetNextEmitter(emitter)) {
@@ -335,21 +335,21 @@ void EffectsStruct::remove(bool bForceDeleteEmitters) {
removeFromActiveEmittersList();
}
void EffectsStruct::addToActiveEmittersList(u16 resourceId, bool bFlags) {
void dEmitter_c::addToActiveEmittersList(u16 resourceId, bool create) {
mEffect = resourceId;
mFlags = 0;
setImmortal();
dJEffManager_c::sPlayingEffectsList.append(this);
onFlag(EMITTER_0x1);
if (bFlags) {
onFlag(EMITTER_0x4);
onFlag(EMITTER_New);
if (create) {
onFlag(EMITTER_OneShot);
}
if (dParticle::mgr_c::GetInstance()->getResUserWork(resourceId) & 0x4000) {
onFlag(EMITTER_0x10);
}
}
bool EffectsStruct::areAllEmittersDone() {
bool dEmitter_c::areAllEmittersDone() {
bool allDone = true;
if (mpEmitterHead != nullptr) {
@@ -370,7 +370,7 @@ bool EffectsStruct::areAllEmittersDone() {
return allDone;
}
void EffectsStruct::execute() {
void dEmitter_c::execute() {
if (mpOwner != nullptr && (mpOwner->mDeleteRequest || mpOwner->mLifecycleState == fBase_c::TO_BE_DELETED)) {
mpOwner = nullptr;
}
@@ -389,7 +389,7 @@ void EffectsStruct::execute() {
}
}
}
onFlag(EMITTER_0x1);
onFlag(EMITTER_New);
} else {
playCalcEmitters();
if (checkFlag(EMITTER_0x20)) {
@@ -402,7 +402,7 @@ void EffectsStruct::execute() {
}
}
bool EffectsStruct::getOwnerPolyAttrs(s32 *pOut1, s32 *pOut2) {
bool dEmitter_c::getOwnerPolyAttrs(s32 *pOut1, s32 *pOut2) {
if (mpOwner != nullptr && mpOwner->mGroupType == fBase_c::ACTOR) {
dAcBase_c *actor = static_cast<dAcBase_c *>(mpOwner);
*pOut1 = actor->mPolyAttr0;
@@ -415,11 +415,11 @@ bool EffectsStruct::getOwnerPolyAttrs(s32 *pOut1, s32 *pOut2) {
}
}
void EffectsStruct::realizeAlpha() {
void dEmitter_c::realizeAlpha() {
setGlobalAlpha(mFadeTimer * (255.0f / mFadeDuration));
}
void EffectsStruct::setFading(u8 lifetime) {
void dEmitter_c::setFading(u8 lifetime) {
if (!checkFlag(EMITTER_Fading)) {
mFadeTimer = lifetime;
onFlag(EMITTER_Fading);
@@ -456,7 +456,6 @@ void dParticleFogProc_c::doDraw() {
dJEffManager_c::draw(&info, mIdx);
}
extern "C" bool fn_80054AD0();
void dEffect2D_c::draw() {
f32 proj[GX_PROJECTION_SZ];
GXGetProjectionv(proj);
@@ -470,7 +469,7 @@ void dEffect2D_c::draw() {
C_MTXLightOrtho(mtx1, -h, h, -f, f, 0.5f, 0.5f, 0.5f, 0.5f);
MTXScale(mtx2, fn_80054AD0() ? dGfx_c::get16x9to4x3WidthScaleF() : 1.0f, 1.0f, 1.0f);
MTXScale(mtx2, dGfx_c::isTvMode4To3() ? dGfx_c::get16x9to4x3WidthScaleF() : 1.0f, 1.0f, 1.0f);
MTXCopy(mtx2, info.mCamMtx);
MTXCopy(mtx1, info.mPrjMtx);
dJEffManager_c::draw(&info, mGroupId);
@@ -831,16 +830,18 @@ void dJEffManager_c::execute() {
EffectsList::Iterator itNext = it;
++itNext;
it->execute();
if (it->checkFlag(EffectsStruct::EMITTER_Fading)) {
if (it->checkFlag(dEmitter_c::EMITTER_Fading)) {
it->realizeAlpha();
}
if (it->checkFlag(EffectsStruct::EMITTER_0x1)) {
it->offFlag(EffectsStruct::EMITTER_0x1);
if (it->checkFlag(dEmitter_c::EMITTER_New)) {
// Make sure we don't remove an emitter that didn't even
// have a chance to spawn anything yet..
it->offFlag(dEmitter_c::EMITTER_New);
} else {
if (it->areAllEmittersDone()) {
it->remove(false);
} else {
it->onFlag(EffectsStruct::EMITTER_0x2);
it->onFlag(dEmitter_c::EMITTER_Active);
}
}
it = itNext;
@@ -972,40 +973,40 @@ dEmitterBase_c *dJEffManager_c::spawnEffect(
return spawnEffectInternal(effectResourceId, transform, c1, c2, idx1, idx2);
}
bool EffectsStruct::createEffect(
bool dEmitter_c::startEffect(
u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2
) {
return createEffect(true, resourceId, pos, rot, scale, c1, c2);
return setupEffect(true, resourceId, pos, rot, scale, c1, c2);
}
bool EffectsStruct::createUIEffect(
bool dEmitter_c::startUIEffect(
u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2
) {
mVec3_c adjustedPosition(pos.x * dGfx_c::getCurrentScreenTo4x3WidthScaleF(), pos.y, pos.z);
return createEffect(true, resourceId, adjustedPosition, rot, scale, c1, c2);
return setupEffect(true, resourceId, adjustedPosition, rot, scale, c1, c2);
}
bool EffectsStruct::createEffect(u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2) {
return createEffect(true, resourceId, transform, c1, c2);
bool dEmitter_c::startEffect(u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2) {
return setupEffect(true, resourceId, transform, c1, c2);
}
bool EffectsStruct::createContinuousEffect(
bool dEmitter_c::holdEffect(
u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2
) {
return createEffect(false, resourceId, pos, rot, scale, c1, c2);
return setupEffect(false, resourceId, pos, rot, scale, c1, c2);
}
bool EffectsStruct::createContinuousUIEffect(
bool dEmitter_c::holdUIEffect(
u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2
) {
mVec3_c adjustedPosition(pos.x * dGfx_c::getCurrentScreenTo4x3WidthScaleF(), pos.y, pos.z);
return createEffect(false, resourceId, adjustedPosition, rot, scale, c1, c2);
return setupEffect(false, resourceId, adjustedPosition, rot, scale, c1, c2);
}
bool EffectsStruct::createContinuousEffect(
bool dEmitter_c::holdEffect(
u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2
) {
return createEffect(false, resourceId, transform, c1, c2);
return setupEffect(false, resourceId, transform, c1, c2);
}
bool dJEffManager_c::createMassObjEffect(
@@ -1128,52 +1129,52 @@ void dEmitterBase_c::loadColors(
emitter->setGlobalEnvColor(r, g, b);
}
void EffectsStruct::removeFromActiveEmittersList() {
void dEmitter_c::removeFromActiveEmittersList() {
if (dJEffManager_c::sPlayingEffectsList.GetPosition(this) != dJEffManager_c::sPlayingEffectsList.GetEndIter()) {
dJEffManager_c::sPlayingEffectsList.remove(this);
}
}
bool EffectsStruct::createEffect(
bool bFlags, u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1,
bool dEmitter_c::setupEffect(
bool create, u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1,
const GXColor *c2
) {
if (!bFlags && canReuse(resourceId)) {
if (!create && canReuse(resourceId)) {
setPosRotScale(pos, rot, scale);
s32 idx1 = 0;
s32 idx2 = 0;
getOwnerPolyAttrs(&idx1, &idx2);
loadColors(c1, c2, idx1, idx2);
onFlag(EMITTER_0x1);
onFlag(EMITTER_New);
} else {
remove(false);
s32 idx1 = 0;
s32 idx2 = 0;
getOwnerPolyAttrs(&idx1, &idx2);
if (createEmitters(resourceId, pos, rot, scale, c1, c2, idx1, idx2)) {
addToActiveEmittersList(resourceId, bFlags);
addToActiveEmittersList(resourceId, create);
}
}
return hasEmitters();
}
bool EffectsStruct::createEffect(
bool bFlags, u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2
bool dEmitter_c::setupEffect(
bool create, u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2
) {
if (!bFlags && canReuse(resourceId)) {
if (!create && canReuse(resourceId)) {
s32 idx1 = 0;
s32 idx2 = 0;
getOwnerPolyAttrs(&idx1, &idx2);
loadColors(c1, c2, idx1, idx2);
onFlag(EMITTER_0x1);
onFlag(EMITTER_New);
} else {
remove(false);
s32 idx1 = 0;
s32 idx2 = 0;
getOwnerPolyAttrs(&idx1, &idx2);
if (createEmitters(resourceId, mVec3_c::Zero, nullptr, nullptr, c1, c2, idx1, idx2)) {
addToActiveEmittersList(resourceId, bFlags);
addToActiveEmittersList(resourceId, create);
}
}
setTransform(transform);
@@ -1271,7 +1272,7 @@ void dWaterEffect_c::execute(f32 water, f32 ground) {
// Spawn effect while in water
mVec3_c pos(ac->mPosition.x, water, ac->mPosition.z);
mVec3_c scale(mScale, mScale, mScale);
mEff.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_127_, pos, nullptr, &scale, nullptr, nullptr);
mEff.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_127_, pos, nullptr, &scale, nullptr, nullptr);
f32 rate = nw4r::math::FAbs(ac->mSpeed) * 0.02f;
rate = rate > 0.95f ? 0.95f : rate;
mEff.setRate(rate + 0.05f);