1#include "Item/CoinRotateCalculator.h"
2
3#include "Library/LiveActor/LiveActor.h"
4#include "Library/Math/MathUtil.h"
5#include "Library/Nature/NatureUtil.h"
6#include "Library/Scene/SceneObjUtil.h"
7#include "Library/Stage/StageRhythm.h"
8
9CoinRotateCalculator::CoinRotateCalculator(al::LiveActor* actor) : mActor(actor) {}
10
11inline f32 modDegree(f32 value) {
12 return al::modf(a: value + 360.0f, b: 360.0f) + 0.0f;
13}
14
15inline f32 getObjAngle(al::LiveActor* actor, bool isInWater, s32 objCountOffset) {
16 al::StageSyncCounter* syncObj = al::getSceneObj<al::StageSyncCounter>(user: actor);
17 f32 objCounter = modDegree(value: syncObj->getCounter() + objCountOffset);
18
19 return (isInWater ? 2.0f : 3.0f) * objCounter;
20}
21
22void CoinRotateCalculator::reset() {
23 mIsInWater = al::isInWater(mActor);
24 mRotate = getObjAngle(actor: mActor, isInWater: mIsInWater, objCountOffset: mObjCountOffset);
25 mLastObjAngle = mRotate;
26 mForceFrames = 0;
27 mForceOffset = 0.0f;
28 mFishingLineOffset = 0.0f;
29 mRotateOffset = 0.0f;
30}
31
32void CoinRotateCalculator::update(const sead::Vector3f& force, bool checkWater) {
33 if (checkWater)
34 mIsInWater = al::isInWater(mActor);
35
36 f32 objAngle = getObjAngle(actor: mActor, isInWater: mIsInWater, objCountOffset: mObjCountOffset);
37
38 if (al::isNearZero(vec: force)) {
39 if (--mForceFrames <= 0) {
40 mForceOffset = modDegree(value: mForceOffset) - 0.8f;
41 if (mForceOffset < 0.0f)
42 mForceOffset = 0.0f;
43 } else {
44 mForceOffset += mForceFrames * 0.3f;
45 }
46 } else {
47 mForceFrames = sead::Mathi::clamp(value: mForceFrames + 1, low: 0, high: 120);
48 mForceOffset += mForceFrames * 0.3f;
49 }
50
51 mFishingLineOffset = sead::Mathf::clampMin(val: mFishingLineOffset - 0.8f, min_: 0.0f);
52
53 if (sead::Mathf::abs(x: modDegree(value: objAngle) - modDegree(value: mLastObjAngle)) > 5.0f)
54 objAngle = (mIsInWater ? 3.5f : 4.0f) + mLastObjAngle;
55
56 mRotate = objAngle + mForceOffset + mFishingLineOffset + mRotateOffset;
57 mLastObjAngle = objAngle;
58}
59
60void CoinRotateCalculator::addFishingLineTouch() {
61 mFishingLineOffset += 5;
62}
63
64f32 CoinRotateCalculator::getRotate() const {
65 return mRotate;
66}
67
68f32 CoinRotateCalculator::getRotateSpeed() const {
69 return al::isInWater(mActor) ? 2.0f : 3.0f;
70}
71