NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_a_obj_center2.cpp
1#include <game/bases/d_a_obj_center2.hpp>
3#include <game/bases/d_bg.hpp>
4#include <game/bases/d_center_save_mng.hpp>
5#include <game/bases/d_enemy.hpp>
6#include <game/bases/d_quake.hpp>
7#include <game/bases/d_switch_flag_mng.hpp>
9
10ACTOR_PROFILE(OBJ_CENTER2, daObjCenter2_c, 0);
11
12STATE_DEFINE(daObjCenter2_c, ReturnHome);
15
17 if (ACTOR_PARAM(RotateCoinSE)) {
18 dAudio::g_pSndObjMap->startSound(SE_OBJ_COIN_POP_UP, mPos, 0);
19 }
20}
21
23 mExecStopMask = 0;
24 mRotDir = ACTOR_PARAM(IsCCW);
25 mRotationID = ACTOR_PARAM(RotID);
26
27 if (!dCenterSaveMng_c::m_instance->center_check(&mPos, ACTOR_PARAM(RotID), &mHomeRotation)) {
28 mHomeRotation = l_EnMuki[mRotDir] * (ACTOR_PARAM(InitialRotation) * 0x1000) + 0xc000;
29 }
30
31 static const s16 l_RotSpeed[] = {
32 0x40, 0x80, 0xc0, 0x100, 0x20, 0x200, 0x400
33 };
34
35 u32 rotSpeedMode = ACTOR_PARAM(RotationSpeed);
36 if (rotSpeedMode >= ARRAY_SIZE(l_RotSpeed)) {
37 rotSpeedMode = 0;
38 }
39 mRotationSpeed = l_RotSpeed[rotSpeedMode];
40
41 mRotationMode = ACTOR_PARAM(RotationMode);
43 mZoomControl = ACTOR_PARAM(ZoomControl);
44
45 dBg_c::m_bg_p->m_900a5 = mZoomControl;
46 if (m_flag_keep[1] != 0 && dSwitchFlagMng_c::m_instance->mFlag & m_flagbit_keep) {
48 mAngle.z = mHomeRotation + l_EnMuki[mRotDir] * (ACTOR_PARAM(TargetRotationOffset) * 0x1000);
49 mStateMgr.changeState(StateID_GoAim);
50 return SUCCEEDED;
51 } else if (mRotationMode == MODE_PERMANENT) {
52 mRotDir ^= 1;
53 }
54 }
56 mStateMgr.changeState(StateID_ReturnHome);
57 } else if (mRotationMode == MODE_PERMANENT) {
58 mStateMgr.changeState(StateID_Move);
59 } else {
60 mStateMgr.changeState(StateID_GoAim);
61 }
62 return SUCCEEDED;
63}
64
66 if (!(mExecStop & BIT_FLAG(STAGE_ACTOR_ENEMY))) {
67 mCoinSoundReady = false;
68 mStateMgr.executeState();
69 }
70
71 if (mZoomControl != 0) {
72 float ang = std::fabs((float) mAngle.z / 0x4000);
73 if (ang >= 1.0f) {
74 ang = ang - 1.0f;
75 } else {
76 ang = 1.0f - ang;
77 }
78 ang = 1.0f - ang;
79 dBg_c::m_bg_p->mZoomRelated = 3;
80 dBg_c::m_bg_p->mZoomWeight = 1.0f - ang * ang * ang;
81 dBg_c::m_bg_p->setZoomPos(mPos);
82 }
83
84 return SUCCEEDED;
85}
86
88 return l_EnMuki[mRotDir] * (ACTOR_PARAM(InitialRotation) * 0x1000) + 0xc000;
89}
90
97
98void daObjCenter2_c::initializeState_ReturnHome() {
99 mCoinSoundReady = true;
100 mCoinSoundPlayed = false;
101 mRotDir = ACTOR_PARAM(IsCCW) ^ 1;
102 mAngDelta = mRotationSpeed * l_EnMuki[mRotDir];
104}
105
106void daObjCenter2_c::finalizeState_ReturnHome() {}
107
108void daObjCenter2_c::executeState_ReturnHome() {
109 if (dSwitchFlagMng_c::m_instance->mFlag & mEventMask) {
110 mStateMgr.changeState(StateID_GoAim);
111 return;
112 }
113
114 if (mAngle.z != mTargetRotation) {
115 mAngle.z += mAngDelta;
116 int deltaAbs = labs(mAngDelta);
117 short target = mTargetRotation;
118 if (abs(mAngle.z.mAngle - target) < deltaAbs) {
119 mAngle.z = target;
120 if (ACTOR_PARAM(RotateShock)) {
121 dQuake_c::m_instance->startShockAll(dQuake_c::TYPE_0, 3, 0, false);
122 }
123 }
124 }
125}
126
127void daObjCenter2_c::initializeState_GoAim() {
128 mCoinSoundReady = true;
129 mCoinSoundPlayed = false;
130 mRotDir = ACTOR_PARAM(IsCCW);
131 mAngDelta = mRotationSpeed * l_EnMuki[mRotDir];
133 mTargetRotation = mHomeRotation + l_EnMuki[mRotDir] * (ACTOR_PARAM(TargetRotationOffset) * 0x1000);
134 } else {
136 }
137}
138
139void daObjCenter2_c::finalizeState_GoAim() {}
140
141void daObjCenter2_c::executeState_GoAim() {
143 if ((dSwitchFlagMng_c::m_instance->mFlag & mEventMask) == 0) {
144 mStateMgr.changeState(StateID_ReturnHome);
145 return;
146 }
147 } else if (mAngle.z == mTargetRotation && dSwitchFlagMng_c::m_instance->mFlag & mEventMask) {
148 mHomeRotation += l_EnMuki[mRotDir] * (ACTOR_PARAM(TargetRotationOffset) * 0x1000);
149 // Restart the state to start another rotation.
150 mStateMgr.changeState(StateID_GoAim);
151 return;
152 }
153
154 if (mAngle.z != mTargetRotation) {
155 mAngle.z += mAngDelta;
156 int deltaAbs = labs(mAngDelta);
157 short target = mTargetRotation;
158 if (abs(mAngle.z.mAngle - target) < deltaAbs) {
159 mAngle.z = target;
161 if (ACTOR_PARAM(RotateShock)) {
162 dQuake_c::m_instance->startShockAll(dQuake_c::TYPE_0, 3, 0, false);
163 }
164 }
165 }
166}
167
168void daObjCenter2_c::initializeState_Move() {
169 if (mRotDir != DIR_LR_R) {
170 mAngDelta = -mRotationSpeed * 0x1000;
171 } else {
172 mAngDelta = mRotationSpeed * 0x1000;
173 }
174}
175
176void daObjCenter2_c::finalizeState_Move() {}
177
178void daObjCenter2_c::executeState_Move() {
179 int delta;
180 if (dSwitchFlagMng_c::m_instance->mFlag & mEventMask) {
181 delta = -mRotationSpeed * 0x1000;
182 } else {
183 delta = mRotationSpeed * 0x1000;
184 }
185 if (mRotDir != DIR_LR_R) {
186 delta = -delta;
187 }
188 int deltaAbs = labs(delta >> 7);
189 if (mAngDelta != delta) {
190 if (delta < 0) {
191 mAngDelta -= deltaAbs;
192 if (mAngDelta < delta) {
193 mAngDelta = delta;
194 }
195 } else {
196 mAngDelta += deltaAbs;
197 if (mAngDelta > delta) {
198 mAngDelta = delta;
199 }
200 }
201 }
202 mAngle.z += mAngDelta >> 12;
203}
sFStateMgr_c< dActorState_c, sStateMethodUsr_FI_c > mStateMgr
The state manager.
static u8 mExecStop
The actors for which the execute operation is currently disabled.
Definition d_actor.hpp:409
u8 mExecStopMask
The mask required to disable the execute operation for the actor.
Definition d_actor.hpp:376
static u8 m_flag_keep[2]
Temporary storage for the next created sprite actor's tracked event IDs. See mEventNums.
Definition d_actor.hpp:419
static u64 m_flagbit_keep
Temporary storage for the next created sprite actor's event mask. See mEventMask.
Definition d_actor.hpp:422
u64 mEventMask
The event mask, generated from mEventNums.
Definition d_actor.hpp:358
@ STAGE_ACTOR_ENEMY
An enemy actor.
Definition d_actor.hpp:49
mVec3_c mPos
The actor's position.
mAng3_c mAngle
The actor's rotation (for 2D actors).
void center_entry(const mVec3_c *pos, u8 id, short rotation)
Saves the rotation state for a given position and ID.
static dCenterSaveMng_c * m_instance
The singleton instance of the manager.
A controller for rotating objects around a center point.
u8 mZoomControl
Whether the zoom level is controlled by the rotation controller. [Unknown what 1 and 2 mean].
int mAngDelta
The incremental change in rotation per frame.
short getAngle()
Returns the home rotation angle of this rotation controller.
void tryPlayCoinSE()
Plays a coin sound effect if it has not been played yet for the current rotation.
u8 mRotationID
The rotation ID to be set on the affected objects.
virtual int create() override
do method for the create operation.
short mHomeRotation
The starting rotation.
virtual int execute() override
do method for the execute operation.
@ MODE_PERMANENT
Permamently rotate in one direction.
@ MODE_BACK_AND_FORTH
Move to the stop target when active, move back when inactive.
bool mCoinSoundReady
Whether the coin sound is ready to be played.
u8 mRotationMode
The rotation mode. See RotationMode_e.
bool mCoinSoundPlayed
Whether the coin sound has been played.
static sFStateID_c< daObjCenter2_c > StateID_GoAim
Rotating to the stop rotation.
short mTargetRotation
The current rotation the controller is targeting.
u8 mRotDir
The rotation direction. See DIRECTION_LR_e (right = clockwise, left = counter-clockwise).
static sFStateID_c< daObjCenter2_c > StateID_ReturnHome
Returning to the home rotation.
short mRotationSpeed
The angular speed of the rotation.
void coinSE()
Plays a coin sound effect if the actor is configured to do so.
static sFStateID_c< daObjCenter2_c > StateID_Move
Rotating in one direction.
@ SUCCEEDED
The step was completed successfully.
Definition f_base.hpp:46
#define ACTOR_PROFILE(profName, className, properties)
Creates an actor profile, using the profile number as the execute and draw order value.
Definition f_profile.hpp:29
#define STATE_DEFINE(class, name)
Defines a state.
Definition s_State.hpp:36