NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_wm_demo_actor.cpp
1#include <game/bases/d_wm_demo_actor.hpp>
2#include <game/bases/d_cs_seq_manager.hpp>
3#include <game/bases/d_res.hpp>
5#include <game/bases/d_wm_lib.hpp>
6#include <game/cLib/c_lib.hpp>
8#include <game/mLib/m_heap.hpp>
9#include <lib/nw4r/g3d/res_file.hpp>
10
11dWmDemoActor_c::dWmDemoActor_c() {}
12
15 if (actor == nullptr) {
16 next = nullptr;
17 return nullptr;
18 }
19 switch (actor->GetActorType()) {
24 next = (dWmDemoActor_c *) actor;
25 break;
26 default:
27 next = nullptr;
28 break;
29 }
30 return actor;
31}
32
33void dWmDemoActor_c::setCutEndSpecific(int cutsceneId, bool param2) {
34 if (cutsceneId == -1) {
35 return;
36 }
37 dWmDemoActor_c::setCutEnd();
38}
39
40bool dWmDemoActor_c::isStaff() {
41 dWmDemoActor_c *a1 = dCsSeqMng_c::ms_instance->m_1ac;
42 dWmDemoActor_c *a2 = dCsSeqMng_c::ms_instance->m_1b0;
43 if (a1 == this || a2 == this) {
44 return true;
45 }
46 return false;
47}
48
49void dWmDemoActor_c::InitJumpParam(const mVec3_c &startPos, const mVec3_c &targetPos,
50 int numFrames, float jumpSpeed, float maxYSpeed) {
51 if (startPos.y == targetPos.y) {
52 __initJumpParam1(startPos, targetPos, numFrames, jumpSpeed, maxYSpeed);
53 } else {
54 __initJumpParam2(startPos, targetPos, numFrames, jumpSpeed, maxYSpeed);
55 }
56}
57
58void dWmDemoActor_c::__initJumpParam1(const mVec3_c &startPos, const mVec3_c &targetPos,
59 int numFrames, float jumpSpeed, float maxYSpeed) {
60
61 // The formula is derived from s = v₀ * t + ½ * a * t².
62 // In this case, we land at the same height we started, so we have
63 // 0 = v₀ * t + ½ * a * t², where
64 // t = numFrames
65 // v₀ = jumpSpeed
66
67 // Rearrange for a:
68 // ½ * a * t² = -v₀ * t
69 // a = (2 * -v₀ * t) / t²
70 // a = (2 * -v₀) / t
71 // a = -(2 * v₀) / t
72
73 float numFramesF = numFrames;
74 float accel = -(2.0f * jumpSpeed) / numFramesF;
75 mSpeedF = (targetPos - startPos).xzLen() / numFramesF;
76 mMaxFallSpeed = maxYSpeed;
77 mAccelY = accel;
78 mSpeed.y = jumpSpeed;
79}
80
81void dWmDemoActor_c::__initJumpParam2(const mVec3_c &startPos, const mVec3_c &targetPos,
82 int numFrames, float jumpSpeed, float maxYSpeed) {
83 // The formula is derived from s = v₀ * t + ½ * a * t², where:
84 // s = targetPos.y - startPos.y
85 // t = numFrames
86 // v₀ = jumpSpeed
87
88 // Rearrange for a:
89 // ½ * a * t² = s - v₀ * t
90 // a = (s - v₀ * t) * 2 / t²
91 // a = (v₀ * t - s) * -2 / t² [(not sure why this step was done)]
92
93 float numFramesF = numFrames;
94 float accel = ((jumpSpeed * numFramesF - (targetPos.y - startPos.y)) * -2.0f) / (numFramesF * numFramesF);
95 mSpeedF = (targetPos - startPos).xzLen() / numFramesF;
96 mMaxFallSpeed = maxYSpeed;
97 mAccelY = accel;
98 mSpeed.y = jumpSpeed;
99}
100
101void dWmDemoActor_c::initJumpBase(mVec3_c pos, int numFrames, float jumpSpeed) {
102 mTargetPos = pos;
103 InitJumpParam(mPos, mTargetPos, numFrames, jumpSpeed, -50.0f);
104 s16 ang = cLib::targetAngleY(mPos, mTargetPos);
105 mAngle.y = ang;
106 mAngle3D.y = ang;
107}
108
109bool dWmDemoActor_c::procJumpBase() {
110 calcSpeed();
111 posMove();
112 if (mLastPos.y >= mTargetPos.y && mPos.y <= mTargetPos.y) {
113 mPos = mTargetPos;
114 return true;
115 }
116 return false;
117}
118
119void dWmDemoActor_c::setDirection(const mVec3_c &dir) {
120 mVec3_c direction = dir;
121 direction.normalize();
122 if (EGG::Mathf::abs(direction.x) < 0.1f && EGG::Mathf::abs(direction.z) < 0.1f) {
123 direction = mVec3_c(0.0f, 0.0f, -1.0f);
124 }
125 s16 ang = cM::atan2s(direction.x, direction.z);
126 mAngle.y = ang;
127 mAngle3D.y = ang;
128}
129
130void dWmDemoActor_c::rotDirectionY(short angle, bool is3D) {
131 mAngle.y += angle;
132 if (is3D) {
133 mAngle3D.y = mAngle.y;
134 }
135}
136
137void dWmDemoActor_c::rotDirectionX(short angle, bool is3D) {
138 mAngle.x += angle;
139 if (is3D) {
140 mAngle3D.x = mAngle.x;
141 }
142}
143
144bool dWmDemoActor_c::checkArriveTargetXYZ(const mVec3_c &startPos, const mVec3_c &targetPos) {
145 float dist = startPos.distTo(targetPos);
146 float distToLast = startPos.distTo(mLastPos);
147 float distToCurr = startPos.distTo(mPos);
148 if (distToLast - dist < 0 && distToCurr - dist >= 0) {
149 return true;
150 }
151 return false;
152}
153
154bool dWmDemoActor_c::checkArriveTargetXZ(const mVec3_c &startPos, const mVec3_c &targetPos) {
155 float dist = (targetPos - startPos).xzLen();
156 float distToLast = (mLastPos - startPos).xzLen();
157 float distToCurr = (mPos - startPos).xzLen();
158 if (distToLast - dist < 0 && distToCurr - dist >= 0) {
159 return true;
160 }
161 return false;
162}
163
164void dWmDemoActor_c::CreateShadowModel(const char *arc, const char *path, const char *mdlName, bool param4) {
165 mHeapAllocator.createHeapRestoreCurrent(-1, mHeap::g_gameHeaps[0], nullptr, 0x20, 0);
166
167 nw4r::g3d::ResFile resFile = dResMng_c::m_instance->mRes.getRes(arc, path);
168 mModel.create(resFile.GetResMdl(mdlName), &mHeapAllocator, 0x20, 1, 0);
169
170 mSvMdl = new dWmSVMdl_c();
171 mSvMdl->create(&mHeapAllocator, mModel);
172
173 mHeapAllocator.adjustFrmHeapRestoreCurrent();
174}
175
176void dWmDemoActor_c::CalcShadow(float yOffs, float scaleX, float scaleY, float scaleZ) {
177 mVec3_c shadowPos = mPos;
178 mAng3_c shadowRot = mAng3_c::onlyY(mAngle.y);
179 shadowPos.y = mPos.y + yOffs;
180 mMatrix.trans(shadowPos);
181 mMatrix.ZXYrotM(shadowRot);
182 mModel.setLocalMtx(&mMatrix);
183 mModel.setScale(scaleX, scaleY, scaleZ);
184 mModel.calc(false);
185}
186
187void dWmDemoActor_c::CalcShadow(float yOffs, float scale) {
188 CalcShadow(yOffs, scale, 1.0f, scale);
189}
190
191void dWmDemoActor_c::DrawShadow(bool param1) {
192 if (mSvMdl != nullptr) {
193 mSvMdl->entry();
194 }
195}
196
197void dWmDemoActor_c::_initDemoJumpBaseCore(const mVec3_c &pos, int delay, int frames, float jumpSpeed,
198 float scaleStart, float scaleTarget, const short &angY) {
199 mScaleCurr = scaleStart;
200 mScale.x = scaleStart * 1.0;
201 mScale.y = scaleStart * 1.0;
202 mScale.z = scaleStart * 1.0;
203 mScaleDelta = (scaleTarget - scaleStart) / frames;
204 mScaleTarget = scaleTarget;
205 mScaleDelay = delay;
206 initJumpBase(pos, frames, jumpSpeed);
207 mAngle.y = angY;
208}
209
210void dWmDemoActor_c::_initDemoJumpBase(const mVec3_c &pos, int delay, int frames, float jumpSpeed,
211 float scaleStart, float scaleTarget, const mVec3_c &dir) {
212 short ang = cM::atan2s(dir.x, dir.z);
213 _initDemoJumpBaseCore(pos, delay, frames, jumpSpeed, scaleStart, scaleTarget, ang);
214}
215
216bool dWmDemoActor_c::_procDemoJumpBase() {
217 if (mScaleDelay > 0) {
218 mScaleDelay--;
219 } else {
220 mScaleCurr += mScaleDelta;
221 if (mScaleDelta > 0.0f) {
222 if (mScaleCurr < mScaleTarget) {
223 mScale.set(mScaleCurr, mScaleCurr, mScaleCurr);
224 } else {
225 mScaleCurr = mScaleTarget;
226 mScale.set(mScaleTarget, mScaleTarget, mScaleTarget);
227 }
228 } else {
229 if (mScaleCurr > mScaleTarget) {
230 mScale.set(mScaleCurr, mScaleCurr, mScaleCurr);
231 } else {
232 mScaleCurr = mScaleTarget;
233 mScale.set(mScaleTarget, mScaleTarget, mScaleTarget);
234 }
235 }
236 return procJumpBase();
237 }
238 return false;
239}
240
241float dWmDemoActor_c::GetBgPosY(const mVec3_c &startPos, const mVec3_c &targetPos, int directionType) {
242 float yPos = 0.0f;
243 switch (directionType) {
244 case dWmLib::DIR3D_FRONT:
245 case dWmLib::DIR3D_BACK: {
246 float diffz = EGG::Mathf::abs(startPos.z - targetPos.z);
247 float diffpz = EGG::Mathf::abs(mPos.z - startPos.z);
248 float ratio = diffpz / diffz;
249
250 float delta = targetPos.y - startPos.y;
251 if (EGG::Mathf::abs(delta) < 5.0f) {
252 delta = 0.0f;
253 }
254 yPos = delta * ratio + startPos.y;
255 break;
256 }
257 case dWmLib::DIR3D_LEFT:
258 case dWmLib::DIR3D_RIGHT: {
259 float diffx = EGG::Mathf::abs(startPos.x - targetPos.x);
260 float diffpx = EGG::Mathf::abs(mPos.x - startPos.x);
261 float ratio = diffpx / diffx;
262
263 float delta = targetPos.y - startPos.y;
264 if (EGG::Mathf::abs(delta) < 5.0f) {
265 delta = 0.0f;
266 }
267 yPos = delta * ratio + startPos.y;
268 break;
269 }
270 case dWmLib::DIR3D_UP:
271 case dWmLib::DIR3D_DOWN:
272 yPos = targetPos.y;
273 }
274 return yPos;
275}
276
277void dWmDemoActor_c::CsSPosSimple(int directionType, float yTarget) {
278 switch (directionType) {
279 case dWmLib::DIR3D_FRONT:
280 case dWmLib::DIR3D_BACK:
281 case dWmLib::DIR3D_LEFT:
282 case dWmLib::DIR3D_RIGHT:
283 if (mSpeed.y < 0.0f && mPos.y < yTarget) {
284 mPos.y = yTarget;
285 }
286 break;
287 case dWmLib::DIR3D_UP:
288 if (mPos.y > yTarget) {
289 mPos.y = yTarget;
290 }
291 break;
292 case dWmLib::DIR3D_DOWN:
293 if (mPos.y < yTarget) {
294 mPos.y = yTarget;
295 }
296 break;
297 }
298}
299
300void dWmDemoActor_c::clearSpeedAll() {
301 mSpeedF = 0.0f;
302 mAccelY = 0.0f;
303 mSpeed.y = 0.0f;
304 mMaxFallSpeed = 0.0f;
305}
306
307void dWmDemoActor_c::adjustHeightBase(const mVec3_c &startPos, const mVec3_c &targetPos, int directionType) {
308 if (directionType < 0) {
309 directionType = dWmLib::getPointDir(startPos, targetPos);
310 }
311 CsSPosSimple(directionType, GetBgPosY(startPos, targetPos, directionType));
312}
313
314bool dWmDemoActor_c::isCutscenePlaying(int *csList, int csCount) {
315 int cutName = dCsSeqMng_c::ms_instance->GetCutName();
316 bool found = false;
317 for (int i = 0; i < csCount; i++) {
318 if (csList[i] == cutName) {
319 found = true;
320 break;
321 }
322 }
323 return found;
324}
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 mSpeed
The actor's speed.
mVec3_c mLastPos
The actor's position in the previous frame.
mVec3_c mPos
The actor's position.
float mSpeedF
The actor's horizontal speed.
void posMove()
Moves the actor by its speed.
virtual int GetActorType()
Gets the actor kind. See ACTOR_KIND_e.
float mMaxFallSpeed
The actor's maximum fall speed.
void calcSpeed()
Updates the actor's speed (3D actors). See here for details.
mAng3_c mAngle
The actor's rotation (for 2D actors).
float mAccelY
The actor's vertical acceleration.
@ ACTOR_MAP_ENEMY
A map enemy (dWmEnemy_c).
@ ACTOR_MAP_OBJECT
A map object (dWmObjActor_c).
@ ACTOR_MAP_DEMO
A map actor affected by cutscenes (dWmDemoActor_c).
@ ACTOR_MAP_PLAYER
The worldmap player actor (dWmPlayer_c).
dBaseActor_c()
Constructs a new actor.
static dResMng_c * m_instance
The instance of this class.
Definition d_res_mng.hpp:47
dRes_c mRes
The resource manager.
Definition d_res_mng.hpp:41
void * getRes(const char *arcName, const char *resPath) const
Gets a resource.
Definition d_res.cpp:64
virtual void setCutEndSpecific(int cutsceneId, bool param2)
bool isCutscenePlaying(int *csList, int csCount)
static dBaseActor_c * GetChildDemoActor(dBaseActor_c *prev, dWmDemoActor_c *&next)
@ ACTOR
The base is an actor.
Definition f_base.hpp:26
static fBase_c * searchBaseByGroupType(unsigned char groupType, const fBase_c *parent)
Searches for a base with a given group type, optionally under a given parent.
Definition f_manager.cpp:41
A three-dimensional floating point vector.
Definition m_vec.hpp:100
float normalize()
Normalizes the vector.
Definition m_vec.cpp:18
s16 atan2s(float sin, float cos)
Converts a sine and a cosine to an angle in units.
Definition c_math.cpp:168