mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-23 09:04:21 +00:00
Library/Movement: Implement ClockMovement (#1053)
This commit is contained in:
parent
e815a23f5f
commit
b847fd4117
|
|
@ -264305,60 +264305,60 @@ Library/Movement/ClockMovement.o:
|
|||
label:
|
||||
- _ZN2al13ClockMovementC1ERKNS_13ActorInitInfoE
|
||||
- _ZN2al13ClockMovementC2ERKNS_13ActorInitInfoE
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952a1c
|
||||
size: 100
|
||||
label: _ZN2al13ClockMovement8exeDelayEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952a80
|
||||
size: 204
|
||||
label: _ZN2al13ClockMovement13exeRotateSignEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952b4c
|
||||
size: 156
|
||||
label: _ZN2al13ClockMovement9exeRotateEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952be8
|
||||
size: 96
|
||||
label: _ZN2al13ClockMovement7exeWaitEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952c48
|
||||
size: 64
|
||||
label: _ZNK2al13ClockMovement16isFirstStepDelayEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952c88
|
||||
size: 68
|
||||
label: _ZNK2al13ClockMovement21isFirstStepRotateSignEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952ccc
|
||||
size: 68
|
||||
label: _ZNK2al13ClockMovement17isFirstStepRotateEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952d10
|
||||
size: 64
|
||||
label: _ZNK2al13ClockMovement15isFirstStepWaitEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x952d50
|
||||
size: 36
|
||||
label: _ZN2al13ClockMovementD0Ev
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
lazy: true
|
||||
- offset: 0x952d74
|
||||
size: 104
|
||||
label: ''
|
||||
status: NotDecompiled
|
||||
label: _ZNK12_GLOBAL__N_121ClockMovementNrvDelay7executeEPN2al11NerveKeeperE
|
||||
status: Matching
|
||||
- offset: 0x952ddc
|
||||
size: 8
|
||||
label: ''
|
||||
status: NotDecompiled
|
||||
label: _ZNK12_GLOBAL__N_126ClockMovementNrvRotateSign7executeEPN2al11NerveKeeperE
|
||||
status: Matching
|
||||
- offset: 0x952de4
|
||||
size: 8
|
||||
label: ''
|
||||
status: NotDecompiled
|
||||
label: _ZNK12_GLOBAL__N_122ClockMovementNrvRotate7executeEPN2al11NerveKeeperE
|
||||
status: Matching
|
||||
- offset: 0x952dec
|
||||
size: 100
|
||||
label: ''
|
||||
status: NotDecompiled
|
||||
label: _ZNK12_GLOBAL__N_120ClockMovementNrvWait7executeEPN2al11NerveKeeperE
|
||||
status: Matching
|
||||
Library/Movement/EnemyStateBlowDown.o:
|
||||
'.text':
|
||||
- offset: 0x952e50
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ void ClockMapParts::exeRotate() {
|
|||
|
||||
mTimer++;
|
||||
if (mTimer >= mRotateTimer) {
|
||||
mCurrentStep = modi(mCurrentStep + mTurnStepCount + 1, mTurnStepCount);
|
||||
mCurrentStep = wrapValue(mCurrentStep + 1, mTurnStepCount);
|
||||
startNerveAction(this, "Wait");
|
||||
tryStartSe(this, "RotateEnd");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,6 +205,10 @@ void makeBoxMullerRandomGauss(sead::Vector2f* outBox, f32 randA, f32 randB);
|
|||
f32 modf(f32 a, f32 b);
|
||||
s32 modi(s32 a, s32 b);
|
||||
|
||||
inline s32 wrapValue(s32 value, s32 maxRange) {
|
||||
return modi(value + maxRange, maxRange);
|
||||
}
|
||||
|
||||
inline f32 wrapValue(f32 value, f32 maxRange) {
|
||||
return modf(value + maxRange, maxRange) + 0.0f;
|
||||
}
|
||||
|
|
|
|||
101
lib/al/Library/Movement/ClockMovement.cpp
Normal file
101
lib/al/Library/Movement/ClockMovement.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include "Library/Movement/ClockMovement.h"
|
||||
|
||||
#include "Library/Math/MathUtil.h"
|
||||
#include "Library/Nerve/NerveSetupUtil.h"
|
||||
#include "Library/Nerve/NerveUtil.h"
|
||||
#include "Library/Placement/PlacementFunction.h"
|
||||
|
||||
namespace {
|
||||
using namespace al;
|
||||
|
||||
NERVE_IMPL(ClockMovement, Delay);
|
||||
NERVE_IMPL(ClockMovement, RotateSign);
|
||||
NERVE_IMPL(ClockMovement, Rotate);
|
||||
NERVE_IMPL(ClockMovement, Wait);
|
||||
|
||||
NERVES_MAKE_STRUCT(ClockMovement, Delay, RotateSign, Rotate);
|
||||
NERVES_MAKE_NOSTRUCT(ClockMovement, Wait);
|
||||
} // namespace
|
||||
|
||||
namespace al {
|
||||
|
||||
ClockMovement::ClockMovement(const ActorInitInfo& info) : NerveExecutor("クロックパーツ動作") {
|
||||
getQuat(&mInitialQuat, info);
|
||||
mCurrentQuat = mInitialQuat;
|
||||
tryGetArg(&mClockAngleDegree, info, "ClockAngleDegree");
|
||||
tryGetArg(&mRotateAxis, info, "RotateAxis");
|
||||
tryGetArg(&mDelayTime, info, "DelayTime");
|
||||
tryGetArg(&mRotateSignTime, info, "RotateSignTime");
|
||||
tryGetArg(&mRotateTime, info, "RotateTime");
|
||||
tryGetArg(&mWaitTime, info, "WaitTime");
|
||||
|
||||
if (mDelayTime == 0)
|
||||
initNerve(&NrvClockMovement.RotateSign, 0);
|
||||
else
|
||||
initNerve(&NrvClockMovement.Delay, 0);
|
||||
|
||||
s32 stepsPerCycle = 1;
|
||||
if (mClockAngleDegree != 0) {
|
||||
stepsPerCycle = sead::Mathi::lcm(sead::Mathi::abs(mClockAngleDegree), 360) /
|
||||
sead::Mathi::abs(mClockAngleDegree);
|
||||
}
|
||||
mMaxStepIndex = stepsPerCycle;
|
||||
}
|
||||
|
||||
void ClockMovement::exeDelay() {
|
||||
if (isGreaterEqualStep(this, mDelayTime - 1)) {
|
||||
if (mRotateSignTime > 0)
|
||||
setNerve(this, &NrvClockMovement.RotateSign);
|
||||
else
|
||||
setNerve(this, &NrvClockMovement.Rotate);
|
||||
}
|
||||
}
|
||||
|
||||
void ClockMovement::exeRotateSign() {
|
||||
f32 rotateAngle = wrapValue(static_cast<f32>(mCurrentStepIndex * mClockAngleDegree), 360.0f);
|
||||
|
||||
rotateQuatLocalDirDegree(&mCurrentQuat, mInitialQuat, mRotateAxis,
|
||||
rotateAngle +
|
||||
sead::Mathf::sin(getNerveStep(this) * sead::Mathf::pi2() / 18.0f));
|
||||
|
||||
if (isGreaterEqualStep(this, mRotateSignTime - 1))
|
||||
setNerve(this, &NrvClockMovement.Rotate);
|
||||
}
|
||||
|
||||
void ClockMovement::exeRotate() {
|
||||
f32 rotateAngle = wrapValue(
|
||||
(calcNerveRate(this, mRotateTime) + mCurrentStepIndex) * mClockAngleDegree, 360.0f);
|
||||
rotateQuatLocalDirDegree(&mCurrentQuat, mInitialQuat, mRotateAxis, rotateAngle);
|
||||
|
||||
if (isGreaterEqualStep(this, mRotateTime)) {
|
||||
mCurrentStepIndex = wrapValue(mCurrentStepIndex + 1, mMaxStepIndex);
|
||||
setNerve(this, &Wait);
|
||||
}
|
||||
}
|
||||
|
||||
void ClockMovement::exeWait() {
|
||||
if (isGreaterEqualStep(this, mWaitTime)) {
|
||||
if (mRotateSignTime > 0)
|
||||
setNerve(this, &NrvClockMovement.RotateSign);
|
||||
else
|
||||
setNerve(this, &NrvClockMovement.Rotate);
|
||||
}
|
||||
}
|
||||
|
||||
bool ClockMovement::isFirstStepDelay() const {
|
||||
return isNerve(this, &NrvClockMovement.Delay) && isFirstStep(this);
|
||||
}
|
||||
|
||||
bool ClockMovement::isFirstStepRotateSign() const {
|
||||
return isNerve(this, &NrvClockMovement.RotateSign) && isFirstStep(this);
|
||||
}
|
||||
|
||||
bool ClockMovement::isFirstStepRotate() const {
|
||||
return isNerve(this, &NrvClockMovement.Rotate) && isFirstStep(this);
|
||||
}
|
||||
|
||||
bool ClockMovement::isFirstStepWait() const {
|
||||
return isNerve(this, &Wait) && isFirstStep(this);
|
||||
}
|
||||
|
||||
} // namespace al
|
||||
36
lib/al/Library/Movement/ClockMovement.h
Normal file
36
lib/al/Library/Movement/ClockMovement.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include <math/seadQuat.h>
|
||||
|
||||
#include "Library/Nerve/NerveExecutor.h"
|
||||
|
||||
namespace al {
|
||||
struct ActorInitInfo;
|
||||
|
||||
class ClockMovement : public NerveExecutor {
|
||||
public:
|
||||
ClockMovement(const ActorInitInfo& info);
|
||||
void exeDelay();
|
||||
void exeRotateSign();
|
||||
void exeRotate();
|
||||
void exeWait();
|
||||
bool isFirstStepDelay() const;
|
||||
bool isFirstStepRotateSign() const;
|
||||
bool isFirstStepRotate() const;
|
||||
bool isFirstStepWait() const;
|
||||
|
||||
private:
|
||||
sead::Quatf mCurrentQuat = sead::Quatf::unit;
|
||||
sead::Quatf mInitialQuat = sead::Quatf::unit;
|
||||
s32 mRotateAxis = 0;
|
||||
s32 mClockAngleDegree = 90;
|
||||
s32 mCurrentStepIndex = 0;
|
||||
s32 mMaxStepIndex = 4;
|
||||
s32 mDelayTime = 0;
|
||||
s32 mRotateSignTime = 36;
|
||||
s32 mRotateTime = 60;
|
||||
s32 mWaitTime = 0;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ClockMovement) == 0x50);
|
||||
} // namespace al
|
||||
|
|
@ -59,7 +59,7 @@ void SwingMovement::exeMove() {
|
|||
if (updateRotate())
|
||||
setNerve(this, &Stop);
|
||||
|
||||
mFrameInCycle = modi((mFrameInCycle + 1) + mSwingCycle, mSwingCycle);
|
||||
mFrameInCycle = wrapValue(mFrameInCycle + 1, mSwingCycle);
|
||||
}
|
||||
|
||||
void SwingMovement::exeStop() {
|
||||
|
|
|
|||
|
|
@ -323,11 +323,8 @@ s32 getNextRailPointNo(const IUseRail* railHolder) {
|
|||
s32 newIndex = getRailPointNo(railHolder) + modifier;
|
||||
s32 railPointNum = getRailPointNum(railHolder);
|
||||
|
||||
if (isLoop) {
|
||||
s32 sum = railPointNum + newIndex;
|
||||
s32 railPointNumAgain = getRailPointNum(railHolder);
|
||||
return modi(sum + railPointNumAgain, railPointNumAgain);
|
||||
}
|
||||
if (isLoop)
|
||||
return wrapValue(railPointNum + newIndex, getRailPointNum(railHolder));
|
||||
|
||||
return sead::Mathi::clamp2(0, newIndex, railPointNum - 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ void FlowMapCtrl::update() {
|
|||
flowParameters.y =
|
||||
calcRate01(halfInterval - sead::Mathi::abs(halfInterval - mFlowStep), 0.0f, halfInterval);
|
||||
flowParameters.z = calcRate01(mFlowStep, 0.0f, mInterval);
|
||||
flowParameters.w =
|
||||
calcRate01(modi(mFlowStep + halfInterval + mInterval, mInterval), 0.0f, mInterval);
|
||||
flowParameters.w = calcRate01(wrapValue(mFlowStep + halfInterval, mInterval), 0.0f, mInterval);
|
||||
|
||||
s32 materialCount = getMaterialCount(mParent);
|
||||
for (s32 i = 0; i < materialCount; i++) {
|
||||
|
|
@ -27,7 +26,7 @@ void FlowMapCtrl::update() {
|
|||
}
|
||||
|
||||
mFlowStep++;
|
||||
mFlowStep = modi(mFlowStep + mInterval, mInterval);
|
||||
mFlowStep = wrapValue(mFlowStep, mInterval);
|
||||
}
|
||||
|
||||
} // namespace al
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ void KoopaLandPointHolder::decidePointEitherFarSide(const sead::Vector3f& pos) {
|
|||
}
|
||||
|
||||
mInvalidPoints[mCurrentLandPoint] = false;
|
||||
s32 prevPoint = al::modi(mCurrentLandPoint - 1 + mLandPoints, mLandPoints);
|
||||
s32 nextPoint = al::modi(mCurrentLandPoint + 1 + mLandPoints, mLandPoints);
|
||||
s32 prevPoint = al::wrapValue(mCurrentLandPoint - 1, mLandPoints);
|
||||
s32 nextPoint = al::wrapValue(mCurrentLandPoint + 1, mLandPoints);
|
||||
|
||||
f32 prevDist = getKoopaLandPointDistance(mPointsTrans[prevPoint], pos);
|
||||
f32 nextDist = getKoopaLandPointDistance(mPointsTrans[nextPoint], pos);
|
||||
|
|
|
|||
|
|
@ -638,7 +638,8 @@ void Bubble::control() {
|
|||
if (!al::isNerve(this, &NrvBubble.StandBy) && !al::isNerve(this, &NrvBubble.Delay) &&
|
||||
(!isHack() || !rs::isActiveHackStartDemo(mPlayerHack)) &&
|
||||
!al::isClipped(mClippingProbeActor) && !mIsClipped) {
|
||||
mReviveDelayCount = al::modi(mReviveDelayCount + 1 + mReviveDelayTime, mReviveDelayTime);
|
||||
mReviveDelayCount =
|
||||
al::wrapValue(static_cast<s32>(mReviveDelayCount + 1), mReviveDelayTime);
|
||||
}
|
||||
|
||||
mIsClipped = al::isClipped(mClippingProbeActor);
|
||||
|
|
|
|||
|
|
@ -505,7 +505,8 @@ void Gamane::exeHack() {
|
|||
mCoinsLeft--;
|
||||
}
|
||||
|
||||
mHackCoinAppearCounter = al::modi((mHackCoinAppearCounter++ + 1) + 6, 6);
|
||||
// NOTE: this is only one increment, as post-incrementing is used
|
||||
mHackCoinAppearCounter = al::wrapValue(mHackCoinAppearCounter++ + 1, 6);
|
||||
}
|
||||
|
||||
void Gamane::exeTrampled() {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ HosuiTrailKeeper::HosuiTrailKeeper(const al::ActorInitInfo& initInfo) {
|
|||
void HosuiTrailKeeper::appearTrail(const sead::Vector3f& pos, const sead::Vector3f& dir) {
|
||||
s32 count = mTrails.size();
|
||||
|
||||
s32 prevIdx = al::modi(mIndex + count - 1 + count, count);
|
||||
s32 prevIdx = al::wrapValue(mIndex + count - 1, count);
|
||||
HosuiTrail* prevTrail = mTrails[prevIdx];
|
||||
|
||||
if (al::isAlive(prevTrail) && (pos - al::getTrans(prevTrail)).length() < 120.0f)
|
||||
|
|
@ -56,12 +56,12 @@ void HosuiTrailKeeper::appearTrail(const sead::Vector3f& pos, const sead::Vector
|
|||
trail->setFollowCollisionParts(triangle.getCollisionParts());
|
||||
}
|
||||
|
||||
s32 disappearIdx = al::modi(mIndex + 5 + count, count);
|
||||
s32 disappearIdx = al::wrapValue(mIndex + 5, count);
|
||||
HosuiTrail* disappearTrail = mTrails[disappearIdx];
|
||||
if (al::isAlive(disappearTrail))
|
||||
disappearTrail->disappear();
|
||||
|
||||
mIndex = al::modi(mIndex + 1 + count, count);
|
||||
mIndex = al::wrapValue(mIndex + 1, count);
|
||||
}
|
||||
|
||||
void HosuiTrailKeeper::forceKillAll() {
|
||||
|
|
|
|||
|
|
@ -243,8 +243,7 @@ void MenuSelectParts::exeSelect() {
|
|||
s32 direction = mKeyRepeatCtrl->isUp() ? -1 : 1;
|
||||
|
||||
al::startAction(mLayoutArray[calcPartsIndex(mCursorItemIndex)], "Wait");
|
||||
mCursorItemIndex =
|
||||
al::modi(mCursorItemIndex + direction + mMenuItemAmount, mMenuItemAmount);
|
||||
mCursorItemIndex = al::wrapValue(mCursorItemIndex + direction, mMenuItemAmount);
|
||||
|
||||
f32 pitch = ((1.0f - (f32)mCursorItemIndex / (mMenuItemAmount - 1)) * 0.375f) + 1.0f;
|
||||
al::PadRumbleParam param;
|
||||
|
|
|
|||
|
|
@ -161,15 +161,15 @@ void WindowConfirmData::exeWait() {
|
|||
|
||||
if (rs::isRepeatUiDown(mWindowConfirmLayout)) {
|
||||
if (mSelectionCooldown == 0)
|
||||
changeSelectingIdx(al::modi((mSelectionIndex + 1) + 2, 2));
|
||||
mSelectionCooldown = al::modi((mSelectionCooldown + 1) + 10, 10);
|
||||
changeSelectingIdx(al::wrapValue(mSelectionIndex + 1, 2));
|
||||
mSelectionCooldown = al::wrapValue(mSelectionCooldown + 1, 10);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rs::isRepeatUiUp(mWindowConfirmLayout)) {
|
||||
if (mSelectionCooldown == 0)
|
||||
changeSelectingIdx(al::modi((mSelectionIndex - 1) + 2, 2));
|
||||
mSelectionCooldown = al::modi((mSelectionCooldown + 1) + 10, 10);
|
||||
changeSelectingIdx(al::wrapValue(mSelectionIndex - 1, 2));
|
||||
mSelectionCooldown = al::wrapValue(mSelectionCooldown + 1, 10);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,18 +82,18 @@ void SmallBirdStateFlyAway::exeFlyAway() {
|
|||
mIsColliding = false;
|
||||
startActionAtRandomFrameIfNotPlaying(mActor, "Fly");
|
||||
if (rs::isModeE3MovieRom()) {
|
||||
gVerticalAccelIndex = al::modi(gVerticalAccelIndex + 7, 6);
|
||||
gVerticalAccelIndex = al::wrapValue(gVerticalAccelIndex + 1, 6);
|
||||
mVerticalAccel = gE3MovieVerticalAccel[gVerticalAccelIndex];
|
||||
gHorizontalAccelIndex = al::modi(gHorizontalAccelIndex + 5, 4);
|
||||
gHorizontalAccelIndex = al::wrapValue(gHorizontalAccelIndex + 1, 4);
|
||||
mHorizontalAccel = gE3MovieHorizontalAccel[gHorizontalAccelIndex];
|
||||
} else {
|
||||
gVerticalAccelIndex = al::modi(gVerticalAccelIndex + 5, 4);
|
||||
gVerticalAccelIndex = al::wrapValue(gVerticalAccelIndex + 1, 4);
|
||||
mVerticalAccel = gVerticalAccel[gVerticalAccelIndex];
|
||||
mHorizontalAccel = gHorizontalAccel;
|
||||
}
|
||||
mTargetAccelDir = {0, mVerticalAccel, mHorizontalAccel};
|
||||
al::normalize(&mTargetAccelDir);
|
||||
gCollisionCheckOffsetStep = al::modi(gCollisionCheckOffsetStep + 11, 10);
|
||||
gCollisionCheckOffsetStep = al::wrapValue(gCollisionCheckOffsetStep + 1, 10);
|
||||
mCollisionCheckOffsetStep = gCollisionCheckOffsetStep;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue