NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_a_wm_dokan_route.cpp
2#include <game/bases/d_cs_seq_manager.hpp>
3#include <game/bases/d_a_wm_dokan_route.hpp>
4#include <game/bases/d_s_world_map_static.hpp>
5#include <game/bases/d_wm_lib.hpp>
6#include <game/bases/d_info.hpp>
7#include <game/bases/d_wm_se_manager.hpp>
8#include <game/sLib/s_GlobalData.hpp>
9
10const char *daWmDokanRoute_c::sPointNames[] = {
11 "W601",
12 "W603",
13 "W603",
14 "W605",
15 "W605", // [unused]
16 "W605"
17};
18
19ACTOR_PROFILE(WM_DOKANROUTE, daWmDokanRoute_c, 0);
20
21template <>
23 1.0f,
24 {
25 {mVec3_c(0.0f, 0.0f, 0.0f), 1.0f, 60, 98, 30, daWmDokanRoute_c::EAST},
26 {mVec3_c(0.0f, 0.0f, 0.0f), 1.0f, 30, 75, 15, daWmDokanRoute_c::SOUTH},
27 {mVec3_c(0.0f, 0.0f, 0.0f), 1.0f, 90, 160, 15, daWmDokanRoute_c::WEST},
28 {mVec3_c(0.0f, 0.0f, 0.0f), 1.0f, 120, 155, 15, daWmDokanRoute_c::SOUTH},
29 {mVec3_c(0.0f, 0.0f, 0.0f), 1.0f, 110, 150, 15, daWmDokanRoute_c::SOUTH}, // [unused]
30 {mVec3_c(0.0f, 0.0f, 0.0f), 1.0f, 155, 175, 15, daWmDokanRoute_c::SOUTH}
31 }
32};
33
35 EXIT_TYPE_NORMAL,
36 EXIT_TYPE_NORMAL,
37 EXIT_TYPE_NORMAL,
38 EXIT_TYPE_NORMAL,
39 EXIT_TYPE_SECRET, // [unused]
40 EXIT_TYPE_NORMAL,
41};
42
45
49 mClipSphere.set(mPos, 250.0f);
50
51 initState();
53 return SUCCEEDED;
54}
55
57 processCutsceneCommand(dCsSeqMng_c::ms_instance->GetCutName(), dCsSeqMng_c::ms_instance->m_164);
58
59 static const ProcFunc Proc_tbl[PROC_COUNT] = {
61 };
62
63 (this->*Proc_tbl[mCurrProc])();
64 initPosRot(); // [unnecessary call]
65 calcAnim();
67 return SUCCEEDED;
68}
69
71 mModel.entry();
72 return SUCCEEDED;
73}
74
78
80 mAllocator.createFrmHeap(-1, mHeap::g_gameHeaps[mHeap::GAME_HEAP_DEFAULT], nullptr, 0x20);
81 mResFile = dResMng_c::m_instance->getRes("cobDokanRoute", "g3d/model.brres");
82
83 nw4r::g3d::ResMdl resMdl = mResFile.GetResMdl("cobDokanRoute");
84 mModel.create(resMdl, &mAllocator, nw4r::g3d::ScnMdl::ANM_TEXSRT | nw4r::g3d::ScnMdl::BUFFER_RESMATMISC, 1);
85
86 static const char *resAnmNames[ANIM_COUNT] = {
87 "cobDokanRoute"
88 };
89
90 static const m3d::playMode_e playModes[ANIM_COUNT] = {
92 };
93
94 for (int i = 0; i < ANIM_COUNT; i++) {
95 nw4r::g3d::ResAnmChr resAnmChr = mResFile.GetResAnmChr(resAnmNames[i]);
96 mChrAnim[i].create(resMdl, resAnmChr, &mAllocator, nullptr);
97 mChrAnim[i].mPlayMode = playModes[i];
98 mChrAnim[i].setRate(0.0f);
99 mChrAnim[i].setFrame(0.0f);
100
101 nw4r::g3d::ResAnmTexSrt resAnmTexSrt = mResFile.GetResAnmTexSrt(resAnmNames[i]);
102 mSrtAnim[i].create(resMdl, resAnmTexSrt, &mAllocator, nullptr, 1);
103 mSrtAnim[i].setPlayMode(playModes[i], 0);
104 mSrtAnim[i].setRate(0.0f, 0);
105 mSrtAnim[i].setFrame(0.0f, 0);
106
107 mModel.setAnm(mChrAnim[i]);
108 mModel.setAnm(mSrtAnim[i]);
109 }
110
112 mAllocator.adjustFrmHeap();
113}
114
116 mModel.play();
117}
118
120 mVec3_c pos = mPos;
121 mAng3_c angle = mAngle;
122 mMatrix.trans(pos);
123 mMatrix.ZXYrotM(angle);
124 model.setLocalMtx(&mMatrix);
125 model.setScale(mScale);
126 model.calc(false);
127}
128
130 initPosRot();
131 initAnim();
132 float scale = GLOBAL_DATA.mScaleMultiplier;
133 mScale.set(scale, scale, scale);
134 init_exec();
135}
136
138 mCurrProc = PROC_TYPE_EXEC;
139}
140
142
143void daWmDokanRoute_c::processCutsceneCommand(int cutsceneCommandId, bool isFirstFrame) {
144 if (cutsceneCommandId == dCsSeqMng_c::CUTSCENE_CMD_NONE) {
145 return;
146 }
147
148 if (isFirstFrame) {
149 if (cutsceneCommandId == dCsSeqMng_c::CUTSCENE_CMD_COURSE_UNLOCK) {
151 }
152 }
153
154 if (cutsceneCommandId == dCsSeqMng_c::CUTSCENE_CMD_COURSE_UNLOCK) {
156 } else {
157 setCutEnd();
158 }
159}
160
162 u8 nodeNum = GetNodeNum();
163 mPos = mInitialPos + GLOBAL_DATA.mNodeConfigs[nodeNum].mPosOffset;
164 s16 pipeDir = GLOBAL_DATA.mNodeConfigs[nodeNum].mDirection;
165
166 float frame = 0.0f;
167 mVec3_c rot = mVec3_c::Ez;
168
169 switch (pipeDir) {
170 case EAST:
171 frame = 2.0f;
172 rot = mVec3_c::Ez;
173 break;
174
175 case WEST:
176 frame = 1.0f;
177 rot = -mVec3_c::Ez;
178 break;
179
180 case NORTH:
181 frame = 0.0f;
182 rot = mVec3_c::Ex;
183 break;
184
185 case SOUTH:
186 frame = 0.0f;
187 rot = -mVec3_c::Ex;
188 break;
189
190 default:
191 break;
192 }
193
194 s16 angle = rot.xzAng();
195 mAngle.y = angle;
196 mAngle3D.y = angle;
197
198 mSrtAnim[cobDokanRoute].setFrame(frame, 0);
199}
200
202 u8 nodeNum = GetNodeNum();
203 int courseNo = dWmLib::GetCourseNoFromPointName(sPointNames[nodeNum]);
204 dInfo_c *info = dInfo_c::getInstance();
205
206 float frame = 0.0f;
207 switch (sExitTypes[nodeNum]) {
208 case EXIT_TYPE_NORMAL:
209 if (dWmLib::IsCourseOmoteClear(dScWMap_c::m_WorldNo, courseNo) &&
210 !dWmLib::IsCourseFirstOmoteClear(dScWMap_c::m_WorldNo, courseNo, info->mCurrentCourseNode)
211 ) {
212 frame = getEndFrame();
213 }
214 break;
215
216 case EXIT_TYPE_SECRET:
217 if (dWmLib::IsCourseUraClear(dScWMap_c::m_WorldNo, courseNo) &&
218 !dWmLib::IsCourseFirstUraClear(dScWMap_c::m_WorldNo, courseNo, info->mCurrentCourseNode)
219 ) {
220 frame = getEndFrame();
221 }
222 break;
223
224 default:
225 break;
226 }
227
228 mChrAnim[cobDokanRoute].setFrame(frame);
229 mChrAnim[cobDokanRoute].setRate(0.0f);
230}
231
233 u8 nodeNum = GetNodeNum();
234 int courseNo = dWmLib::GetCourseNoFromPointName(sPointNames[nodeNum]);
235 dInfo_c *info = dInfo_c::getInstance();
236
238 if (sExitTypes[nodeNum] != EXIT_TYPE_SECRET && dWmLib::IsCourseFirstOmoteClear(dScWMap_c::m_WorldNo, courseNo, info->mCurrentCourseNode) ||
239 sExitTypes[nodeNum] == EXIT_TYPE_SECRET && dWmLib::IsCourseFirstUraClear(dScWMap_c::m_WorldNo, courseNo, info->mCurrentCourseNode)) {
240 mStateTimer = GLOBAL_DATA.mNodeConfigs[nodeNum].mInitialDelay;
242 }
243}
244
246 u8 nodeNum = GetNodeNum();
247
248 switch (mState) {
249 case STATE_IDLE:
250 setCutEnd();
251 break;
252
253 case STATE_WAIT_DELAY:
254 if (mStateTimer > 0) {
255 mStateTimer--;
256 } else {
258 }
259 break;
260
261 case STATE_ANIM_START:
262 dWmSeManager_c::m_pInstance->playSound(dWmSeManager_c::WM_SE_OBJ_CS_DOKAN, mPos, 1);
263 mChrAnim[cobDokanRoute].setRate(GLOBAL_DATA.mNodeConfigs[nodeNum].mAnmRate);
264 mStateTimer = GLOBAL_DATA.mNodeConfigs[nodeNum].mAnimDuration - GLOBAL_DATA.mNodeConfigs[nodeNum].mInitialDelay;
266 break;
267
268 case STATE_ANIM_PLAY:
269 if (mStateTimer > 0) {
270 mStateTimer--;
271
272 // Begin linearly decelerating if less than mDecelDuration frames are left
273 if (mStateTimer <= GLOBAL_DATA.mNodeConfigs[nodeNum].mDecelDuration) {
274 float decelFrames = (float) GLOBAL_DATA.mNodeConfigs[nodeNum].mDecelDuration - mStateTimer;
275 float decelPercent = decelFrames / GLOBAL_DATA.mNodeConfigs[nodeNum].mDecelDuration;
276 float rate = (1.0f - decelPercent) * GLOBAL_DATA.mNodeConfigs[nodeNum].mAnmRate;
277 mChrAnim[cobDokanRoute].setRate(rate);
278 }
279 } else {
281 }
282 break;
283
284 case STATE_ANIM_END:
285 mChrAnim[cobDokanRoute].setRate(0.0f);
286 setCutEnd();
287 break;
288
289 default:
290 break;
291 }
292}
293
295 u8 nodeNum = GetNodeNum();
296 float movementDuration = GLOBAL_DATA.mNodeConfigs[nodeNum].mAnimDuration - GLOBAL_DATA.mNodeConfigs[nodeNum].mInitialDelay;
297 float frame = (movementDuration - GLOBAL_DATA.mNodeConfigs[nodeNum].mDecelDuration) * GLOBAL_DATA.mNodeConfigs[nodeNum].mAnmRate;
298
299 // Compute linear deceleration to get final frame
300 for (int i = 0; i < GLOBAL_DATA.mNodeConfigs[nodeNum].mDecelDuration; i++) {
301 float decelPercent = i / (float) GLOBAL_DATA.mNodeConfigs[nodeNum].mDecelDuration;
302 frame += (1.0f - decelPercent) * GLOBAL_DATA.mNodeConfigs[nodeNum].mAnmRate;
303 }
304
305 return frame;
306}
mAng3_c mAngle3D
The actor's rotation (for 3D actors).
mMtx_c mMatrix
The actor's partial transformation matrix. See makeMtx() for details.
mVec3_c mScale
The actor's scale (defaults to 1).
mVec3_c mPos
The actor's position.
mAng3_c mAngle
The actor's rotation (for 2D actors).
static dResMng_c * m_instance
The instance of this class.
Definition d_res_mng.hpp:61
static void setSoftLight_Map(m3d::bmdl_c &mdl)
Sets the soft light effect for map actors.
mSphere_c mClipSphere
A sphere representing the actor's visible area.
The actor for World Map pipes used in course unlock paths.
virtual int execute()
do method for the execute operation.
virtual int doDelete()
do method for the delete operation.
mVec3_c mInitialPos
The initial position of the pipe.
void init_exec()
Process initialization function for the exec process type.
void createModel()
Initializes the resources for the actor.
nw4r::g3d::ResFile mResFile
The resource file.
m3d::anmTexSrt_c mSrtAnim[ANIM_COUNT]
The texture animations.
STATE_e mState
The current cutscene state. See STATE_e.
void calcAnim()
Updates the currently playing animation.
m3d::mdl_c mModel
The model.
PROC_TYPE_e mCurrProc
The current process type. See dWmObjActor_c::PROC_TYPE_e.
dHeapAllocator_c mAllocator
The allocator.
virtual int draw()
do method for the draw operation.
virtual int create()
do method for the create operation.
void initState()
Sets up the actor's initial state.
void calcModel(m3d::mdl_c &model)
Updates the model's transformation matrix.
~daWmDokanRoute_c()
Destroys the object.
float getEndFrame()
Computes the animation frame for a fully completed pipe animation.
static const u8 sExitTypes[NODE_COUNT]
The exit type associated with each node. Values are EXIT_TYPE_e.
void initPosRot()
Initializes the pipe position and rotation (and the associated texture animation).
void onCourseUnlock()
Updates the course unlock cutscene animation.
m3d::anmChr_c mChrAnim[ANIM_COUNT]
The model animations.
void mode_exec()
Process function for the exec process type.
void onCourseUnlockInit()
Initializes the course unlock cutscene animation.
@ STATE_ANIM_PLAY
The movement animation is playing.
@ STATE_ANIM_START
The sound effect is played and the pipe begins moving.
@ STATE_IDLE
No animation plays.
@ STATE_ANIM_END
The movement animation is completed.
@ STATE_WAIT_DELAY
Initial delay before the pipe begins moving.
@ EXIT_TYPE_SECRET
The pipe is part of a secret exit unlock animation.
@ EXIT_TYPE_NORMAL
The pipe is part of a regular exit unlock animation.
virtual void processCutsceneCommand(int cutsceneCommandId, bool isFirstFrame)
Contains the actor-specific logic for processing the current world map cutscene.
void initAnim()
Initializes the pipe's model animation, based on the associated level's completion status.
daWmDokanRoute_c()
Constructs a new object.
int mStateTimer
The timer for the current state.
static const char * sPointNames[NODE_COUNT]
The point name associated with each node.
@ SUCCEEDED
The step was completed successfully.
Definition f_base.hpp:46
A three-dimensional short angle vector.
Definition m_angle.hpp:59
A three-dimensional floating point vector.
Definition m_vec.hpp:112
static mVec3_c Ex
The unit vector for the X axis.
Definition m_vec.hpp:221
static mVec3_c Ez
The unit vector for the Z axis.
Definition m_vec.hpp:223
static const T::GlobalData_t mData
#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
playMode_e
Definition banm.hpp:7
@ FORWARD_ONCE
Play the animation forward once.
Definition banm.hpp:9
@ GAME_HEAP_DEFAULT
The default game heap (alias of MEM1 or MEM2).
Definition m_heap.hpp:38
EGG::ExpHeap * g_gameHeaps[GAME_HEAP_COUNT]
The game heaps.
Definition m_heap.cpp:13
The global configuration for the actor.