Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/game/mario_actions_airborne.c
7858 views
1
#include <PR/ultratypes.h>
2
3
#include "sm64.h"
4
#include "area.h"
5
#include "audio/external.h"
6
#include "camera.h"
7
#include "engine/graph_node.h"
8
#include "engine/math_util.h"
9
#include "game_init.h"
10
#include "interaction.h"
11
#include "level_update.h"
12
#include "mario.h"
13
#include "mario_step.h"
14
#include "save_file.h"
15
#include "rumble_init.h"
16
17
#include "settings.h"
18
19
void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3) {
20
s32 animFrame = m->marioObj->header.gfx.animInfo.animFrame;
21
if (animFrame == frame1 || animFrame == frame2 || animFrame == frame3) {
22
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
23
}
24
}
25
26
void play_far_fall_sound(struct MarioState *m) {
27
u32 action = m->action;
28
if (!(action & ACT_FLAG_INVULNERABLE) && action != ACT_TWIRLING && action != ACT_FLYING
29
&& !(m->flags & MARIO_UNKNOWN_18)) {
30
if (m->peakHeight - m->pos[1] > 1150.0f) {
31
play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject);
32
m->flags |= MARIO_UNKNOWN_18;
33
}
34
}
35
}
36
37
#ifndef VERSION_JP
38
void play_knockback_sound(struct MarioState *m) {
39
if (m->actionArg == 0 && (m->forwardVel <= -28.0f || m->forwardVel >= 28.0f)) {
40
play_sound_if_no_flag(m, SOUND_MARIO_DOH, MARIO_MARIO_SOUND_PLAYED);
41
} else {
42
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
43
}
44
}
45
#endif
46
47
s32 lava_boost_on_wall(struct MarioState *m) {
48
49
if (mario_has_improved_metal_cap(m))
50
return FALSE;
51
52
m->faceAngle[1] = atan2s(m->wall->normal.z, m->wall->normal.x);
53
54
if (m->forwardVel < 24.0f) {
55
m->forwardVel = 24.0f;
56
}
57
58
if (!(m->flags & MARIO_METAL_CAP)) {
59
m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18;
60
}
61
62
play_sound(SOUND_MARIO_ON_FIRE, m->marioObj->header.gfx.cameraToObject);
63
update_mario_sound_and_camera(m);
64
return drop_and_set_mario_action(m, ACT_LAVA_BOOST, 1);
65
}
66
67
s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) {
68
f32 fallHeight;
69
f32 damageHeight;
70
71
fallHeight = m->peakHeight - m->pos[1];
72
73
#pragma GCC diagnostic push
74
#if defined(__clang__)
75
#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
76
#elif defined(__GNUC__)
77
#pragma GCC diagnostic ignored "-Wtype-limits"
78
#endif
79
80
//! Never true
81
if (m->actionState == ACT_GROUND_POUND) {
82
damageHeight = 600.0f;
83
} else {
84
damageHeight = 1150.0f;
85
}
86
87
#pragma GCC diagnostic pop
88
89
if (m->action != ACT_TWIRLING && m->floor->type != SURFACE_BURNING) {
90
if (m->vel[1] < -55.0f) {
91
if (fallHeight > 3000.0f) {
92
if (!configDisableFallDamage) {
93
m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 16 : 24;
94
}
95
#if ENABLE_RUMBLE
96
queue_rumble_data(5, 80);
97
#endif
98
set_camera_shake_from_hit(SHAKE_FALL_DAMAGE);
99
play_sound(SOUND_MARIO_ATTACKED, m->marioObj->header.gfx.cameraToObject);
100
return drop_and_set_mario_action(m, hardFallAction, 4);
101
} else if (fallHeight > damageHeight && !mario_floor_is_slippery(m)) {
102
if ((!configDisableFallDamage) && (!mario_has_improved_metal_cap(m))) {
103
m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 8 : 12;
104
}
105
m->squishTimer = 30;
106
#if ENABLE_RUMBLE
107
queue_rumble_data(5, 80);
108
#endif
109
set_camera_shake_from_hit(SHAKE_FALL_DAMAGE);
110
play_sound(SOUND_MARIO_ATTACKED, m->marioObj->header.gfx.cameraToObject);
111
}
112
}
113
}
114
115
return FALSE;
116
}
117
118
s32 check_kick_or_dive_in_air(struct MarioState *m) {
119
if (m->input & INPUT_B_PRESSED) {
120
if (configImprovedControls) {
121
if (m->forwardVel >= 28.0f && m->controller->stickMag > 48.0f) {
122
return set_mario_action(m, ACT_DIVE, 1);
123
}
124
return set_mario_action(m, ACT_JUMP_KICK, 0);
125
}
126
else {
127
return set_mario_action(m, m->forwardVel > 28.0f ? ACT_DIVE : ACT_JUMP_KICK, 0);
128
}
129
}
130
return FALSE;
131
}
132
133
s32 should_get_stuck_in_ground(struct MarioState *m) {
134
u32 terrainType = m->area->terrainType & TERRAIN_MASK;
135
struct Surface *floor = m->floor;
136
s32 flags = floor->flags;
137
s32 type = floor->type;
138
139
if (floor != NULL && (terrainType == TERRAIN_SNOW || terrainType == TERRAIN_SAND)
140
&& type != SURFACE_BURNING && SURFACE_IS_NOT_HARD(type)) {
141
if (!(flags & 0x01) && m->peakHeight - m->pos[1] > 1000.0f && floor->normal.y >= 0.8660254f) {
142
return TRUE;
143
}
144
}
145
146
return FALSE;
147
}
148
149
s32 check_fall_damage_or_get_stuck(struct MarioState *m, u32 hardFallAction) {
150
if (should_get_stuck_in_ground(m)) {
151
#ifdef VERSION_JP
152
play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
153
#else
154
play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
155
#endif
156
m->particleFlags |= PARTICLE_MIST_CIRCLE;
157
drop_and_set_mario_action(m, ACT_FEET_STUCK_IN_GROUND, 0);
158
#if ENABLE_RUMBLE
159
queue_rumble_data(5, 80);
160
#endif
161
return TRUE;
162
}
163
164
return check_fall_damage(m, hardFallAction);
165
}
166
167
s32 check_horizontal_wind(struct MarioState *m) {
168
struct Surface *floor;
169
f32 speed;
170
s16 pushAngle;
171
172
floor = m->floor;
173
174
if (!mario_has_improved_metal_cap(m) && floor->type == SURFACE_HORIZONTAL_WIND) {
175
pushAngle = floor->force << 8;
176
177
m->slideVelX += 1.2f * sins(pushAngle);
178
m->slideVelZ += 1.2f * coss(pushAngle);
179
180
speed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
181
182
if (speed > 48.0f) {
183
m->slideVelX = m->slideVelX * 48.0f / speed;
184
m->slideVelZ = m->slideVelZ * 48.0f / speed;
185
speed = configApplyBugFixes ? 48.0f : 32.0f; //! This was meant to be 48?
186
} else if (speed > 32.0f) {
187
speed = 32.0f;
188
}
189
190
m->vel[0] = m->slideVelX;
191
m->vel[2] = m->slideVelZ;
192
m->slideYaw = atan2s(m->slideVelZ, m->slideVelX);
193
m->forwardVel = speed * coss(m->faceAngle[1] - m->slideYaw);
194
195
#ifdef VERSION_JP
196
play_sound(SOUND_ENV_WIND2, m->marioObj->header.gfx.cameraToObject);
197
#endif
198
return TRUE;
199
}
200
201
return FALSE;
202
}
203
204
void update_air_with_turn(struct MarioState *m) {
205
f32 dragThreshold;
206
s16 intendedDYaw;
207
f32 intendedMag;
208
209
if (!check_horizontal_wind(m)) {
210
dragThreshold = m->action == ACT_LONG_JUMP ? 48.0f : 32.0f;
211
m->forwardVel = approach_f32(m->forwardVel, 0.0f, 0.35f, 0.35f);
212
213
if (m->input & INPUT_NONZERO_ANALOG) {
214
intendedDYaw = m->intendedYaw - m->faceAngle[1];
215
intendedMag = m->intendedMag / 32.0f;
216
217
if (configImprovedControls) {
218
if ((m->forwardVel > 0 && intendedMag * coss(intendedDYaw) > 0) || (m->forwardVel < 0 && intendedMag * coss(intendedDYaw) < 0)) {
219
if (m->action != ACT_WALL_KICK_AIR)
220
m->forwardVel += intendedMag * coss(intendedDYaw) * 1.5f;
221
}
222
else {
223
m->forwardVel += intendedMag * coss(intendedDYaw) * 3.5f;
224
}
225
m->faceAngle[1] += 1024.0f * sins(intendedDYaw) * intendedMag;
226
}
227
else {
228
m->forwardVel += 1.5f * coss(intendedDYaw) * intendedMag;
229
m->faceAngle[1] += 512.0f * sins(intendedDYaw) * intendedMag;
230
}
231
}
232
233
//! Uncapped air speed. Net positive when moving forward.
234
if (m->forwardVel > dragThreshold) {
235
m->forwardVel -= 1.0f;
236
}
237
if (m->forwardVel < -16.0f) {
238
m->forwardVel += 2.0f;
239
}
240
241
m->vel[0] = m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
242
m->vel[2] = m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
243
}
244
}
245
246
void update_air_without_turn(struct MarioState *m, u32 canTurn) {
247
f32 sidewaysSpeed = 0.0f;
248
f32 dragThreshold;
249
s16 intendedDYaw;
250
f32 intendedMag;
251
252
if (!check_horizontal_wind(m)) {
253
dragThreshold = m->action == ACT_LONG_JUMP ? 48.0f : 32.0f;
254
m->forwardVel = approach_f32(m->forwardVel, 0.0f, 0.35f, 0.35f);
255
256
if (m->input & INPUT_NONZERO_ANALOG) {
257
intendedDYaw = m->intendedYaw - m->faceAngle[1];
258
intendedMag = m->intendedMag / 32.0f;
259
260
if (configImprovedControls && m->action != ACT_LONG_JUMP) {
261
if ((m->forwardVel > 0 && intendedMag * coss(intendedDYaw) > 0) || (m->forwardVel < 0 && intendedMag * coss(intendedDYaw) < 0)) {
262
if (m->action != ACT_WALL_KICK_AIR)
263
m->forwardVel += intendedMag * coss(intendedDYaw) * 1.5f;
264
}
265
else {
266
m->forwardVel += intendedMag * coss(intendedDYaw) * 3.5f;
267
}
268
if (configFullAirControl && canTurn) {
269
sidewaysSpeed = intendedMag * sins(intendedDYaw) * 7.5f;
270
m->faceAngle[1] += 768.0f * sins(intendedDYaw) * intendedMag;
271
}
272
else if (canTurn) {
273
sidewaysSpeed = intendedMag * sins(intendedDYaw) * 15.0f;
274
m->faceAngle[1] += 320.0f * sins(intendedDYaw) * intendedMag;
275
}
276
else {
277
sidewaysSpeed = intendedMag * sins(intendedDYaw) * 15.0f;
278
m->faceAngle[1] += 64.0f * sins(intendedDYaw) * intendedMag;
279
}
280
281
}
282
else {
283
m->forwardVel += intendedMag * coss(intendedDYaw) * 1.5f;
284
if (configFullAirControl && canTurn) {
285
sidewaysSpeed = intendedMag * sins(intendedDYaw) * 5.0f;
286
m->faceAngle[1] += 768.0f * sins(intendedDYaw) * intendedMag;
287
}
288
else {
289
sidewaysSpeed = intendedMag * sins(intendedDYaw) * 10.0f;
290
}
291
}
292
}
293
294
//! Uncapped air speed. Net positive when moving forward.
295
if (m->forwardVel > dragThreshold) {
296
m->forwardVel -= 1.0f;
297
}
298
if (m->forwardVel < -16.0f) {
299
m->forwardVel += 2.0f;
300
}
301
302
m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
303
m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
304
305
m->slideVelX += sidewaysSpeed * sins(m->faceAngle[1] + 0x4000);
306
m->slideVelZ += sidewaysSpeed * coss(m->faceAngle[1] + 0x4000);
307
308
m->vel[0] = m->slideVelX;
309
m->vel[2] = m->slideVelZ;
310
}
311
}
312
313
void update_lava_boost_or_twirling(struct MarioState *m) {
314
s16 intendedDYaw;
315
f32 intendedMag;
316
317
if (m->input & INPUT_NONZERO_ANALOG) {
318
intendedDYaw = m->intendedYaw - m->faceAngle[1];
319
intendedMag = m->intendedMag / 32.0f;
320
321
m->forwardVel += coss(intendedDYaw) * intendedMag;
322
m->faceAngle[1] += sins(intendedDYaw) * intendedMag * 1024.0f;
323
324
if (m->forwardVel < 0.0f) {
325
m->faceAngle[1] += 0x8000;
326
m->forwardVel *= -1.0f;
327
}
328
329
if (m->forwardVel > 32.0f) {
330
m->forwardVel -= 2.0f;
331
}
332
}
333
334
m->vel[0] = m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
335
m->vel[2] = m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
336
}
337
338
void update_flying_yaw(struct MarioState *m) {
339
s16 targetYawVel = -(s16)(m->controller->stickX * (m->forwardVel / 4.0f));
340
341
if (targetYawVel > 0) {
342
if (m->angleVel[1] < 0) {
343
m->angleVel[1] += 0x40;
344
if (m->angleVel[1] > 0x10) {
345
m->angleVel[1] = 0x10;
346
}
347
} else {
348
m->angleVel[1] = approach_s32(m->angleVel[1], targetYawVel, 0x10, 0x20);
349
}
350
} else if (targetYawVel < 0) {
351
if (m->angleVel[1] > 0) {
352
m->angleVel[1] -= 0x40;
353
if (m->angleVel[1] < -0x10) {
354
m->angleVel[1] = -0x10;
355
}
356
} else {
357
m->angleVel[1] = approach_s32(m->angleVel[1], targetYawVel, 0x20, 0x10);
358
}
359
} else {
360
m->angleVel[1] = approach_s32(m->angleVel[1], 0, 0x40, 0x40);
361
}
362
363
m->faceAngle[1] += m->angleVel[1];
364
m->faceAngle[2] = 20 * -m->angleVel[1];
365
}
366
367
void update_flying_pitch(struct MarioState *m) {
368
s16 targetPitchVel = -(s16)(m->controller->stickY * (m->forwardVel / 5.0f));
369
370
if (targetPitchVel > 0) {
371
if (m->angleVel[0] < 0) {
372
m->angleVel[0] += 0x40;
373
if (m->angleVel[0] > 0x20) {
374
m->angleVel[0] = 0x20;
375
}
376
} else {
377
m->angleVel[0] = approach_s32(m->angleVel[0], targetPitchVel, 0x20, 0x40);
378
}
379
} else if (targetPitchVel < 0) {
380
if (m->angleVel[0] > 0) {
381
m->angleVel[0] -= 0x40;
382
if (m->angleVel[0] < -0x20) {
383
m->angleVel[0] = -0x20;
384
}
385
} else {
386
m->angleVel[0] = approach_s32(m->angleVel[0], targetPitchVel, 0x40, 0x20);
387
}
388
} else {
389
m->angleVel[0] = approach_s32(m->angleVel[0], 0, 0x40, 0x40);
390
}
391
}
392
393
void update_flying(struct MarioState *m) {
394
UNUSED u32 unused;
395
396
update_flying_pitch(m);
397
update_flying_yaw(m);
398
399
m->forwardVel -= 2.0f * ((f32) m->faceAngle[0] / 0x4000) + 0.1f;
400
m->forwardVel -= 0.5f * (1.0f - coss(m->angleVel[1]));
401
402
if (m->forwardVel < 0.0f) {
403
m->forwardVel = 0.0f;
404
}
405
406
if (m->forwardVel > 16.0f) {
407
m->faceAngle[0] += (m->forwardVel - 32.0f) * 6.0f;
408
} else if (m->forwardVel > 4.0f) {
409
m->faceAngle[0] += (m->forwardVel - 32.0f) * 10.0f;
410
} else {
411
m->faceAngle[0] -= 0x400;
412
}
413
414
m->faceAngle[0] += m->angleVel[0];
415
416
if (m->faceAngle[0] > 0x2AAA) {
417
m->faceAngle[0] = 0x2AAA;
418
}
419
if (m->faceAngle[0] < -0x2AAA) {
420
m->faceAngle[0] = -0x2AAA;
421
}
422
423
m->vel[0] = m->forwardVel * coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
424
m->vel[1] = m->forwardVel * sins(m->faceAngle[0]);
425
m->vel[2] = m->forwardVel * coss(m->faceAngle[0]) * coss(m->faceAngle[1]);
426
427
m->slideVelX = m->vel[0];
428
m->slideVelZ = m->vel[2];
429
}
430
431
u32 common_air_action_step(struct MarioState *m, u32 landAction, s32 animation, u32 stepArg) {
432
u32 stepResult;
433
434
update_air_without_turn(m, 1);
435
436
stepResult = perform_air_step(m, stepArg);
437
switch (stepResult) {
438
case AIR_STEP_NONE:
439
set_mario_animation(m, animation);
440
break;
441
442
case AIR_STEP_LANDED:
443
if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
444
set_mario_action(m, landAction, 0);
445
}
446
break;
447
448
case AIR_STEP_HIT_WALL:
449
set_mario_animation(m, animation);
450
451
if (m->forwardVel > 16.0f) {
452
#if ENABLE_RUMBLE
453
queue_rumble_data(5, 40);
454
#endif
455
mario_bonk_reflection(m, FALSE);
456
m->faceAngle[1] += 0x8000;
457
458
if (m->wall != NULL) {
459
set_mario_action(m, ACT_AIR_HIT_WALL, 0);
460
} else {
461
if (m->vel[1] > 0.0f) {
462
m->vel[1] = 0.0f;
463
}
464
465
//! Hands-free holding. Bonking while no wall is referenced
466
// sets Mario's action to a non-holding action without
467
// dropping the object, causing the hands-free holding
468
// glitch. This can be achieved using an exposed ceiling,
469
// out of bounds, grazing the bottom of a wall while
470
// falling such that the final quarter step does not find a
471
// wall collision, or by rising into the top of a wall such
472
// that the final quarter step detects a ledge, but you are
473
// not able to ledge grab it.
474
if (m->forwardVel >= 38.0f) {
475
m->particleFlags |= PARTICLE_VERTICAL_STAR;
476
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
477
} else {
478
if (m->forwardVel > 8.0f) {
479
mario_set_forward_vel(m, -8.0f);
480
}
481
return set_mario_action(m, ACT_SOFT_BONK, 0);
482
}
483
}
484
} else {
485
mario_set_forward_vel(m, 0.0f);
486
}
487
break;
488
489
case AIR_STEP_GRABBED_LEDGE:
490
set_mario_animation(m, MARIO_ANIM_IDLE_ON_LEDGE);
491
drop_and_set_mario_action(m, ACT_LEDGE_GRAB, 0);
492
break;
493
494
case AIR_STEP_GRABBED_CEILING:
495
set_mario_action(m, ACT_START_HANGING, 0);
496
break;
497
498
case AIR_STEP_HIT_LAVA_WALL:
499
lava_boost_on_wall(m);
500
break;
501
}
502
503
return stepResult;
504
}
505
506
s32 act_jump(struct MarioState *m) {
507
508
if (configImprovedControls && m->actionTimer < 1) {
509
m->actionTimer++;
510
if (m->input & INPUT_Z_PRESSED && m->forwardVel > 10.0f) {
511
return set_jumping_action(m, ACT_LONG_JUMP, 0);
512
}
513
}
514
515
if (check_kick_or_dive_in_air(m)) {
516
return TRUE;
517
}
518
519
if (m->input & INPUT_Z_PRESSED) {
520
return set_mario_action(m, ACT_GROUND_POUND, 0);
521
}
522
523
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
524
common_air_action_step(m, ACT_JUMP_LAND, MARIO_ANIM_SINGLE_JUMP,
525
AIR_STEP_CHECK_LEDGE_GRAB | AIR_STEP_CHECK_HANG);
526
return FALSE;
527
}
528
529
s32 act_double_jump(struct MarioState *m) {
530
s32 animation = (m->vel[1] >= 0.0f)
531
? MARIO_ANIM_DOUBLE_JUMP_RISE
532
: MARIO_ANIM_DOUBLE_JUMP_FALL;
533
534
if (check_kick_or_dive_in_air(m)) {
535
return TRUE;
536
}
537
538
if (m->input & INPUT_Z_PRESSED) {
539
return set_mario_action(m, ACT_GROUND_POUND, 0);
540
}
541
542
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_HOOHOO);
543
common_air_action_step(m, ACT_DOUBLE_JUMP_LAND, animation,
544
AIR_STEP_CHECK_LEDGE_GRAB | AIR_STEP_CHECK_HANG);
545
return FALSE;
546
}
547
548
s32 act_triple_jump(struct MarioState *m) {
549
if (configTwirlTripleJump) {
550
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
551
return set_mario_action(m, ACT_TWIRLING, 0);
552
}
553
554
if (gSpecialTripleJump) {
555
return set_mario_action(m, ACT_SPECIAL_TRIPLE_JUMP, 0);
556
}
557
558
if (m->input & INPUT_B_PRESSED) {
559
return set_mario_action(m, ACT_DIVE, 0);
560
}
561
562
if (m->input & INPUT_Z_PRESSED) {
563
return set_mario_action(m, ACT_GROUND_POUND, 0);
564
}
565
566
#ifndef VERSION_JP
567
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
568
#else
569
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
570
#endif
571
572
common_air_action_step(m, ACT_TRIPLE_JUMP_LAND, MARIO_ANIM_TRIPLE_JUMP, 0);
573
#if ENABLE_RUMBLE
574
if (m->action == ACT_TRIPLE_JUMP_LAND) {
575
queue_rumble_data(5, 40);
576
}
577
#endif
578
play_flip_sounds(m, 2, 8, 20);
579
return FALSE;
580
}
581
582
s32 act_backflip(struct MarioState *m) {
583
if (m->input & INPUT_Z_PRESSED) {
584
return set_mario_action(m, ACT_GROUND_POUND, 0);
585
}
586
587
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAH_WAH_HOO);
588
common_air_action_step(m, ACT_BACKFLIP_LAND, MARIO_ANIM_BACKFLIP, 0);
589
#if ENABLE_RUMBLE
590
if (m->action == ACT_BACKFLIP_LAND) {
591
queue_rumble_data(5, 40);
592
}
593
#endif
594
play_flip_sounds(m, 2, 3, 17);
595
return FALSE;
596
}
597
598
s32 act_freefall(struct MarioState *m) {
599
s32 animation;
600
601
if (m->input & INPUT_B_PRESSED) {
602
return set_mario_action(m, ACT_DIVE, 0);
603
}
604
605
if (m->input & INPUT_Z_PRESSED) {
606
return set_mario_action(m, ACT_GROUND_POUND, 0);
607
}
608
609
switch (m->actionArg) {
610
case 0:
611
animation = MARIO_ANIM_GENERAL_FALL;
612
break;
613
case 1:
614
animation = MARIO_ANIM_FALL_FROM_SLIDE;
615
break;
616
case 2:
617
animation = MARIO_ANIM_FALL_FROM_SLIDE_KICK;
618
break;
619
}
620
621
common_air_action_step(m, ACT_FREEFALL_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB);
622
return FALSE;
623
}
624
625
s32 act_hold_jump(struct MarioState *m) {
626
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
627
return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
628
}
629
630
if ((m->input & INPUT_B_PRESSED) && !(m->heldObj->oInteractionSubtype & INT_SUBTYPE_HOLDABLE_NPC)) {
631
return set_mario_action(m, ACT_AIR_THROW, 0);
632
}
633
634
if (m->input & INPUT_Z_PRESSED) {
635
return drop_and_set_mario_action(m, ACT_GROUND_POUND, 0);
636
}
637
638
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
639
common_air_action_step(m, ACT_HOLD_JUMP_LAND, MARIO_ANIM_JUMP_WITH_LIGHT_OBJ,
640
AIR_STEP_CHECK_LEDGE_GRAB);
641
return FALSE;
642
}
643
644
s32 act_hold_freefall(struct MarioState *m) {
645
s32 animation;
646
if (m->actionArg == 0) {
647
animation = MARIO_ANIM_FALL_WITH_LIGHT_OBJ;
648
} else {
649
animation = MARIO_ANIM_FALL_FROM_SLIDING_WITH_LIGHT_OBJ;
650
}
651
652
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
653
return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
654
}
655
656
if ((m->input & INPUT_B_PRESSED) && !(m->heldObj->oInteractionSubtype & INT_SUBTYPE_HOLDABLE_NPC)) {
657
return set_mario_action(m, ACT_AIR_THROW, 0);
658
}
659
660
if (m->input & INPUT_Z_PRESSED) {
661
return drop_and_set_mario_action(m, ACT_GROUND_POUND, 0);
662
}
663
664
common_air_action_step(m, ACT_HOLD_FREEFALL_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB);
665
return FALSE;
666
}
667
668
s32 act_side_flip(struct MarioState *m) {
669
if (m->input & INPUT_B_PRESSED) {
670
return set_mario_action(m, ACT_DIVE, 0);
671
}
672
673
if (m->input & INPUT_Z_PRESSED) {
674
if (configApplyBugFixes)
675
m->marioObj->header.gfx.angle[1] += 0x8000;
676
return set_mario_action(m, ACT_GROUND_POUND, 0);
677
}
678
679
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
680
681
if (common_air_action_step(m, ACT_SIDE_FLIP_LAND, MARIO_ANIM_SLIDEFLIP, AIR_STEP_CHECK_LEDGE_GRAB)
682
!= AIR_STEP_GRABBED_LEDGE) {
683
m->marioObj->header.gfx.angle[1] += 0x8000;
684
}
685
686
// This must be one line to match on -O2
687
// clang-format off
688
if (m->marioObj->header.gfx.animInfo.animFrame == 6) play_sound(SOUND_ACTION_SIDE_FLIP_UNK, m->marioObj->header.gfx.cameraToObject);
689
// clang-format on
690
return FALSE;
691
}
692
693
s32 act_wall_kick_air(struct MarioState *m) {
694
if (m->input & INPUT_B_PRESSED) {
695
return set_mario_action(m, ACT_DIVE, 0);
696
}
697
698
if (m->input & INPUT_Z_PRESSED) {
699
return set_mario_action(m, ACT_GROUND_POUND, 0);
700
}
701
702
play_mario_jump_sound(m);
703
common_air_action_step(m, ACT_JUMP_LAND, MARIO_ANIM_SLIDEJUMP, AIR_STEP_CHECK_LEDGE_GRAB);
704
return FALSE;
705
}
706
707
s32 act_long_jump(struct MarioState *m) {
708
s32 animation;
709
if (!m->marioObj->oMarioLongJumpIsSlow) {
710
animation = MARIO_ANIM_FAST_LONGJUMP;
711
} else {
712
animation = MARIO_ANIM_SLOW_LONGJUMP;
713
}
714
715
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
716
717
if (m->floor->type == SURFACE_VERTICAL_WIND && m->actionState == 0) {
718
play_sound(SOUND_MARIO_HERE_WE_GO, m->marioObj->header.gfx.cameraToObject);
719
m->actionState = 1;
720
}
721
722
common_air_action_step(m, ACT_LONG_JUMP_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB);
723
#if ENABLE_RUMBLE
724
if (m->action == ACT_LONG_JUMP_LAND) {
725
queue_rumble_data(5, 40);
726
}
727
#endif
728
return FALSE;
729
}
730
731
s32 act_riding_shell_air(struct MarioState *m) {
732
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
733
set_mario_animation(m, MARIO_ANIM_JUMP_RIDING_SHELL);
734
735
update_air_without_turn(m, 1);
736
737
switch (perform_air_step(m, 0)) {
738
case AIR_STEP_LANDED:
739
set_mario_action(m, ACT_RIDING_SHELL_GROUND, 1);
740
break;
741
742
case AIR_STEP_HIT_WALL:
743
mario_set_forward_vel(m, 0.0f);
744
break;
745
746
case AIR_STEP_HIT_LAVA_WALL:
747
lava_boost_on_wall(m);
748
break;
749
}
750
751
m->marioObj->header.gfx.pos[1] += 42.0f;
752
return FALSE;
753
}
754
755
s32 act_twirling(struct MarioState *m) {
756
s16 startTwirlYaw = m->twirlYaw;
757
s16 yawVelTarget;
758
759
if (m->input & INPUT_A_DOWN) {
760
yawVelTarget = 0x2000;
761
} else {
762
yawVelTarget = 0x1800;
763
}
764
765
m->angleVel[1] = approach_s32(m->angleVel[1], yawVelTarget, 0x200, 0x200);
766
m->twirlYaw += m->angleVel[1];
767
768
set_mario_animation(m, m->actionArg == 0 ? MARIO_ANIM_START_TWIRL : MARIO_ANIM_TWIRL);
769
if (is_anim_past_end(m)) {
770
m->actionArg = 1;
771
}
772
773
if (startTwirlYaw > m->twirlYaw) {
774
play_sound(SOUND_ACTION_TWIRL, m->marioObj->header.gfx.cameraToObject);
775
}
776
777
update_lava_boost_or_twirling(m);
778
779
switch (perform_air_step(m, 0)) {
780
case AIR_STEP_LANDED:
781
set_mario_action(m, ACT_TWIRL_LAND, 0);
782
break;
783
784
case AIR_STEP_HIT_WALL:
785
mario_bonk_reflection(m, FALSE);
786
break;
787
788
case AIR_STEP_HIT_LAVA_WALL:
789
lava_boost_on_wall(m);
790
break;
791
}
792
793
m->marioObj->header.gfx.angle[1] += m->twirlYaw;
794
#if ENABLE_RUMBLE
795
reset_rumble_timers();
796
#endif
797
return FALSE;
798
}
799
800
s32 act_dive(struct MarioState *m) {
801
if (m->actionArg == 0) {
802
play_mario_sound(m, SOUND_ACTION_THROW, SOUND_MARIO_HOOHOO);
803
} else {
804
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
805
}
806
807
set_mario_animation(m, MARIO_ANIM_DIVE);
808
if (mario_check_object_grab(m)) {
809
mario_grab_used_object(m);
810
m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ;
811
if (m->action != ACT_DIVE) {
812
return TRUE;
813
}
814
}
815
816
update_air_without_turn(m, 0);
817
818
switch (perform_air_step(m, 0)) {
819
case AIR_STEP_NONE:
820
if (m->vel[1] < 0.0f && m->faceAngle[0] > -0x2AAA) {
821
m->faceAngle[0] -= 0x200;
822
if (m->faceAngle[0] < -0x2AAA) {
823
m->faceAngle[0] = -0x2AAA;
824
}
825
}
826
m->marioObj->header.gfx.angle[0] = -m->faceAngle[0];
827
break;
828
829
case AIR_STEP_LANDED:
830
if (should_get_stuck_in_ground(m) && m->faceAngle[0] == -0x2AAA) {
831
#if ENABLE_RUMBLE
832
queue_rumble_data(5, 80);
833
#endif
834
#ifdef VERSION_JP
835
play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
836
#else
837
play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
838
#endif
839
m->particleFlags |= PARTICLE_MIST_CIRCLE;
840
drop_and_set_mario_action(m, ACT_HEAD_STUCK_IN_GROUND, 0);
841
} else if (!check_fall_damage(m, ACT_HARD_FORWARD_GROUND_KB)) {
842
if (m->heldObj == NULL) {
843
if (configRolling && m->input & INPUT_Z_DOWN) {
844
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
845
set_mario_action(m, ACT_ROLL, 0);
846
}
847
else
848
set_mario_action(m, ACT_DIVE_SLIDE, 0);
849
} else {
850
set_mario_action(m, ACT_DIVE_PICKING_UP, 0);
851
}
852
}
853
m->faceAngle[0] = 0;
854
break;
855
856
case AIR_STEP_HIT_WALL:
857
mario_bonk_reflection(m, TRUE);
858
m->faceAngle[0] = 0;
859
860
if (m->vel[1] > 0.0f) {
861
m->vel[1] = 0.0f;
862
}
863
864
m->particleFlags |= PARTICLE_VERTICAL_STAR;
865
drop_and_set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
866
break;
867
868
case AIR_STEP_HIT_LAVA_WALL:
869
lava_boost_on_wall(m);
870
break;
871
}
872
873
return FALSE;
874
}
875
876
s32 act_air_throw(struct MarioState *m) {
877
if (++(m->actionTimer) == 4) {
878
mario_throw_held_object(m);
879
}
880
881
play_sound_if_no_flag(m, SOUND_MARIO_WAH2, MARIO_MARIO_SOUND_PLAYED);
882
set_mario_animation(m, MARIO_ANIM_THROW_LIGHT_OBJECT);
883
update_air_without_turn(m, 1);
884
885
switch (perform_air_step(m, 0)) {
886
case AIR_STEP_LANDED:
887
if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
888
m->action = ACT_AIR_THROW_LAND;
889
}
890
break;
891
892
case AIR_STEP_HIT_WALL:
893
mario_set_forward_vel(m, 0.0f);
894
break;
895
896
case AIR_STEP_HIT_LAVA_WALL:
897
lava_boost_on_wall(m);
898
break;
899
}
900
901
return FALSE;
902
}
903
904
s32 act_water_jump(struct MarioState *m) {
905
if (configImprovedSwimming) {
906
if (m->forwardVel < 18.0f) {
907
mario_set_forward_vel(m, 18.0f);
908
}
909
}
910
else {
911
if (m->forwardVel < 15.0f) {
912
mario_set_forward_vel(m, 15.0f);
913
}
914
}
915
916
play_mario_sound(m, SOUND_ACTION_UNKNOWN432, 0);
917
set_mario_animation(m, MARIO_ANIM_SINGLE_JUMP);
918
919
switch (perform_air_step(m, AIR_STEP_CHECK_LEDGE_GRAB)) {
920
case AIR_STEP_LANDED:
921
set_mario_action(m, ACT_JUMP_LAND, 0);
922
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
923
break;
924
925
case AIR_STEP_HIT_WALL:
926
if (configImprovedSwimming) {
927
mario_set_forward_vel(m, 18.0f);
928
}
929
else {
930
mario_set_forward_vel(m, 15.0f);
931
}
932
break;
933
934
case AIR_STEP_GRABBED_LEDGE:
935
#ifndef VERSION_JP
936
set_mario_animation(m, MARIO_ANIM_IDLE_ON_LEDGE);
937
#endif
938
set_mario_action(m, ACT_LEDGE_GRAB, 0);
939
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
940
break;
941
942
case AIR_STEP_HIT_LAVA_WALL:
943
lava_boost_on_wall(m);
944
break;
945
}
946
947
return FALSE;
948
}
949
950
s32 act_hold_water_jump(struct MarioState *m) {
951
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
952
return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
953
}
954
955
if (configImprovedSwimming) {
956
if (m->forwardVel < 18.0f) {
957
mario_set_forward_vel(m, 18.0f);
958
}
959
}
960
else {
961
if (m->forwardVel < 15.0f) {
962
mario_set_forward_vel(m, 15.0f);
963
}
964
}
965
966
play_mario_sound(m, SOUND_ACTION_UNKNOWN432, 0);
967
set_mario_animation(m, MARIO_ANIM_JUMP_WITH_LIGHT_OBJ);
968
969
switch (perform_air_step(m, 0)) {
970
case AIR_STEP_LANDED:
971
set_mario_action(m, ACT_HOLD_JUMP_LAND, 0);
972
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
973
break;
974
975
case AIR_STEP_HIT_WALL:
976
if (configImprovedSwimming) {
977
mario_set_forward_vel(m, 18.0f);
978
}
979
else {
980
mario_set_forward_vel(m, 15.0f);
981
}
982
break;
983
984
case AIR_STEP_HIT_LAVA_WALL:
985
lava_boost_on_wall(m);
986
break;
987
}
988
989
return FALSE;
990
}
991
992
s32 act_steep_jump(struct MarioState *m) {
993
if (m->input & INPUT_B_PRESSED) {
994
return set_mario_action(m, ACT_DIVE, 0);
995
}
996
997
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
998
mario_set_forward_vel(m, 0.98f * m->forwardVel);
999
1000
switch (perform_air_step(m, 0)) {
1001
case AIR_STEP_LANDED:
1002
if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
1003
m->faceAngle[0] = 0;
1004
set_mario_action(m, m->forwardVel < 0.0f ? ACT_BEGIN_SLIDING : ACT_JUMP_LAND, 0);
1005
}
1006
break;
1007
1008
case AIR_STEP_HIT_WALL:
1009
mario_set_forward_vel(m, 0.0f);
1010
break;
1011
1012
case AIR_STEP_HIT_LAVA_WALL:
1013
lava_boost_on_wall(m);
1014
break;
1015
}
1016
1017
set_mario_animation(m, MARIO_ANIM_SINGLE_JUMP);
1018
m->marioObj->header.gfx.angle[1] = m->marioObj->oMarioSteepJumpYaw;
1019
return FALSE;
1020
}
1021
1022
s32 act_ground_pound(struct MarioState *m) {
1023
u32 stepResult;
1024
f32 yOffset;
1025
u8 lagTime;
1026
1027
play_sound_if_no_flag(m, SOUND_ACTION_THROW, MARIO_ACTION_SOUND_PLAYED);
1028
1029
if (m->actionState == 0) {
1030
1031
if (configApplyBugFixes > 2) {
1032
m->vel[1] = 0.0f;
1033
stepResult = perform_air_step(m, 0);
1034
}
1035
1036
if (m->actionTimer < 10) {
1037
yOffset = 20 - 2 * m->actionTimer;
1038
if (m->pos[1] + yOffset + 160.0f < m->ceilHeight) {
1039
m->pos[1] += yOffset;
1040
m->peakHeight = m->pos[1];
1041
vec3f_copy(m->marioObj->header.gfx.pos, m->pos);
1042
}
1043
if (configImprovedControls) {
1044
m->vel[1] = -24.0f;
1045
}
1046
}
1047
else if (configImprovedControls) {
1048
m->vel[1] = -54.0f;
1049
}
1050
1051
if (!configImprovedControls) {
1052
m->vel[1] = -50.0f;
1053
}
1054
mario_set_forward_vel(m, 0.0f);
1055
1056
set_mario_animation(m, m->actionArg == 0 ? MARIO_ANIM_START_GROUND_POUND
1057
: MARIO_ANIM_TRIPLE_JUMP_GROUND_POUND);
1058
if (m->actionTimer == 0) {
1059
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
1060
}
1061
1062
m->actionTimer++;
1063
if (configImprovedControls) {
1064
lagTime = 2;
1065
}
1066
else {
1067
lagTime = 4;
1068
}
1069
if (m->actionTimer >= m->marioObj->header.gfx.animInfo.curAnim->loopEnd + lagTime) {
1070
play_sound(SOUND_MARIO_GROUND_POUND_WAH, m->marioObj->header.gfx.cameraToObject);
1071
m->actionState = 1;
1072
}
1073
} else {
1074
set_mario_animation(m, MARIO_ANIM_GROUND_POUND);
1075
1076
stepResult = perform_air_step(m, 0);
1077
if (stepResult == AIR_STEP_LANDED) {
1078
if (should_get_stuck_in_ground(m)) {
1079
#if ENABLE_RUMBLE
1080
queue_rumble_data(5, 80);
1081
#endif
1082
#ifdef VERSION_JP
1083
play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
1084
#else
1085
play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
1086
#endif
1087
m->particleFlags |= PARTICLE_MIST_CIRCLE;
1088
set_mario_action(m, ACT_BUTT_STUCK_IN_GROUND, 0);
1089
} else {
1090
play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_HEAVY_LANDING);
1091
if (!check_fall_damage(m, ACT_HARD_BACKWARD_GROUND_KB)) {
1092
m->particleFlags |= PARTICLE_MIST_CIRCLE | PARTICLE_HORIZONTAL_STAR;
1093
set_mario_action(m, ACT_GROUND_POUND_LAND, 0);
1094
}
1095
}
1096
set_camera_shake_from_hit(SHAKE_GROUND_POUND);
1097
} else if (!configImprovedControls && stepResult == AIR_STEP_HIT_WALL) {
1098
mario_set_forward_vel(m, -16.0f);
1099
if (m->vel[1] > 0.0f) {
1100
m->vel[1] = 0.0f;
1101
}
1102
1103
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1104
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
1105
}
1106
}
1107
1108
if (configOdysseyDive && m->input & INPUT_B_PRESSED) {
1109
set_mario_action(m, ACT_DIVE, 0);
1110
mario_set_forward_vel(m, 40.0f);
1111
m->vel[1] = 28;
1112
}
1113
1114
return FALSE;
1115
}
1116
1117
s32 act_burning_jump(struct MarioState *m) {
1118
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, m->actionArg == 0 ? 0 : -1);
1119
mario_set_forward_vel(m, m->forwardVel);
1120
1121
if (perform_air_step(m, 0) == AIR_STEP_LANDED) {
1122
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1123
set_mario_action(m, ACT_BURNING_GROUND, 0);
1124
}
1125
1126
set_mario_animation(m, m->actionArg == 0 ? MARIO_ANIM_SINGLE_JUMP : MARIO_ANIM_FIRE_LAVA_BURN);
1127
m->particleFlags |= PARTICLE_FIRE;
1128
play_sound(SOUND_MOVING_LAVA_BURN, m->marioObj->header.gfx.cameraToObject);
1129
1130
m->marioObj->oMarioBurnTimer += 3;
1131
1132
m->health -= 10;
1133
if (m->health < 0x100) {
1134
m->health = 0xFF;
1135
}
1136
#if ENABLE_RUMBLE
1137
reset_rumble_timers();
1138
#endif
1139
return FALSE;
1140
}
1141
1142
s32 act_burning_fall(struct MarioState *m) {
1143
mario_set_forward_vel(m, m->forwardVel);
1144
1145
if (perform_air_step(m, 0) == AIR_STEP_LANDED) {
1146
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1147
set_mario_action(m, ACT_BURNING_GROUND, 0);
1148
}
1149
1150
set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
1151
m->particleFlags |= PARTICLE_FIRE;
1152
m->marioObj->oMarioBurnTimer += 3;
1153
1154
m->health -= 10;
1155
if (m->health < 0x100) {
1156
m->health = 0xFF;
1157
}
1158
#if ENABLE_RUMBLE
1159
reset_rumble_timers();
1160
#endif
1161
return FALSE;
1162
}
1163
1164
s32 act_crazy_box_bounce(struct MarioState *m) {
1165
f32 minSpeed;
1166
1167
if (m->actionTimer == 0) {
1168
switch (m->actionArg) {
1169
case 0:
1170
m->vel[1] = 45.0f;
1171
minSpeed = 32.0f;
1172
break;
1173
1174
case 1:
1175
m->vel[1] = 60.0f;
1176
minSpeed = 36.0f;
1177
break;
1178
1179
case 2:
1180
m->vel[1] = 100.0f;
1181
minSpeed = 48.0f;
1182
break;
1183
}
1184
1185
play_sound(minSpeed < 40.0f ? SOUND_GENERAL_BOING1 : SOUND_GENERAL_BOING2,
1186
m->marioObj->header.gfx.cameraToObject);
1187
1188
if (m->forwardVel < minSpeed) {
1189
mario_set_forward_vel(m, minSpeed);
1190
}
1191
1192
m->actionTimer = 1;
1193
}
1194
1195
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
1196
set_mario_animation(m, MARIO_ANIM_DIVE);
1197
1198
update_air_without_turn(m, 0);
1199
1200
switch (perform_air_step(m, 0)) {
1201
case AIR_STEP_LANDED:
1202
if (m->actionArg < 2) {
1203
set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, m->actionArg + 1);
1204
} else {
1205
m->heldObj->oInteractStatus = INT_STATUS_STOP_RIDING;
1206
m->heldObj = NULL;
1207
set_mario_action(m, ACT_STOMACH_SLIDE, 0);
1208
}
1209
#if ENABLE_RUMBLE
1210
queue_rumble_data(5, 80);
1211
#endif
1212
m->particleFlags |= PARTICLE_MIST_CIRCLE;
1213
break;
1214
1215
case AIR_STEP_HIT_WALL:
1216
mario_bonk_reflection(m, FALSE);
1217
break;
1218
1219
case AIR_STEP_HIT_LAVA_WALL:
1220
lava_boost_on_wall(m);
1221
break;
1222
}
1223
1224
m->marioObj->header.gfx.angle[0] = atan2s(m->forwardVel, -m->vel[1]);
1225
return FALSE;
1226
}
1227
1228
u32 common_air_knockback_step(struct MarioState *m, u32 landAction, u32 hardFallAction, s32 animation,
1229
f32 speed) {
1230
u32 stepResult;
1231
1232
mario_set_forward_vel(m, speed);
1233
1234
stepResult = perform_air_step(m, 0);
1235
switch (stepResult) {
1236
case AIR_STEP_NONE:
1237
set_mario_animation(m, animation);
1238
break;
1239
1240
case AIR_STEP_LANDED:
1241
#if ENABLE_RUMBLE
1242
if (m->action != ACT_SOFT_BONK) {
1243
queue_rumble_data(5, 40);
1244
}
1245
#endif
1246
if (!check_fall_damage_or_get_stuck(m, hardFallAction)) {
1247
#ifndef VERSION_JP
1248
if (m->action == ACT_THROWN_FORWARD || m->action == ACT_THROWN_BACKWARD) {
1249
set_mario_action(m, landAction, m->hurtCounter);
1250
} else {
1251
set_mario_action(m, landAction, m->actionArg);
1252
}
1253
#else
1254
set_mario_action(m, landAction, m->actionArg);
1255
#endif
1256
}
1257
break;
1258
1259
case AIR_STEP_HIT_WALL:
1260
set_mario_animation(m, MARIO_ANIM_BACKWARD_AIR_KB);
1261
mario_bonk_reflection(m, FALSE);
1262
1263
if (m->vel[1] > 0.0f) {
1264
m->vel[1] = 0.0f;
1265
}
1266
1267
mario_set_forward_vel(m, -speed);
1268
break;
1269
1270
case AIR_STEP_HIT_LAVA_WALL:
1271
lava_boost_on_wall(m);
1272
break;
1273
}
1274
1275
return stepResult;
1276
}
1277
1278
s32 check_wall_kick(struct MarioState *m) {
1279
if ((m->input & INPUT_A_PRESSED) && m->wallKickTimer != 0 && m->prevAction == ACT_AIR_HIT_WALL) {
1280
m->faceAngle[1] += 0x8000;
1281
if (configWallSliding) {
1282
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1283
}
1284
return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
1285
}
1286
1287
return FALSE;
1288
}
1289
1290
s32 act_wall_slide(struct MarioState *m) {
1291
m->marioObj->header.gfx.angle[1] = m->faceAngle[1];
1292
if (m->input & INPUT_A_PRESSED) {
1293
m->faceAngle[1] += 0x8000;
1294
mario_set_forward_vel(m, 32.0f);
1295
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1296
return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
1297
}
1298
switch (perform_air_step(m, 0)) {
1299
case AIR_STEP_NONE:
1300
set_mario_action(m, ACT_FREEFALL, 0);
1301
break;
1302
1303
case AIR_STEP_LANDED:
1304
set_mario_action(m, ACT_JUMP_LAND_STOP, 0);
1305
break;
1306
1307
case AIR_STEP_HIT_LAVA_WALL:
1308
lava_boost_on_wall(m);
1309
break;
1310
}
1311
if (m->vel[1] < -20.0f) {
1312
m->vel[1] = -20.0f;
1313
}
1314
mario_set_forward_vel(m, 1.0f);
1315
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
1316
m->particleFlags |= PARTICLE_DUST;
1317
m->marioObj->header.gfx.angle[1] = m->faceAngle[1]+0x8000;
1318
return FALSE;
1319
}
1320
1321
s32 act_backward_air_kb(struct MarioState *m) {
1322
if (check_wall_kick(m)) {
1323
return TRUE;
1324
}
1325
1326
#ifndef VERSION_JP
1327
play_knockback_sound(m);
1328
#else
1329
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
1330
#endif
1331
common_air_knockback_step(m, ACT_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB, 0x0002, -16.0f);
1332
return FALSE;
1333
}
1334
1335
s32 act_forward_air_kb(struct MarioState *m) {
1336
if (check_wall_kick(m)) {
1337
return TRUE;
1338
}
1339
1340
#ifndef VERSION_JP
1341
play_knockback_sound(m);
1342
#else
1343
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
1344
#endif
1345
common_air_knockback_step(m, ACT_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB, 0x002D, 16.0f);
1346
return FALSE;
1347
}
1348
1349
s32 act_hard_backward_air_kb(struct MarioState *m) {
1350
#ifndef VERSION_JP
1351
play_knockback_sound(m);
1352
#else
1353
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
1354
#endif
1355
common_air_knockback_step(m, ACT_HARD_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB, 0x0002,
1356
-16.0f);
1357
return FALSE;
1358
}
1359
1360
s32 act_hard_forward_air_kb(struct MarioState *m) {
1361
#ifndef VERSION_JP
1362
play_knockback_sound(m);
1363
#else
1364
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
1365
#endif
1366
common_air_knockback_step(m, ACT_HARD_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB, 0x002D, 16.0f);
1367
return FALSE;
1368
}
1369
1370
s32 act_thrown_backward(struct MarioState *m) {
1371
u32 landAction;
1372
if (m->actionArg != 0) {
1373
landAction = ACT_HARD_BACKWARD_GROUND_KB;
1374
} else {
1375
landAction = ACT_BACKWARD_GROUND_KB;
1376
}
1377
1378
play_sound_if_no_flag(m, SOUND_MARIO_WAAAOOOW, MARIO_MARIO_SOUND_PLAYED);
1379
1380
common_air_knockback_step(m, landAction, ACT_HARD_BACKWARD_GROUND_KB, 0x0002, m->forwardVel);
1381
1382
m->forwardVel *= 0.98f;
1383
return FALSE;
1384
}
1385
1386
s32 act_thrown_forward(struct MarioState *m) {
1387
s16 pitch;
1388
1389
u32 landAction;
1390
if (m->actionArg != 0) {
1391
landAction = ACT_HARD_FORWARD_GROUND_KB;
1392
} else {
1393
landAction = ACT_FORWARD_GROUND_KB;
1394
}
1395
1396
play_sound_if_no_flag(m, SOUND_MARIO_WAAAOOOW, MARIO_MARIO_SOUND_PLAYED);
1397
1398
if (common_air_knockback_step(m, landAction, ACT_HARD_FORWARD_GROUND_KB, 0x002D, m->forwardVel)
1399
== AIR_STEP_NONE) {
1400
pitch = atan2s(m->forwardVel, -m->vel[1]);
1401
if (pitch > 0x1800) {
1402
pitch = 0x1800;
1403
}
1404
1405
m->marioObj->header.gfx.angle[0] = pitch + 0x1800;
1406
}
1407
1408
m->forwardVel *= 0.98f;
1409
return FALSE;
1410
}
1411
1412
s32 act_soft_bonk(struct MarioState *m) {
1413
if (check_wall_kick(m)) {
1414
return TRUE;
1415
}
1416
1417
#ifndef VERSION_JP
1418
play_knockback_sound(m);
1419
#else
1420
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
1421
#endif
1422
1423
common_air_knockback_step(m, ACT_FREEFALL_LAND, ACT_HARD_BACKWARD_GROUND_KB, 0x0056, m->forwardVel);
1424
return FALSE;
1425
}
1426
1427
s32 act_getting_blown(struct MarioState *m) {
1428
if (m->actionState == 0) {
1429
if (m->forwardVel > -60.0f) {
1430
m->forwardVel -= 6.0f;
1431
} else {
1432
m->actionState = 1;
1433
}
1434
} else {
1435
if (m->forwardVel < -16.0f) {
1436
m->forwardVel += 0.8f;
1437
}
1438
1439
if (m->vel[1] < 0.0f && m->unkC4 < 4.0f) {
1440
m->unkC4 += 0.05f;
1441
}
1442
}
1443
1444
if (++(m->actionTimer) == 20 && (!configAngryPenguin || gCurrCourseNum != COURSE_CCM)) {
1445
mario_blow_off_cap(m, 50.0f);
1446
}
1447
1448
mario_set_forward_vel(m, m->forwardVel);
1449
#ifdef VERSION_JP
1450
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
1451
#endif
1452
set_mario_animation(m, MARIO_ANIM_BACKWARD_AIR_KB);
1453
1454
switch (perform_air_step(m, 0)) {
1455
case AIR_STEP_LANDED:
1456
set_mario_action(m, ACT_HARD_BACKWARD_AIR_KB, 0);
1457
break;
1458
1459
case AIR_STEP_HIT_WALL:
1460
set_mario_animation(m, MARIO_ANIM_AIR_FORWARD_KB);
1461
mario_bonk_reflection(m, FALSE);
1462
1463
if (m->vel[1] > 0.0f) {
1464
m->vel[1] = 0.0f;
1465
}
1466
1467
mario_set_forward_vel(m, -m->forwardVel);
1468
break;
1469
}
1470
1471
return FALSE;
1472
}
1473
1474
s32 act_air_hit_wall(struct MarioState *m) {
1475
if (m->heldObj != NULL) {
1476
mario_drop_held_object(m);
1477
}
1478
if (configWallSliding) {
1479
if (++(m->actionTimer) <= 2) {
1480
if (m->input & INPUT_A_PRESSED) {
1481
m->vel[1] = 52.0f;
1482
m->faceAngle[1] += 0x8000;
1483
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1484
return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
1485
}
1486
}
1487
else {
1488
m->wallKickTimer = 5;
1489
if (m->vel[1] > 0.0f) {
1490
m->vel[1] = 0.0f;
1491
}
1492
return set_mario_action(m, ACT_WALL_SLIDE, 0);
1493
}
1494
}
1495
else {
1496
if (++(m->actionTimer) <= 2) {
1497
if (m->input & INPUT_A_PRESSED) {
1498
m->vel[1] = 52.0f;
1499
m->faceAngle[1] += 0x8000;
1500
return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
1501
}
1502
} else if (m->forwardVel >= 38.0f) {
1503
m->wallKickTimer = 5;
1504
if (m->vel[1] > 0.0f) {
1505
m->vel[1] = 0.0f;
1506
}
1507
1508
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1509
return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
1510
} else {
1511
m->wallKickTimer = 5;
1512
if (m->vel[1] > 0.0f) {
1513
m->vel[1] = 0.0f;
1514
}
1515
1516
if (m->forwardVel > 8.0f) {
1517
mario_set_forward_vel(m, -8.0f);
1518
}
1519
return set_mario_action(m, ACT_SOFT_BONK, 0);
1520
}
1521
}
1522
1523
#ifdef AVOID_UB
1524
return
1525
#endif
1526
set_mario_animation(m, MARIO_ANIM_START_WALLKICK);
1527
1528
//! Missing return statement. The returned value is the result of the call
1529
// to set_mario_animation. In practice, this value is nonzero.
1530
// This results in this action "cancelling" into itself. It is supposed to
1531
// execute on two frames, but instead it executes twice on the same frame.
1532
// This results in firsties only being possible for a single frame, instead
1533
// of two.
1534
}
1535
1536
s32 act_forward_rollout(struct MarioState *m) {
1537
if (m->actionState == 0) {
1538
m->vel[1] = 30.0f;
1539
m->actionState = 1;
1540
}
1541
1542
if (!configFlashbackGroundPound)
1543
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
1544
1545
update_air_without_turn(m, 0);
1546
1547
switch (perform_air_step(m, 0)) {
1548
case AIR_STEP_NONE:
1549
if (m->actionState == 1) {
1550
if (set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING) == 4) {
1551
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
1552
}
1553
} else {
1554
set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
1555
}
1556
break;
1557
1558
case AIR_STEP_LANDED:
1559
set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
1560
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1561
break;
1562
1563
case AIR_STEP_HIT_WALL:
1564
mario_set_forward_vel(m, 0.0f);
1565
break;
1566
1567
case AIR_STEP_HIT_LAVA_WALL:
1568
lava_boost_on_wall(m);
1569
break;
1570
}
1571
1572
if (m->actionState == 1 && is_anim_past_end(m)) {
1573
m->actionState = 2;
1574
}
1575
return FALSE;
1576
}
1577
1578
s32 act_backward_rollout(struct MarioState *m) {
1579
if (m->actionState == 0) {
1580
m->vel[1] = 30.0f;
1581
m->actionState = 1;
1582
}
1583
1584
if (!configFlashbackGroundPound)
1585
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
1586
1587
update_air_without_turn(m, 0);
1588
1589
switch (perform_air_step(m, 0)) {
1590
case AIR_STEP_NONE:
1591
if (m->actionState == 1) {
1592
if (set_mario_animation(m, MARIO_ANIM_BACKWARD_SPINNING) == 4) {
1593
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
1594
}
1595
} else {
1596
set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
1597
}
1598
break;
1599
1600
case AIR_STEP_LANDED:
1601
set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
1602
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1603
break;
1604
1605
case AIR_STEP_HIT_WALL:
1606
mario_set_forward_vel(m, 0.0f);
1607
break;
1608
1609
case AIR_STEP_HIT_LAVA_WALL:
1610
lava_boost_on_wall(m);
1611
break;
1612
}
1613
1614
if (m->actionState == 1 && m->marioObj->header.gfx.animInfo.animFrame == 2) {
1615
m->actionState = 2;
1616
}
1617
return FALSE;
1618
}
1619
1620
s32 act_butt_slide_air(struct MarioState *m) {
1621
if (++(m->actionTimer) > 30 && m->pos[1] - m->floorHeight > 500.0f) {
1622
return set_mario_action(m, ACT_FREEFALL, 1);
1623
}
1624
1625
update_air_with_turn(m);
1626
1627
switch (perform_air_step(m, 0)) {
1628
case AIR_STEP_LANDED:
1629
if (m->actionState == 0 && m->vel[1] < 0.0f && m->floor->normal.y >= 0.9848077f) {
1630
m->vel[1] = -m->vel[1] / 2.0f;
1631
m->actionState = 1;
1632
} else {
1633
set_mario_action(m, ACT_BUTT_SLIDE, 0);
1634
}
1635
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1636
break;
1637
1638
case AIR_STEP_HIT_WALL:
1639
if (m->vel[1] > 0.0f) {
1640
m->vel[1] = 0.0f;
1641
}
1642
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1643
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
1644
break;
1645
1646
case AIR_STEP_HIT_LAVA_WALL:
1647
lava_boost_on_wall(m);
1648
break;
1649
}
1650
1651
set_mario_animation(m, MARIO_ANIM_SLIDE);
1652
return FALSE;
1653
}
1654
1655
s32 act_hold_butt_slide_air(struct MarioState *m) {
1656
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
1657
return drop_and_set_mario_action(m, ACT_HOLD_FREEFALL, 1);
1658
}
1659
1660
if (++m->actionTimer > 30 && m->pos[1] - m->floorHeight > 500.0f) {
1661
return set_mario_action(m, ACT_HOLD_FREEFALL, 1);
1662
}
1663
1664
update_air_with_turn(m);
1665
1666
switch (perform_air_step(m, 0)) {
1667
case AIR_STEP_LANDED:
1668
if (m->actionState == 0 && m->vel[1] < 0.0f && m->floor->normal.y >= 0.9848077f) {
1669
m->vel[1] = -m->vel[1] / 2.0f;
1670
m->actionState = 1;
1671
} else {
1672
set_mario_action(m, ACT_HOLD_BUTT_SLIDE, 0);
1673
}
1674
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1675
break;
1676
1677
case AIR_STEP_HIT_WALL:
1678
if (m->vel[1] > 0.0f) {
1679
m->vel[1] = 0.0f;
1680
}
1681
1682
mario_drop_held_object(m);
1683
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1684
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
1685
break;
1686
1687
case AIR_STEP_HIT_LAVA_WALL:
1688
lava_boost_on_wall(m);
1689
break;
1690
}
1691
1692
set_mario_animation(m, MARIO_ANIM_SLIDING_ON_BOTTOM_WITH_LIGHT_OBJ);
1693
return FALSE;
1694
}
1695
1696
s32 act_lava_boost(struct MarioState *m) {
1697
#if ENABLE_RUMBLE
1698
if (!(m->flags & MARIO_MARIO_SOUND_PLAYED)) {
1699
#endif
1700
play_sound_if_no_flag(m, SOUND_MARIO_ON_FIRE, MARIO_MARIO_SOUND_PLAYED);
1701
#if ENABLE_RUMBLE
1702
queue_rumble_data(5, 80);
1703
}
1704
#endif
1705
1706
if (!(m->input & INPUT_NONZERO_ANALOG)) {
1707
m->forwardVel = approach_f32(m->forwardVel, 0.0f, 0.35f, 0.35f);
1708
}
1709
1710
update_lava_boost_or_twirling(m);
1711
1712
switch (perform_air_step(m, 0)) {
1713
case AIR_STEP_LANDED:
1714
if (m->floor->type == SURFACE_BURNING) {
1715
m->actionState = 0;
1716
if (!(m->flags & MARIO_METAL_CAP)) {
1717
m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18;
1718
}
1719
m->vel[1] = 84.0f;
1720
play_sound(SOUND_MARIO_ON_FIRE, m->marioObj->header.gfx.cameraToObject);
1721
#if ENABLE_RUMBLE
1722
queue_rumble_data(5, 80);
1723
#endif
1724
} else {
1725
play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
1726
if (m->actionState < 2 && m->vel[1] < 0.0f) {
1727
m->vel[1] = -m->vel[1] * 0.4f;
1728
mario_set_forward_vel(m, m->forwardVel * 0.5f);
1729
m->actionState += 1;
1730
} else {
1731
set_mario_action(m, ACT_LAVA_BOOST_LAND, 0);
1732
}
1733
}
1734
break;
1735
1736
case AIR_STEP_HIT_WALL:
1737
mario_bonk_reflection(m, FALSE);
1738
break;
1739
1740
case AIR_STEP_HIT_LAVA_WALL:
1741
lava_boost_on_wall(m);
1742
break;
1743
}
1744
1745
set_mario_animation(m, MARIO_ANIM_FIRE_LAVA_BURN);
1746
if ((m->area->terrainType & TERRAIN_MASK) != TERRAIN_SNOW && !(m->flags & MARIO_METAL_CAP)
1747
&& m->vel[1] > 0.0f) {
1748
m->particleFlags |= PARTICLE_FIRE;
1749
if (m->actionState == 0) {
1750
play_sound(SOUND_MOVING_LAVA_BURN, m->marioObj->header.gfx.cameraToObject);
1751
}
1752
}
1753
1754
if (m->health < 0x100) {
1755
level_trigger_warp(m, WARP_OP_DEATH);
1756
}
1757
1758
m->marioBodyState->eyeState = MARIO_EYES_DEAD;
1759
#if ENABLE_RUMBLE
1760
reset_rumble_timers();
1761
#endif
1762
return FALSE;
1763
}
1764
1765
s32 act_slide_kick(struct MarioState *m) {
1766
if (m->actionState == 0 && m->actionTimer == 0) {
1767
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_HOOHOO);
1768
set_mario_animation(m, MARIO_ANIM_SLIDE_KICK);
1769
}
1770
1771
if (++(m->actionTimer) > 30 && m->pos[1] - m->floorHeight > 500.0f) {
1772
return set_mario_action(m, ACT_FREEFALL, 2);
1773
}
1774
1775
update_air_without_turn(m, 0);
1776
1777
switch (perform_air_step(m, 0)) {
1778
case AIR_STEP_NONE:
1779
if (m->actionState == 0) {
1780
m->marioObj->header.gfx.angle[0] = atan2s(m->forwardVel, -m->vel[1]);
1781
if (m->marioObj->header.gfx.angle[0] > 0x1800) {
1782
m->marioObj->header.gfx.angle[0] = 0x1800;
1783
}
1784
}
1785
break;
1786
1787
case AIR_STEP_LANDED:
1788
if (m->actionState == 0 && m->vel[1] < 0.0f) {
1789
m->vel[1] = -m->vel[1] / 2.0f;
1790
m->actionState = 1;
1791
m->actionTimer = 0;
1792
} else {
1793
set_mario_action(m, ACT_SLIDE_KICK_SLIDE, 0);
1794
}
1795
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1796
break;
1797
1798
case AIR_STEP_HIT_WALL:
1799
if (m->vel[1] > 0.0f) {
1800
m->vel[1] = 0.0f;
1801
}
1802
1803
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1804
1805
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
1806
break;
1807
1808
case AIR_STEP_HIT_LAVA_WALL:
1809
lava_boost_on_wall(m);
1810
break;
1811
}
1812
1813
return FALSE;
1814
}
1815
1816
s32 act_jump_kick(struct MarioState *m) {
1817
s32 animFrame;
1818
1819
if (m->actionState == 0) {
1820
play_sound_if_no_flag(m, SOUND_MARIO_PUNCH_HOO, MARIO_ACTION_SOUND_PLAYED);
1821
m->marioObj->header.gfx.animInfo.animID = -1;
1822
set_mario_animation(m, MARIO_ANIM_AIR_KICK);
1823
m->actionState = 1;
1824
}
1825
1826
animFrame = m->marioObj->header.gfx.animInfo.animFrame;
1827
if (animFrame == 0) {
1828
m->marioBodyState->punchState = (2 << 6) | 6;
1829
}
1830
if (animFrame >= 0 && animFrame < 8) {
1831
m->flags |= MARIO_KICKING;
1832
}
1833
1834
update_air_without_turn(m, 1);
1835
1836
switch (perform_air_step(m, 0)) {
1837
case AIR_STEP_LANDED:
1838
if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
1839
set_mario_action(m, ACT_FREEFALL_LAND, 0);
1840
}
1841
break;
1842
1843
case AIR_STEP_HIT_WALL:
1844
mario_set_forward_vel(m, 0.0f);
1845
break;
1846
}
1847
1848
return FALSE;
1849
}
1850
1851
s32 act_shot_from_cannon(struct MarioState *m) {
1852
if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
1853
m->statusForCamera->cameraEvent = CAM_EVENT_SHOT_FROM_CANNON;
1854
}
1855
1856
mario_set_forward_vel(m, m->forwardVel);
1857
1858
play_sound_if_no_flag(m, SOUND_MARIO_YAHOO, MARIO_MARIO_SOUND_PLAYED);
1859
1860
switch (perform_air_step(m, 0)) {
1861
case AIR_STEP_NONE:
1862
set_mario_animation(m, MARIO_ANIM_AIRBORNE_ON_STOMACH);
1863
m->faceAngle[0] = atan2s(m->forwardVel, m->vel[1]);
1864
m->marioObj->header.gfx.angle[0] = -m->faceAngle[0];
1865
break;
1866
1867
case AIR_STEP_LANDED:
1868
set_mario_action(m, ACT_DIVE_SLIDE, 0);
1869
m->faceAngle[0] = 0;
1870
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
1871
#if ENABLE_RUMBLE
1872
queue_rumble_data(5, 80);
1873
#endif
1874
break;
1875
1876
case AIR_STEP_HIT_WALL:
1877
mario_set_forward_vel(m, -16.0f);
1878
1879
m->faceAngle[0] = 0;
1880
if (m->vel[1] > 0.0f) {
1881
m->vel[1] = 0.0f;
1882
}
1883
1884
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1885
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
1886
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
1887
break;
1888
1889
case AIR_STEP_HIT_LAVA_WALL:
1890
lava_boost_on_wall(m);
1891
break;
1892
}
1893
1894
if ((m->flags & MARIO_WING_CAP) && m->vel[1] < 0.0f) {
1895
set_mario_action(m, ACT_FLYING, 0);
1896
}
1897
1898
if ((m->forwardVel -= 0.05) < 10.0f) {
1899
mario_set_forward_vel(m, 10.0f);
1900
}
1901
1902
if (m->vel[1] > 0.0f) {
1903
m->particleFlags |= PARTICLE_DUST;
1904
}
1905
#if ENABLE_RUMBLE
1906
reset_rumble_timers();
1907
#endif
1908
return FALSE;
1909
}
1910
1911
s32 act_flying(struct MarioState *m) {
1912
s16 startPitch = m->faceAngle[0];
1913
1914
if (m->input & INPUT_Z_PRESSED) {
1915
if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) {
1916
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
1917
}
1918
return set_mario_action(m, ACT_GROUND_POUND, 1);
1919
}
1920
1921
if (!(m->flags & MARIO_WING_CAP)) {
1922
if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) {
1923
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
1924
}
1925
return set_mario_action(m, ACT_FREEFALL, 0);
1926
}
1927
1928
if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
1929
set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1);
1930
}
1931
1932
if (m->actionState == 0) {
1933
if (m->actionArg == 0) {
1934
set_mario_animation(m, MARIO_ANIM_FLY_FROM_CANNON);
1935
} else {
1936
set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP);
1937
if (m->marioObj->header.gfx.animInfo.animFrame == 1) {
1938
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
1939
}
1940
}
1941
1942
if (is_anim_at_end(m)) {
1943
if (m->actionArg == 2) {
1944
load_level_init_text(0);
1945
m->actionArg = 1;
1946
}
1947
1948
set_mario_animation(m, MARIO_ANIM_WING_CAP_FLY);
1949
m->actionState = 1;
1950
}
1951
}
1952
1953
update_flying(m);
1954
1955
switch (perform_air_step(m, 0)) {
1956
case AIR_STEP_NONE:
1957
m->marioObj->header.gfx.angle[0] = -m->faceAngle[0];
1958
m->marioObj->header.gfx.angle[2] = m->faceAngle[2];
1959
m->actionTimer = 0;
1960
break;
1961
1962
case AIR_STEP_LANDED:
1963
set_mario_action(m, ACT_DIVE_SLIDE, 0);
1964
1965
set_mario_animation(m, MARIO_ANIM_DIVE);
1966
set_anim_to_frame(m, 7);
1967
1968
m->faceAngle[0] = 0;
1969
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
1970
#if ENABLE_RUMBLE
1971
queue_rumble_data(5, 60);
1972
#endif
1973
break;
1974
1975
case AIR_STEP_HIT_WALL:
1976
if (m->wall != NULL) {
1977
mario_set_forward_vel(m, -16.0f);
1978
m->faceAngle[0] = 0;
1979
1980
if (m->vel[1] > 0.0f) {
1981
m->vel[1] = 0.0f;
1982
}
1983
1984
play_sound((m->flags & MARIO_METAL_CAP) ? SOUND_ACTION_METAL_BONK
1985
: SOUND_ACTION_BONK,
1986
m->marioObj->header.gfx.cameraToObject);
1987
1988
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1989
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
1990
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
1991
} else {
1992
if (m->actionTimer++ == 0) {
1993
play_sound(SOUND_ACTION_HIT, m->marioObj->header.gfx.cameraToObject);
1994
}
1995
1996
if (m->actionTimer == 30) {
1997
m->actionTimer = 0;
1998
}
1999
2000
m->faceAngle[0] -= 0x200;
2001
if (m->faceAngle[0] < -0x2AAA) {
2002
m->faceAngle[0] = -0x2AAA;
2003
}
2004
2005
m->marioObj->header.gfx.angle[0] = -m->faceAngle[0];
2006
m->marioObj->header.gfx.angle[2] = m->faceAngle[2];
2007
}
2008
break;
2009
2010
case AIR_STEP_HIT_LAVA_WALL:
2011
lava_boost_on_wall(m);
2012
break;
2013
}
2014
2015
if (m->faceAngle[0] > 0x800 && m->forwardVel >= 48.0f) {
2016
m->particleFlags |= PARTICLE_DUST;
2017
}
2018
2019
if (startPitch <= 0 && m->faceAngle[0] > 0 && m->forwardVel >= 48.0f) {
2020
play_sound(SOUND_ACTION_FLYING_FAST, m->marioObj->header.gfx.cameraToObject);
2021
#ifndef VERSION_JP
2022
play_sound(SOUND_MARIO_YAHOO_WAHA_YIPPEE + ((gAudioRandom % 5) << 16),
2023
m->marioObj->header.gfx.cameraToObject);
2024
#endif
2025
#if ENABLE_RUMBLE
2026
queue_rumble_data(50, 40);
2027
#endif
2028
}
2029
2030
play_sound(SOUND_MOVING_FLYING, m->marioObj->header.gfx.cameraToObject);
2031
adjust_sound_for_speed(m);
2032
return FALSE;
2033
}
2034
2035
s32 act_riding_hoot(struct MarioState *m) {
2036
if (((!(m->input & INPUT_A_DOWN) && !configImprovedHanging) || ((m->input & INPUT_A_PRESSED) && configImprovedHanging))
2037
|| (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK7)) {
2038
m->usedObj->oInteractStatus = 0;
2039
m->usedObj->oHootMarioReleaseTime = gGlobalTimer;
2040
2041
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
2042
#if ENABLE_RUMBLE
2043
queue_rumble_data(4, 40);
2044
#endif
2045
return set_mario_action(m, ACT_FREEFALL, 0);
2046
}
2047
2048
m->pos[0] = m->usedObj->oPosX;
2049
m->pos[1] = m->usedObj->oPosY - 92.5f;
2050
m->pos[2] = m->usedObj->oPosZ;
2051
2052
m->faceAngle[1] = 0x4000 - m->usedObj->oMoveAngleYaw;
2053
2054
if (m->actionState == 0) {
2055
set_mario_animation(m, MARIO_ANIM_HANG_ON_CEILING);
2056
if (is_anim_at_end(m)) {
2057
set_mario_animation(m, MARIO_ANIM_HANG_ON_OWL);
2058
m->actionState = 1;
2059
}
2060
}
2061
2062
vec3f_set(m->vel, 0.0f, 0.0f, 0.0f);
2063
vec3f_set(m->marioObj->header.gfx.pos, m->pos[0], m->pos[1], m->pos[2]);
2064
vec3s_set(m->marioObj->header.gfx.angle, 0, 0x4000 - m->faceAngle[1], 0);
2065
return FALSE;
2066
}
2067
2068
s32 act_flying_triple_jump(struct MarioState *m) {
2069
#ifndef VERSION_JP
2070
if (m->input & (INPUT_B_PRESSED | INPUT_Z_PRESSED)) {
2071
if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) {
2072
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
2073
}
2074
if (m->input & INPUT_B_PRESSED) {
2075
return set_mario_action(m, ACT_DIVE, 0);
2076
} else {
2077
return set_mario_action(m, ACT_GROUND_POUND, 0);
2078
}
2079
}
2080
#else
2081
if (m->input & INPUT_B_PRESSED) {
2082
return set_mario_action(m, ACT_DIVE, 0);
2083
}
2084
2085
if (m->input & INPUT_Z_PRESSED) {
2086
return set_mario_action(m, ACT_GROUND_POUND, 0);
2087
}
2088
#endif
2089
2090
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
2091
if (m->actionState == 0) {
2092
set_mario_animation(m, MARIO_ANIM_TRIPLE_JUMP_FLY);
2093
2094
if (m->marioObj->header.gfx.animInfo.animFrame == 7) {
2095
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
2096
}
2097
2098
if (is_anim_past_end(m)) {
2099
set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING);
2100
#if ENABLE_RUMBLE
2101
queue_rumble_data(8, 80);
2102
#endif
2103
m->actionState = 1;
2104
}
2105
}
2106
2107
if (m->actionState == 1 && m->marioObj->header.gfx.animInfo.animFrame == 1) {
2108
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
2109
}
2110
2111
if (m->vel[1] < 4.0f) {
2112
if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
2113
set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1);
2114
}
2115
2116
if (m->forwardVel < 32.0f) {
2117
mario_set_forward_vel(m, 32.0f);
2118
}
2119
2120
set_mario_action(m, ACT_FLYING, 1);
2121
}
2122
2123
if (m->actionTimer++ == 10 && m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
2124
set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1);
2125
}
2126
2127
update_air_without_turn(m, 1);
2128
2129
switch (perform_air_step(m, 0)) {
2130
case AIR_STEP_LANDED:
2131
if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
2132
set_mario_action(m, ACT_DOUBLE_JUMP_LAND, 0);
2133
}
2134
break;
2135
2136
case AIR_STEP_HIT_WALL:
2137
mario_bonk_reflection(m, FALSE);
2138
break;
2139
2140
case AIR_STEP_HIT_LAVA_WALL:
2141
lava_boost_on_wall(m);
2142
break;
2143
}
2144
2145
return FALSE;
2146
}
2147
2148
s32 act_top_of_pole_jump(struct MarioState *m) {
2149
play_mario_jump_sound(m);
2150
common_air_action_step(m, ACT_FREEFALL_LAND, MARIO_ANIM_HANDSTAND_JUMP, AIR_STEP_CHECK_LEDGE_GRAB);
2151
return FALSE;
2152
}
2153
2154
s32 act_vertical_wind(struct MarioState *m) {
2155
s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
2156
f32 intendedMag = m->intendedMag / 32.0f;
2157
2158
play_sound_if_no_flag(m, SOUND_MARIO_HERE_WE_GO, MARIO_MARIO_SOUND_PLAYED);
2159
if (m->actionState == 0) {
2160
set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP);
2161
if (m->marioObj->header.gfx.animInfo.animFrame == 1) {
2162
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
2163
#if ENABLE_RUMBLE
2164
queue_rumble_data(8, 80);
2165
#endif
2166
}
2167
2168
if (is_anim_past_end(m)) {
2169
m->actionState = 1;
2170
}
2171
} else {
2172
set_mario_animation(m, MARIO_ANIM_AIRBORNE_ON_STOMACH);
2173
}
2174
2175
update_air_without_turn(m, 1);
2176
2177
switch (perform_air_step(m, 0)) {
2178
case AIR_STEP_LANDED:
2179
set_mario_action(m, ACT_DIVE_SLIDE, 0);
2180
break;
2181
2182
case AIR_STEP_HIT_WALL:
2183
mario_set_forward_vel(m, -16.0f);
2184
break;
2185
}
2186
2187
m->marioObj->header.gfx.angle[0] = (s16)(6144.0f * intendedMag * coss(intendedDYaw));
2188
m->marioObj->header.gfx.angle[2] = (s16)(-4096.0f * intendedMag * sins(intendedDYaw));
2189
return FALSE;
2190
}
2191
2192
s32 act_special_triple_jump(struct MarioState *m) {
2193
if (m->input & INPUT_B_PRESSED) {
2194
return set_mario_action(m, ACT_DIVE, 0);
2195
}
2196
2197
if (m->input & INPUT_Z_PRESSED) {
2198
return set_mario_action(m, ACT_GROUND_POUND, 0);
2199
}
2200
2201
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
2202
2203
update_air_without_turn(m, 1);
2204
2205
switch (perform_air_step(m, 0)) {
2206
case AIR_STEP_LANDED:
2207
if (m->actionState++ == 0) {
2208
m->vel[1] = 42.0f;
2209
} else {
2210
set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
2211
}
2212
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
2213
break;
2214
2215
case AIR_STEP_HIT_WALL:
2216
mario_bonk_reflection(m, TRUE);
2217
break;
2218
}
2219
2220
if (m->actionState == 0 || m->vel[1] > 0.0f) {
2221
if (set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING) == 0) {
2222
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
2223
}
2224
} else {
2225
set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
2226
}
2227
2228
m->particleFlags |= PARTICLE_SPARKLES;
2229
return FALSE;
2230
}
2231
2232
s32 check_common_airborne_cancels(struct MarioState *m) {
2233
if (m->pos[1] < m->waterLevel - 100) {
2234
return set_water_plunge_action(m);
2235
}
2236
2237
if (m->input & INPUT_SQUISHED) {
2238
return drop_and_set_mario_action(m, ACT_SQUISHED, 0);
2239
}
2240
2241
if (m->floor->type == SURFACE_VERTICAL_WIND && (m->action & ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)) {
2242
return drop_and_set_mario_action(m, ACT_VERTICAL_WIND, 0);
2243
}
2244
2245
m->quicksandDepth = 0.0f;
2246
return FALSE;
2247
}
2248
2249
2250
s32 act_roll_fall(struct MarioState *m) {
2251
2252
// Stop rolling after letting go of the trigger
2253
if (!(m->input & INPUT_Z_DOWN) && m->forwardVel < 32.0f) {
2254
return set_mario_action(m, ACT_BRAKING, 0);
2255
}
2256
2257
if (m->marioObj->header.gfx.animInfo.animFrame == 7) {
2258
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
2259
}
2260
2261
common_air_action_step(m, ACT_ROLL, MARIO_ANIM_FORWARD_SPINNING, 0);
2262
return FALSE;
2263
}
2264
2265
s32 mario_execute_airborne_action(struct MarioState *m) {
2266
u32 cancel;
2267
2268
if (check_common_airborne_cancels(m)) {
2269
return TRUE;
2270
}
2271
2272
play_far_fall_sound(m);
2273
2274
/* clang-format off */
2275
switch (m->action) {
2276
case ACT_JUMP: cancel = act_jump(m); break;
2277
case ACT_DOUBLE_JUMP: cancel = act_double_jump(m); break;
2278
case ACT_ROLL_FALL: cancel = act_roll_fall(m); break;
2279
case ACT_FREEFALL: cancel = act_freefall(m); break;
2280
case ACT_HOLD_JUMP: cancel = act_hold_jump(m); break;
2281
case ACT_HOLD_FREEFALL: cancel = act_hold_freefall(m); break;
2282
case ACT_SIDE_FLIP: cancel = act_side_flip(m); break;
2283
case ACT_WALL_KICK_AIR: cancel = act_wall_kick_air(m); break;
2284
case ACT_TWIRLING: cancel = act_twirling(m); break;
2285
case ACT_WATER_JUMP: cancel = act_water_jump(m); break;
2286
case ACT_HOLD_WATER_JUMP: cancel = act_hold_water_jump(m); break;
2287
case ACT_STEEP_JUMP: cancel = act_steep_jump(m); break;
2288
case ACT_BURNING_JUMP: cancel = act_burning_jump(m); break;
2289
case ACT_BURNING_FALL: cancel = act_burning_fall(m); break;
2290
case ACT_TRIPLE_JUMP: cancel = act_triple_jump(m); break;
2291
case ACT_BACKFLIP: cancel = act_backflip(m); break;
2292
case ACT_LONG_JUMP: cancel = act_long_jump(m); break;
2293
case ACT_RIDING_SHELL_JUMP:
2294
case ACT_RIDING_SHELL_FALL: cancel = act_riding_shell_air(m); break;
2295
case ACT_DIVE: cancel = act_dive(m); break;
2296
case ACT_AIR_THROW: cancel = act_air_throw(m); break;
2297
case ACT_BACKWARD_AIR_KB: cancel = act_backward_air_kb(m); break;
2298
case ACT_FORWARD_AIR_KB: cancel = act_forward_air_kb(m); break;
2299
case ACT_HARD_FORWARD_AIR_KB: cancel = act_hard_forward_air_kb(m); break;
2300
case ACT_HARD_BACKWARD_AIR_KB: cancel = act_hard_backward_air_kb(m); break;
2301
case ACT_SOFT_BONK: cancel = act_soft_bonk(m); break;
2302
case ACT_AIR_HIT_WALL: cancel = act_air_hit_wall(m); break;
2303
case ACT_FORWARD_ROLLOUT: cancel = act_forward_rollout(m); break;
2304
case ACT_SHOT_FROM_CANNON: cancel = act_shot_from_cannon(m); break;
2305
case ACT_BUTT_SLIDE_AIR: cancel = act_butt_slide_air(m); break;
2306
case ACT_HOLD_BUTT_SLIDE_AIR: cancel = act_hold_butt_slide_air(m); break;
2307
case ACT_LAVA_BOOST: cancel = act_lava_boost(m); break;
2308
case ACT_GETTING_BLOWN: cancel = act_getting_blown(m); break;
2309
case ACT_BACKWARD_ROLLOUT: cancel = act_backward_rollout(m); break;
2310
case ACT_CRAZY_BOX_BOUNCE: cancel = act_crazy_box_bounce(m); break;
2311
case ACT_SPECIAL_TRIPLE_JUMP: cancel = act_special_triple_jump(m); break;
2312
case ACT_GROUND_POUND: cancel = act_ground_pound(m); break;
2313
case ACT_THROWN_FORWARD: cancel = act_thrown_forward(m); break;
2314
case ACT_THROWN_BACKWARD: cancel = act_thrown_backward(m); break;
2315
case ACT_FLYING_TRIPLE_JUMP: cancel = act_flying_triple_jump(m); break;
2316
case ACT_SLIDE_KICK: cancel = act_slide_kick(m); break;
2317
case ACT_JUMP_KICK: cancel = act_jump_kick(m); break;
2318
case ACT_FLYING: cancel = act_flying(m); break;
2319
case ACT_RIDING_HOOT: cancel = act_riding_hoot(m); break;
2320
case ACT_TOP_OF_POLE_JUMP: cancel = act_top_of_pole_jump(m); break;
2321
case ACT_VERTICAL_WIND: cancel = act_vertical_wind(m); break;
2322
case ACT_WALL_SLIDE: cancel = act_wall_slide(m); break;
2323
}
2324
/* clang-format on */
2325
2326
if ((configDebugMovementMode) && (gPlayer1Controller->buttonDown & L_TRIG)) {
2327
set_mario_action(gMarioState, ACT_DEBUG_FREE_MOVE, 0);
2328
}
2329
2330
return cancel;
2331
}
2332