Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/game/mario_actions_moving.c
7858 views
1
#include <PR/ultratypes.h>
2
3
#include "sm64.h"
4
#include "mario.h"
5
#include "audio/external.h"
6
#include "engine/math_util.h"
7
#include "engine/surface_collision.h"
8
#include "mario_step.h"
9
#include "area.h"
10
#include "interaction.h"
11
#include "mario_actions_object.h"
12
#include "memory.h"
13
#include "behavior_data.h"
14
#include "rumble_init.h"
15
16
#include "settings.h"
17
18
struct LandingAction {
19
s16 numFrames;
20
s16 unk02;
21
u32 verySteepAction;
22
u32 endAction;
23
u32 aPressedAction;
24
u32 offFloorAction;
25
u32 slideAction;
26
};
27
28
struct LandingAction sJumpLandAction = {
29
4, 5, ACT_FREEFALL, ACT_JUMP_LAND_STOP, ACT_DOUBLE_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
30
};
31
32
struct LandingAction sFreefallLandAction = {
33
4, 5, ACT_FREEFALL, ACT_FREEFALL_LAND_STOP, ACT_DOUBLE_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
34
};
35
36
struct LandingAction sSideFlipLandAction = {
37
4, 5, ACT_FREEFALL, ACT_SIDE_FLIP_LAND_STOP, ACT_DOUBLE_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
38
};
39
40
struct LandingAction sHoldJumpLandAction = {
41
4, 5, ACT_HOLD_FREEFALL, ACT_HOLD_JUMP_LAND_STOP, ACT_HOLD_JUMP, ACT_HOLD_FREEFALL, ACT_HOLD_BEGIN_SLIDING,
42
};
43
44
struct LandingAction sHoldFreefallLandAction = {
45
4, 5, ACT_HOLD_FREEFALL, ACT_HOLD_FREEFALL_LAND_STOP, ACT_HOLD_JUMP, ACT_HOLD_FREEFALL, ACT_HOLD_BEGIN_SLIDING,
46
};
47
48
struct LandingAction sLongJumpLandAction = {
49
6, 5, ACT_FREEFALL, ACT_LONG_JUMP_LAND_STOP, ACT_LONG_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
50
};
51
52
struct LandingAction sDoubleJumpLandAction = {
53
4, 5, ACT_FREEFALL, ACT_DOUBLE_JUMP_LAND_STOP, ACT_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
54
};
55
56
struct LandingAction sTripleJumpLandAction = {
57
4, 0, ACT_FREEFALL, ACT_TRIPLE_JUMP_LAND_STOP, ACT_UNINITIALIZED, ACT_FREEFALL, ACT_BEGIN_SLIDING,
58
};
59
60
struct LandingAction sBackflipLandAction = {
61
4, 0, ACT_FREEFALL, ACT_BACKFLIP_LAND_STOP, ACT_BACKFLIP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
62
};
63
64
Mat4 sFloorAlignMatrix[2];
65
66
s16 tilt_body_running(struct MarioState *m) {
67
s16 pitch = find_floor_slope(m, 0);
68
pitch = pitch * m->forwardVel / 40.0f;
69
return -pitch;
70
}
71
72
void play_step_sound(struct MarioState *m, s16 frame1, s16 frame2) {
73
if (is_anim_past_frame(m, frame1) || is_anim_past_frame(m, frame2)) {
74
if (m->flags & MARIO_METAL_CAP) {
75
if (m->marioObj->header.gfx.animInfo.animID == MARIO_ANIM_TIPTOE) {
76
play_sound_and_spawn_particles(m, SOUND_ACTION_METAL_STEP_TIPTOE, 0);
77
} else {
78
play_sound_and_spawn_particles(m, SOUND_ACTION_METAL_STEP, 0);
79
}
80
} else if (m->quicksandDepth > 50.0f) {
81
play_sound(SOUND_ACTION_QUICKSAND_STEP, m->marioObj->header.gfx.cameraToObject);
82
} else if (m->marioObj->header.gfx.animInfo.animID == MARIO_ANIM_TIPTOE) {
83
play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP_TIPTOE, 0);
84
} else {
85
play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP, 0);
86
}
87
}
88
}
89
90
void align_with_floor(struct MarioState *m) {
91
m->pos[1] = m->floorHeight;
92
mtxf_align_terrain_triangle(sFloorAlignMatrix[m->unk00], m->pos, m->faceAngle[1], 40.0f);
93
m->marioObj->header.gfx.throwMatrix = &sFloorAlignMatrix[m->unk00];
94
}
95
96
s32 begin_walking_action(struct MarioState *m, f32 forwardVel, u32 action, u32 actionArg) {
97
m->faceAngle[1] = m->intendedYaw;
98
mario_set_forward_vel(m, forwardVel);
99
return set_mario_action(m, action, actionArg);
100
}
101
102
void check_ledge_climb_down(struct MarioState *m) {
103
struct WallCollisionData wallCols;
104
struct Surface *floor;
105
f32 floorHeight;
106
struct Surface *wall;
107
s16 wallAngle;
108
s16 wallDYaw;
109
110
if (m->forwardVel < 10.0f) {
111
wallCols.x = m->pos[0];
112
wallCols.y = m->pos[1];
113
wallCols.z = m->pos[2];
114
wallCols.radius = 10.0f;
115
wallCols.offsetY = -10.0f;
116
117
if (find_wall_collisions(&wallCols) != 0) {
118
floorHeight = find_floor(wallCols.x, wallCols.y, wallCols.z, &floor);
119
if (floor != NULL && (wallCols.y - floorHeight > 160.0f)) {
120
wall = wallCols.walls[wallCols.numWalls - 1];
121
wallAngle = atan2s(wall->normal.z, wall->normal.x);
122
wallDYaw = wallAngle - m->faceAngle[1];
123
124
if (wallDYaw > -0x4000 && wallDYaw < 0x4000) {
125
m->pos[0] = wallCols.x - 20.0f * wall->normal.x;
126
m->pos[2] = wallCols.z - 20.0f * wall->normal.z;
127
128
m->faceAngle[0] = 0;
129
m->faceAngle[1] = wallAngle + 0x8000;
130
131
set_mario_action(m, ACT_LEDGE_CLIMB_DOWN, 0);
132
set_mario_animation(m, MARIO_ANIM_CLIMB_DOWN_LEDGE);
133
}
134
}
135
}
136
}
137
}
138
139
void slide_bonk(struct MarioState *m, u32 fastAction, u32 slowAction) {
140
if (m->forwardVel > 16.0f) {
141
mario_bonk_reflection(m, TRUE);
142
drop_and_set_mario_action(m, fastAction, 0);
143
} else {
144
mario_set_forward_vel(m, 0.0f);
145
set_mario_action(m, slowAction, 0);
146
}
147
}
148
149
s32 set_triple_jump_action(struct MarioState *m, UNUSED u32 action, UNUSED u32 actionArg) {
150
if (m->flags & MARIO_WING_CAP) {
151
return set_mario_action(m, ACT_FLYING_TRIPLE_JUMP, 0);
152
} else if (m->forwardVel > 20.0f) {
153
return set_mario_action(m, ACT_TRIPLE_JUMP, 0);
154
} else {
155
return set_mario_action(m, ACT_JUMP, 0);
156
}
157
158
return FALSE;
159
}
160
161
void update_sliding_angle(struct MarioState *m, f32 accel, f32 lossFactor) {
162
s32 newFacingDYaw;
163
s16 facingDYaw;
164
165
struct Surface *floor = m->floor;
166
s16 slopeAngle = atan2s(floor->normal.z, floor->normal.x);
167
f32 steepness = sqrtf(floor->normal.x * floor->normal.x + floor->normal.z * floor->normal.z);
168
UNUSED f32 normalY = floor->normal.y;
169
170
m->slideVelX += accel * steepness * sins(slopeAngle);
171
m->slideVelZ += accel * steepness * coss(slopeAngle);
172
173
m->slideVelX *= lossFactor;
174
m->slideVelZ *= lossFactor;
175
176
m->slideYaw = atan2s(m->slideVelZ, m->slideVelX);
177
178
facingDYaw = m->faceAngle[1] - m->slideYaw;
179
newFacingDYaw = facingDYaw;
180
181
//! -0x4000 not handled - can slide down a slope while facing perpendicular to it
182
if (newFacingDYaw > 0 && newFacingDYaw <= 0x4000) {
183
if ((newFacingDYaw -= 0x200) < 0) {
184
newFacingDYaw = 0;
185
}
186
} else if (newFacingDYaw > -0x4000 && newFacingDYaw < 0) {
187
if ((newFacingDYaw += 0x200) > 0) {
188
newFacingDYaw = 0;
189
}
190
} else if (newFacingDYaw > 0x4000 && newFacingDYaw < 0x8000) {
191
if ((newFacingDYaw += 0x200) > 0x8000) {
192
newFacingDYaw = 0x8000;
193
}
194
} else if (newFacingDYaw > -0x8000 && newFacingDYaw < -0x4000) {
195
if ((newFacingDYaw -= 0x200) < -0x8000) {
196
newFacingDYaw = -0x8000;
197
}
198
}
199
200
m->faceAngle[1] = m->slideYaw + newFacingDYaw;
201
202
m->vel[0] = m->slideVelX;
203
m->vel[1] = 0.0f;
204
m->vel[2] = m->slideVelZ;
205
206
mario_update_moving_sand(m);
207
mario_update_windy_ground(m);
208
209
//! Speed is capped a frame late (butt slide HSG)
210
m->forwardVel = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
211
if (m->forwardVel > 100.0f) {
212
m->slideVelX = m->slideVelX * 100.0f / m->forwardVel;
213
m->slideVelZ = m->slideVelZ * 100.0f / m->forwardVel;
214
}
215
216
if (newFacingDYaw < -0x4000 || newFacingDYaw > 0x4000) {
217
m->forwardVel *= -1.0f;
218
}
219
}
220
221
s32 update_sliding(struct MarioState *m, f32 stopSpeed) {
222
f32 lossFactor;
223
f32 accel;
224
f32 oldSpeed;
225
f32 newSpeed;
226
227
s32 stopped = FALSE;
228
229
s16 intendedDYaw = m->intendedYaw - m->slideYaw;
230
f32 forward = coss(intendedDYaw);
231
f32 sideward = sins(intendedDYaw);
232
233
//! 10k glitch
234
if (forward < 0.0f && m->forwardVel >= 0.0f) {
235
forward *= 0.5f + 0.5f * m->forwardVel / 100.0f;
236
}
237
238
switch (mario_get_floor_class(m)) {
239
case SURFACE_CLASS_VERY_SLIPPERY:
240
accel = 10.0f;
241
lossFactor = m->intendedMag / 32.0f * forward * 0.02f + 0.98f;
242
break;
243
244
case SURFACE_CLASS_SLIPPERY:
245
accel = 8.0f;
246
lossFactor = m->intendedMag / 32.0f * forward * 0.02f + 0.96f;
247
break;
248
249
default:
250
accel = 7.0f;
251
lossFactor = m->intendedMag / 32.0f * forward * 0.02f + 0.92f;
252
break;
253
254
case SURFACE_CLASS_NOT_SLIPPERY:
255
accel = 5.0f;
256
lossFactor = m->intendedMag / 32.0f * forward * 0.02f + 0.92f;
257
break;
258
}
259
260
oldSpeed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
261
262
//! This is attempting to use trig derivatives to rotate Mario's speed.
263
// It is slightly off/asymmetric since it uses the new X speed, but the old
264
// Z speed.
265
m->slideVelX += m->slideVelZ * (m->intendedMag / 32.0f) * sideward * 0.05f;
266
m->slideVelZ -= m->slideVelX * (m->intendedMag / 32.0f) * sideward * 0.05f;
267
268
newSpeed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
269
270
if (oldSpeed > 0.0f && newSpeed > 0.0f) {
271
m->slideVelX = m->slideVelX * oldSpeed / newSpeed;
272
m->slideVelZ = m->slideVelZ * oldSpeed / newSpeed;
273
}
274
275
update_sliding_angle(m, accel, lossFactor);
276
277
if (!mario_floor_is_slope(m) && m->forwardVel * m->forwardVel < stopSpeed * stopSpeed) {
278
mario_set_forward_vel(m, 0.0f);
279
stopped = TRUE;
280
}
281
282
return stopped;
283
}
284
285
void apply_slope_accel(struct MarioState *m) {
286
f32 slopeAccel;
287
288
struct Surface *floor = m->floor;
289
f32 steepness = sqrtf(floor->normal.x * floor->normal.x + floor->normal.z * floor->normal.z);
290
291
UNUSED f32 normalY = floor->normal.y;
292
s16 floorDYaw = m->floorAngle - m->faceAngle[1];
293
294
if (mario_floor_is_slope(m)) {
295
s16 slopeClass = 0;
296
297
if (m->action != ACT_SOFT_BACKWARD_GROUND_KB && m->action != ACT_SOFT_FORWARD_GROUND_KB) {
298
slopeClass = mario_get_floor_class(m);
299
}
300
301
switch (slopeClass) {
302
case SURFACE_CLASS_VERY_SLIPPERY:
303
slopeAccel = 5.3f;
304
break;
305
case SURFACE_CLASS_SLIPPERY:
306
slopeAccel = 2.7f;
307
break;
308
default:
309
slopeAccel = 1.7f;
310
break;
311
case SURFACE_CLASS_NOT_SLIPPERY:
312
slopeAccel = 0.0f;
313
break;
314
}
315
316
if (floorDYaw > -0x4000 && floorDYaw < 0x4000) {
317
m->forwardVel += slopeAccel * steepness;
318
} else {
319
m->forwardVel -= slopeAccel * steepness;
320
}
321
}
322
323
m->slideYaw = m->faceAngle[1];
324
325
m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
326
m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
327
328
m->vel[0] = m->slideVelX;
329
m->vel[1] = 0.0f;
330
m->vel[2] = m->slideVelZ;
331
332
mario_update_moving_sand(m);
333
mario_update_windy_ground(m);
334
}
335
336
s32 apply_landing_accel(struct MarioState *m, f32 frictionFactor) {
337
s32 stopped = FALSE;
338
339
apply_slope_accel(m);
340
341
if (!mario_floor_is_slope(m)) {
342
m->forwardVel *= frictionFactor;
343
if (m->forwardVel * m->forwardVel < 1.0f) {
344
mario_set_forward_vel(m, 0.0f);
345
stopped = TRUE;
346
}
347
}
348
349
return stopped;
350
}
351
352
void update_shell_speed(struct MarioState *m) {
353
f32 maxTargetSpeed;
354
f32 targetSpeed;
355
356
if (m->floorHeight < m->waterLevel) {
357
m->floorHeight = m->waterLevel;
358
m->floor = &gWaterSurfacePseudoFloor;
359
m->floor->originOffset = m->waterLevel; //! Negative origin offset
360
}
361
362
if (m->floor != NULL && m->floor->type == SURFACE_SLOW) {
363
maxTargetSpeed = 48.0f;
364
} else {
365
maxTargetSpeed = 64.0f;
366
}
367
368
targetSpeed = m->intendedMag * 2.0f;
369
if (targetSpeed > maxTargetSpeed) {
370
targetSpeed = maxTargetSpeed;
371
}
372
if (targetSpeed < 24.0f) {
373
targetSpeed = 24.0f;
374
}
375
376
if (m->forwardVel <= 0.0f) {
377
m->forwardVel += 1.1f;
378
} else if (m->forwardVel <= targetSpeed) {
379
m->forwardVel += 1.1f - m->forwardVel / 58.0f;
380
} else if (m->floor->normal.y >= 0.95f) {
381
m->forwardVel -= 1.0f;
382
}
383
384
//! No backward speed cap (shell hyperspeed)
385
if (m->forwardVel > 64.0f) {
386
m->forwardVel = 64.0f;
387
}
388
389
m->faceAngle[1] =
390
m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
391
392
apply_slope_accel(m);
393
}
394
395
s32 apply_slope_decel(struct MarioState *m, f32 decelCoef) {
396
f32 decel;
397
s32 stopped = FALSE;
398
399
switch (mario_get_floor_class(m)) {
400
case SURFACE_CLASS_VERY_SLIPPERY:
401
decel = decelCoef * 0.2f;
402
break;
403
case SURFACE_CLASS_SLIPPERY:
404
decel = decelCoef * 0.7f;
405
break;
406
default:
407
decel = decelCoef * 2.0f;
408
break;
409
case SURFACE_CLASS_NOT_SLIPPERY:
410
decel = decelCoef * 3.0f;
411
break;
412
}
413
414
if ((m->forwardVel = approach_f32(m->forwardVel, 0.0f, decel, decel)) == 0.0f) {
415
stopped = TRUE;
416
}
417
418
apply_slope_accel(m);
419
return stopped;
420
}
421
422
s32 update_decelerating_speed(struct MarioState *m) {
423
s32 stopped = FALSE;
424
425
if ((m->forwardVel = approach_f32(m->forwardVel, 0.0f, 1.0f, 1.0f)) == 0.0f) {
426
stopped = TRUE;
427
}
428
429
mario_set_forward_vel(m, m->forwardVel);
430
mario_update_moving_sand(m);
431
mario_update_windy_ground(m);
432
433
return stopped;
434
}
435
436
void update_walking_speed(struct MarioState *m) {
437
f32 maxTargetSpeed;
438
f32 targetSpeed;
439
440
if (m->floor != NULL && m->floor->type == SURFACE_SLOW) {
441
maxTargetSpeed = 24.0f;
442
} else {
443
maxTargetSpeed = 32.0f;
444
}
445
446
targetSpeed = m->intendedMag < maxTargetSpeed ? m->intendedMag : maxTargetSpeed;
447
448
if (m->quicksandDepth > 10.0f) {
449
targetSpeed *= 6.25 / m->quicksandDepth;
450
}
451
452
if (m->forwardVel <= 0.0f || configHyperspeedMode) {
453
m->forwardVel += 1.1f;
454
} else if (m->forwardVel <= targetSpeed) {
455
m->forwardVel += 1.1f - m->forwardVel / 43.0f;
456
} else if (m->floor->normal.y >= 0.95f) {
457
m->forwardVel -= 1.0f;
458
}
459
460
if ((!configHyperspeedMode) && m->forwardVel > 48.0f) {
461
m->forwardVel = 48.0f;
462
}
463
464
if (configImprovedControls) {
465
466
if (m->forwardVel < -8.0f) {
467
m->forwardVel = -8.0f;
468
}
469
470
m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x1000, 0x1000);
471
}
472
else {
473
m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
474
}
475
apply_slope_accel(m);
476
}
477
478
s32 should_begin_sliding(struct MarioState *m) {
479
if (m->input & INPUT_ABOVE_SLIDE) {
480
s32 slideLevel = (m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE;
481
s32 movingBackward = m->forwardVel <= -1.0f;
482
483
if (slideLevel || movingBackward || mario_facing_downhill(m, FALSE)) {
484
return TRUE;
485
}
486
}
487
488
return FALSE;
489
}
490
491
s32 analog_stick_held_back(struct MarioState *m) {
492
s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
493
return intendedDYaw < -0x471C || intendedDYaw > 0x471C;
494
}
495
496
s32 check_ground_dive_or_punch(struct MarioState *m) {
497
UNUSED s32 unused;
498
499
if (m->input & INPUT_B_PRESSED) {
500
//! Speed kick (shoutouts to SimpleFlips)
501
if (m->forwardVel >= 29.0f && m->controller->stickMag > 48.0f) {
502
m->vel[1] = 20.0f;
503
return set_mario_action(m, ACT_DIVE, 1);
504
}
505
506
return set_mario_action(m, ACT_MOVE_PUNCHING, 0);
507
}
508
509
return FALSE;
510
}
511
512
s32 begin_braking_action(struct MarioState *m) {
513
mario_drop_held_object(m);
514
515
if (m->actionState == 1) {
516
m->faceAngle[1] = m->actionArg;
517
return set_mario_action(m, ACT_STANDING_AGAINST_WALL, 0);
518
}
519
520
if (m->forwardVel >= 16.0f && m->floor->normal.y >= 0.17364818f) {
521
return set_mario_action(m, ACT_BRAKING, 0);
522
}
523
524
return set_mario_action(m, ACT_DECELERATING, 0);
525
}
526
527
void anim_and_audio_for_walk(struct MarioState *m) {
528
s32 val14;
529
struct Object *marioObj = m->marioObj;
530
s32 val0C = TRUE;
531
s16 targetPitch = 0;
532
f32 val04;
533
534
val04 = m->intendedMag > m->forwardVel ? m->intendedMag : m->forwardVel;
535
536
if (val04 < 4.0f) {
537
val04 = 4.0f;
538
}
539
540
if (m->quicksandDepth > 50.0f) {
541
val14 = (s32)(val04 / 4.0f * 0x10000);
542
set_mario_anim_with_accel(m, MARIO_ANIM_MOVE_IN_QUICKSAND, val14);
543
play_step_sound(m, 19, 93);
544
m->actionTimer = 0;
545
} else {
546
while (val0C) {
547
switch (m->actionTimer) {
548
case 0:
549
if (val04 > 8.0f) {
550
m->actionTimer = 2;
551
} else {
552
//! (Speed Crash) If Mario's speed is more than 2^17.
553
if ((val14 = (s32)(val04 / 4.0f * 0x10000)) < 0x1000) {
554
val14 = 0x1000;
555
}
556
set_mario_anim_with_accel(m, MARIO_ANIM_START_TIPTOE, val14);
557
play_step_sound(m, 7, 22);
558
if (is_anim_past_frame(m, 23)) {
559
m->actionTimer = 2;
560
}
561
562
val0C = FALSE;
563
}
564
break;
565
566
case 1:
567
if (val04 > 8.0f) {
568
m->actionTimer = 2;
569
} else {
570
//! (Speed Crash) If Mario's speed is more than 2^17.
571
if ((val14 = (s32)(val04 * 0x10000)) < 0x1000) {
572
val14 = 0x1000;
573
}
574
set_mario_anim_with_accel(m, MARIO_ANIM_TIPTOE, val14);
575
play_step_sound(m, 14, 72);
576
577
val0C = FALSE;
578
}
579
break;
580
581
case 2:
582
if (val04 < 5.0f) {
583
m->actionTimer = 1;
584
} else if (val04 > 22.0f) {
585
m->actionTimer = 3;
586
} else {
587
//! (Speed Crash) If Mario's speed is more than 2^17.
588
val14 = (s32)(val04 / 4.0f * 0x10000);
589
set_mario_anim_with_accel(m, MARIO_ANIM_WALKING, val14);
590
play_step_sound(m, 10, 49);
591
592
val0C = FALSE;
593
}
594
break;
595
596
case 3:
597
if (val04 < 18.0f) {
598
m->actionTimer = 2;
599
} else {
600
//! (Speed Crash) If Mario's speed is more than 2^17.
601
val14 = (s32)(val04 / 4.0f * 0x10000);
602
set_mario_anim_with_accel(m, MARIO_ANIM_RUNNING, val14);
603
play_step_sound(m, 9, 45);
604
targetPitch = tilt_body_running(m);
605
606
val0C = FALSE;
607
}
608
break;
609
}
610
}
611
}
612
613
marioObj->oMarioWalkingPitch =
614
(s16) approach_s32(marioObj->oMarioWalkingPitch, targetPitch, 0x800, 0x800);
615
marioObj->header.gfx.angle[0] = marioObj->oMarioWalkingPitch;
616
}
617
618
void anim_and_audio_for_hold_walk(struct MarioState *m) {
619
s32 val0C;
620
s32 val08 = TRUE;
621
f32 val04;
622
623
val04 = m->intendedMag > m->forwardVel ? m->intendedMag : m->forwardVel;
624
625
if (val04 < 2.0f) {
626
val04 = 2.0f;
627
}
628
629
while (val08) {
630
switch (m->actionTimer) {
631
case 0:
632
if (val04 > 6.0f) {
633
m->actionTimer = 1;
634
} else {
635
//! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^15.
636
val0C = (s32)(val04 * 0x10000);
637
set_mario_anim_with_accel(m, MARIO_ANIM_SLOW_WALK_WITH_LIGHT_OBJ, val0C);
638
play_step_sound(m, 12, 62);
639
640
val08 = FALSE;
641
}
642
break;
643
644
case 1:
645
if (val04 < 3.0f) {
646
m->actionTimer = 0;
647
} else if (val04 > 11.0f) {
648
m->actionTimer = 2;
649
} else {
650
//! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^15.
651
val0C = (s32)(val04 * 0x10000);
652
set_mario_anim_with_accel(m, MARIO_ANIM_WALK_WITH_LIGHT_OBJ, val0C);
653
play_step_sound(m, 12, 62);
654
655
val08 = FALSE;
656
}
657
break;
658
659
case 2:
660
if (val04 < 8.0f) {
661
m->actionTimer = 1;
662
} else {
663
//! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^16.
664
val0C = (s32)(val04 / 2.0f * 0x10000);
665
set_mario_anim_with_accel(m, MARIO_ANIM_RUN_WITH_LIGHT_OBJ, val0C);
666
play_step_sound(m, 10, 49);
667
668
val08 = FALSE;
669
}
670
break;
671
}
672
}
673
}
674
675
void anim_and_audio_for_heavy_walk(struct MarioState *m) {
676
s32 val04 = (s32)(m->intendedMag * 0x10000);
677
set_mario_anim_with_accel(m, MARIO_ANIM_WALK_WITH_HEAVY_OBJ, val04);
678
play_step_sound(m, 26, 79);
679
}
680
681
void push_or_sidle_wall(struct MarioState *m, Vec3f startPos) {
682
s16 wallAngle;
683
s16 dWallAngle;
684
f32 dx = m->pos[0] - startPos[0];
685
f32 dz = m->pos[2] - startPos[2];
686
f32 movedDistance = sqrtf(dx * dx + dz * dz);
687
//! (Speed Crash) If a wall is after moving 16384 distance, this crashes.
688
s32 val04 = (s32)(movedDistance * 2.0f * 0x10000);
689
690
if (m->forwardVel > 6.0f) {
691
mario_set_forward_vel(m, 6.0f);
692
}
693
694
if (m->wall != NULL) {
695
wallAngle = atan2s(m->wall->normal.z, m->wall->normal.x);
696
dWallAngle = wallAngle - m->faceAngle[1];
697
}
698
699
if (m->wall == NULL || dWallAngle <= -0x71C8 || dWallAngle >= 0x71C8) {
700
m->flags |= MARIO_UNKNOWN_31;
701
set_mario_animation(m, MARIO_ANIM_PUSHING);
702
play_step_sound(m, 6, 18);
703
} else {
704
if (dWallAngle < 0) {
705
set_mario_anim_with_accel(m, MARIO_ANIM_SIDESTEP_RIGHT, val04);
706
} else {
707
set_mario_anim_with_accel(m, MARIO_ANIM_SIDESTEP_LEFT, val04);
708
}
709
710
if (m->marioObj->header.gfx.animInfo.animFrame < 20) {
711
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
712
m->particleFlags |= PARTICLE_DUST;
713
}
714
715
m->actionState = 1;
716
m->actionArg = wallAngle + 0x8000;
717
m->marioObj->header.gfx.angle[1] = wallAngle + 0x8000;
718
m->marioObj->header.gfx.angle[2] = find_floor_slope(m, 0x4000);
719
}
720
}
721
722
void tilt_body_walking(struct MarioState *m, s16 startYaw) {
723
struct MarioBodyState *val0C = m->marioBodyState;
724
UNUSED struct Object *marioObj = m->marioObj;
725
s16 animID = m->marioObj->header.gfx.animInfo.animID;
726
727
if (animID == MARIO_ANIM_WALKING || animID == MARIO_ANIM_RUNNING) {
728
s16 dYaw = m->faceAngle[1] - startYaw;
729
//! (Speed Crash) These casts can cause a crash if (dYaw * forwardVel / 12) or
730
//! (forwardVel * 170) exceed or equal 2^31.
731
s16 val02 = -(s16)(dYaw * m->forwardVel / 12.0f);
732
s16 val00 = (s16)(m->forwardVel * 170.0f);
733
734
if (val02 > 0x1555) {
735
val02 = 0x1555;
736
}
737
if (val02 < -0x1555) {
738
val02 = -0x1555;
739
}
740
741
if (val00 > 0x1555) {
742
val00 = 0x1555;
743
}
744
if (val00 < 0) {
745
val00 = 0;
746
}
747
748
val0C->torsoAngle[2] = approach_s32(val0C->torsoAngle[2], val02, 0x400, 0x400);
749
val0C->torsoAngle[0] = approach_s32(val0C->torsoAngle[0], val00, 0x400, 0x400);
750
} else {
751
val0C->torsoAngle[2] = 0;
752
val0C->torsoAngle[0] = 0;
753
}
754
}
755
756
void tilt_body_ground_shell(struct MarioState *m, s16 startYaw) {
757
struct MarioBodyState *val0C = m->marioBodyState;
758
struct Object *marioObj = m->marioObj;
759
s16 dYaw = m->faceAngle[1] - startYaw;
760
//! (Speed Crash) These casts can cause a crash if (dYaw * forwardVel / 12) or
761
//! (forwardVel * 170) exceed or equal 2^31. Harder (if not impossible to do)
762
//! while on a Koopa Shell making this less of an issue.
763
s16 val04 = -(s16)(dYaw * m->forwardVel / 12.0f);
764
s16 val02 = (s16)(m->forwardVel * 170.0f);
765
766
if (val04 > 0x1800) {
767
val04 = 0x1800;
768
}
769
if (val04 < -0x1800) {
770
val04 = -0x1800;
771
}
772
773
if (val02 > 0x1000) {
774
val02 = 0x1000;
775
}
776
if (val02 < 0) {
777
val02 = 0;
778
}
779
780
val0C->torsoAngle[2] = approach_s32(val0C->torsoAngle[2], val04, 0x200, 0x200);
781
val0C->torsoAngle[0] = approach_s32(val0C->torsoAngle[0], val02, 0x200, 0x200);
782
val0C->headAngle[2] = -val0C->torsoAngle[2];
783
784
marioObj->header.gfx.angle[2] = val0C->torsoAngle[2];
785
marioObj->header.gfx.pos[1] += 45.0f;
786
}
787
788
s32 act_walking(struct MarioState *m) {
789
Vec3f startPos;
790
s16 startYaw = m->faceAngle[1];
791
792
mario_drop_held_object(m);
793
794
if (should_begin_sliding(m)) {
795
return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
796
}
797
798
if (m->input & INPUT_FIRST_PERSON) {
799
return begin_braking_action(m);
800
}
801
802
if (m->input & INPUT_A_PRESSED) {
803
return set_jump_from_landing(m);
804
}
805
806
if (check_ground_dive_or_punch(m)) {
807
return TRUE;
808
}
809
810
if (m->input & INPUT_UNKNOWN_5) {
811
return begin_braking_action(m);
812
}
813
814
if (configImprovedControls) {
815
if (analog_stick_held_back(m)) {
816
if (m->forwardVel >= 12.0f){
817
return set_mario_action(m, ACT_TURNING_AROUND, 0);
818
} else if ((m->forwardVel) < 10.0f && (m->forwardVel > 0.0f)){
819
m->faceAngle[1] = m->intendedYaw;
820
return set_mario_action(m, ACT_TURNING_AROUND, 0);
821
}
822
}
823
}
824
else {
825
if (analog_stick_held_back(m) && m->forwardVel >= 16.0f) {
826
return set_mario_action(m, ACT_TURNING_AROUND, 0);
827
}
828
}
829
830
if (m->input & INPUT_Z_PRESSED) {
831
return set_mario_action(m, ACT_CROUCH_SLIDE, 0);
832
}
833
834
m->actionState = 0;
835
836
vec3f_copy(startPos, m->pos);
837
update_walking_speed(m);
838
839
switch (perform_ground_step(m)) {
840
case GROUND_STEP_LEFT_GROUND:
841
set_mario_action(m, ACT_FREEFALL, 0);
842
set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
843
break;
844
845
case GROUND_STEP_NONE:
846
anim_and_audio_for_walk(m);
847
if (m->intendedMag - m->forwardVel > 16.0f) {
848
m->particleFlags |= PARTICLE_DUST;
849
}
850
break;
851
852
case GROUND_STEP_HIT_WALL:
853
push_or_sidle_wall(m, startPos);
854
m->actionTimer = 0;
855
break;
856
}
857
858
check_ledge_climb_down(m);
859
tilt_body_walking(m, startYaw);
860
return FALSE;
861
}
862
863
s32 act_move_punching(struct MarioState *m) {
864
if (should_begin_sliding(m)) {
865
return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
866
}
867
868
if (m->actionState == 0 && (m->input & INPUT_A_DOWN)) {
869
return set_mario_action(m, ACT_JUMP_KICK, 0);
870
}
871
872
m->actionState = 1;
873
874
mario_update_punch_sequence(m);
875
876
if (m->forwardVel >= 0.0f) {
877
apply_slope_decel(m, 0.5f);
878
} else {
879
if ((m->forwardVel += 8.0f) >= 0.0f) {
880
m->forwardVel = 0.0f;
881
}
882
apply_slope_accel(m);
883
}
884
885
switch (perform_ground_step(m)) {
886
case GROUND_STEP_LEFT_GROUND:
887
set_mario_action(m, ACT_FREEFALL, 0);
888
break;
889
890
case GROUND_STEP_NONE:
891
m->particleFlags |= PARTICLE_DUST;
892
break;
893
}
894
895
return FALSE;
896
}
897
898
s32 act_hold_walking(struct MarioState *m) {
899
if (m->heldObj->behavior == segmented_to_virtual(bhvJumpingBox)) {
900
return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0);
901
}
902
903
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
904
return drop_and_set_mario_action(m, ACT_WALKING, 0);
905
}
906
907
if (should_begin_sliding(m)) {
908
return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0);
909
}
910
911
if (m->input & INPUT_B_PRESSED) {
912
return set_mario_action(m, ACT_THROWING, 0);
913
}
914
915
if (m->input & INPUT_A_PRESSED) {
916
return set_jumping_action(m, ACT_HOLD_JUMP, 0);
917
}
918
919
if (m->input & INPUT_UNKNOWN_5) {
920
return set_mario_action(m, ACT_HOLD_DECELERATING, 0);
921
}
922
923
if (m->input & INPUT_Z_PRESSED) {
924
return drop_and_set_mario_action(m, ACT_CROUCH_SLIDE, 0);
925
}
926
927
m->intendedMag *= 0.4f;
928
929
update_walking_speed(m);
930
931
switch (perform_ground_step(m)) {
932
case GROUND_STEP_LEFT_GROUND:
933
set_mario_action(m, ACT_HOLD_FREEFALL, 0);
934
break;
935
936
case GROUND_STEP_HIT_WALL:
937
if (m->forwardVel > 16.0f) {
938
mario_set_forward_vel(m, 16.0f);
939
}
940
break;
941
}
942
943
anim_and_audio_for_hold_walk(m);
944
945
if (0.4f * m->intendedMag - m->forwardVel > 10.0f) {
946
m->particleFlags |= PARTICLE_DUST;
947
}
948
949
return FALSE;
950
}
951
952
s32 act_hold_heavy_walking(struct MarioState *m) {
953
if (m->input & INPUT_B_PRESSED) {
954
return set_mario_action(m, ACT_HEAVY_THROW, 0);
955
}
956
957
if (should_begin_sliding(m)) {
958
return drop_and_set_mario_action(m, ACT_BEGIN_SLIDING, 0);
959
}
960
961
if (m->input & INPUT_UNKNOWN_5) {
962
return set_mario_action(m, ACT_HOLD_HEAVY_IDLE, 0);
963
}
964
965
m->intendedMag *= 0.1f;
966
967
update_walking_speed(m);
968
969
switch (perform_ground_step(m)) {
970
case GROUND_STEP_LEFT_GROUND:
971
drop_and_set_mario_action(m, ACT_FREEFALL, 0);
972
break;
973
974
case GROUND_STEP_HIT_WALL:
975
if (m->forwardVel > 10.0f) {
976
mario_set_forward_vel(m, 10.0f);
977
}
978
break;
979
}
980
981
anim_and_audio_for_heavy_walk(m);
982
return FALSE;
983
}
984
985
s32 act_turning_around(struct MarioState *m) {
986
if (m->input & INPUT_ABOVE_SLIDE) {
987
return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
988
}
989
990
if (m->input & INPUT_A_PRESSED) {
991
return set_jumping_action(m, ACT_SIDE_FLIP, 0);
992
}
993
994
if (m->input & INPUT_UNKNOWN_5) {
995
return set_mario_action(m, ACT_BRAKING, 0);
996
}
997
998
if (!analog_stick_held_back(m)) {
999
return set_mario_action(m, ACT_WALKING, 0);
1000
}
1001
1002
if (apply_slope_decel(m, 2.0f)) {
1003
return begin_walking_action(m, 8.0f, ACT_FINISH_TURNING_AROUND, 0);
1004
}
1005
1006
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
1007
1008
adjust_sound_for_speed(m);
1009
1010
switch (perform_ground_step(m)) {
1011
case GROUND_STEP_LEFT_GROUND:
1012
set_mario_action(m, ACT_FREEFALL, 0);
1013
break;
1014
1015
case GROUND_STEP_NONE:
1016
m->particleFlags |= PARTICLE_DUST;
1017
break;
1018
}
1019
1020
if (m->forwardVel >= 18.0f) {
1021
set_mario_animation(m, MARIO_ANIM_TURNING_PART1);
1022
} else {
1023
set_mario_animation(m, MARIO_ANIM_TURNING_PART2);
1024
if (is_anim_at_end(m)) {
1025
if (m->forwardVel > 0.0f) {
1026
begin_walking_action(m, -m->forwardVel, ACT_WALKING, 0);
1027
} else {
1028
begin_walking_action(m, 8.0f, ACT_WALKING, 0);
1029
}
1030
}
1031
}
1032
1033
return FALSE;
1034
}
1035
1036
s32 act_finish_turning_around(struct MarioState *m) {
1037
if (m->input & INPUT_ABOVE_SLIDE) {
1038
return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
1039
}
1040
1041
if (m->input & INPUT_A_PRESSED) {
1042
return set_jumping_action(m, ACT_SIDE_FLIP, 0);
1043
}
1044
1045
update_walking_speed(m);
1046
set_mario_animation(m, MARIO_ANIM_TURNING_PART2);
1047
1048
if (perform_ground_step(m) == GROUND_STEP_LEFT_GROUND) {
1049
set_mario_action(m, ACT_FREEFALL, 0);
1050
}
1051
1052
if (is_anim_at_end(m)) {
1053
set_mario_action(m, ACT_WALKING, 0);
1054
}
1055
1056
m->marioObj->header.gfx.angle[1] += 0x8000;
1057
return FALSE;
1058
}
1059
1060
s32 act_braking(struct MarioState *m) {
1061
if (!(m->input & INPUT_FIRST_PERSON)
1062
&& (m->input
1063
& (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED | INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE))) {
1064
return check_common_action_exits(m);
1065
}
1066
1067
if (configImprovedControls) {
1068
if (apply_slope_decel(m, 2.5f)) {
1069
return set_mario_action(m, ACT_BRAKING_STOP, 0);
1070
}
1071
}
1072
else {
1073
if (apply_slope_decel(m, 2.0f)) {
1074
return set_mario_action(m, ACT_BRAKING_STOP, 0);
1075
}
1076
}
1077
1078
if (m->input & INPUT_B_PRESSED) {
1079
return set_mario_action(m, ACT_MOVE_PUNCHING, 0);
1080
}
1081
1082
switch (perform_ground_step(m)) {
1083
case GROUND_STEP_LEFT_GROUND:
1084
set_mario_action(m, ACT_FREEFALL, 0);
1085
break;
1086
1087
case GROUND_STEP_NONE:
1088
m->particleFlags |= PARTICLE_DUST;
1089
break;
1090
1091
case GROUND_STEP_HIT_WALL:
1092
slide_bonk(m, ACT_BACKWARD_GROUND_KB, ACT_BRAKING_STOP);
1093
break;
1094
}
1095
1096
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
1097
adjust_sound_for_speed(m);
1098
set_mario_animation(m, MARIO_ANIM_SKID_ON_GROUND);
1099
return FALSE;
1100
}
1101
1102
s32 act_decelerating(struct MarioState *m) {
1103
s32 val0C;
1104
s16 slopeClass = mario_get_floor_class(m);
1105
1106
if (!(m->input & INPUT_FIRST_PERSON)) {
1107
if (should_begin_sliding(m)) {
1108
return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
1109
}
1110
1111
if (m->input & INPUT_A_PRESSED) {
1112
return set_jump_from_landing(m);
1113
}
1114
1115
if (check_ground_dive_or_punch(m)) {
1116
return TRUE;
1117
}
1118
1119
if (m->input & INPUT_NONZERO_ANALOG) {
1120
return set_mario_action(m, ACT_WALKING, 0);
1121
}
1122
1123
if (m->input & INPUT_Z_PRESSED) {
1124
return set_mario_action(m, ACT_CROUCH_SLIDE, 0);
1125
}
1126
}
1127
1128
if (update_decelerating_speed(m)) {
1129
return set_mario_action(m, ACT_IDLE, 0);
1130
}
1131
1132
switch (perform_ground_step(m)) {
1133
case GROUND_STEP_LEFT_GROUND:
1134
set_mario_action(m, ACT_FREEFALL, 0);
1135
break;
1136
1137
case GROUND_STEP_HIT_WALL:
1138
if (slopeClass == SURFACE_CLASS_VERY_SLIPPERY) {
1139
mario_bonk_reflection(m, TRUE);
1140
} else {
1141
mario_set_forward_vel(m, 0.0f);
1142
}
1143
break;
1144
}
1145
1146
if (slopeClass == SURFACE_CLASS_VERY_SLIPPERY) {
1147
set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_LEFT);
1148
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
1149
adjust_sound_for_speed(m);
1150
m->particleFlags |= PARTICLE_DUST;
1151
} else {
1152
// (Speed Crash) Crashes if speed exceeds 2^17.
1153
if ((val0C = (s32)(m->forwardVel / 4.0f * 0x10000)) < 0x1000) {
1154
val0C = 0x1000;
1155
}
1156
1157
set_mario_anim_with_accel(m, MARIO_ANIM_WALKING, val0C);
1158
play_step_sound(m, 10, 49);
1159
}
1160
1161
if (configImprovedControls)
1162
check_ledge_climb_down(m);
1163
1164
return FALSE;
1165
}
1166
1167
s32 act_hold_decelerating(struct MarioState *m) {
1168
s32 val0C;
1169
s16 slopeClass = mario_get_floor_class(m);
1170
1171
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
1172
return drop_and_set_mario_action(m, ACT_WALKING, 0);
1173
}
1174
1175
if (should_begin_sliding(m)) {
1176
return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0);
1177
}
1178
1179
if (m->input & INPUT_B_PRESSED) {
1180
return set_mario_action(m, ACT_THROWING, 0);
1181
}
1182
1183
if (m->input & INPUT_A_PRESSED) {
1184
return set_jumping_action(m, ACT_HOLD_JUMP, 0);
1185
}
1186
1187
if (m->input & INPUT_Z_PRESSED) {
1188
return drop_and_set_mario_action(m, ACT_CROUCH_SLIDE, 0);
1189
}
1190
1191
if (m->input & INPUT_NONZERO_ANALOG) {
1192
return set_mario_action(m, ACT_HOLD_WALKING, 0);
1193
}
1194
1195
if (update_decelerating_speed(m)) {
1196
return set_mario_action(m, ACT_HOLD_IDLE, 0);
1197
}
1198
1199
m->intendedMag *= 0.4f;
1200
1201
switch (perform_ground_step(m)) {
1202
case GROUND_STEP_LEFT_GROUND:
1203
set_mario_action(m, ACT_HOLD_FREEFALL, 0);
1204
break;
1205
1206
case GROUND_STEP_HIT_WALL:
1207
if (slopeClass == SURFACE_CLASS_VERY_SLIPPERY) {
1208
mario_bonk_reflection(m, TRUE);
1209
} else {
1210
mario_set_forward_vel(m, 0.0f);
1211
}
1212
break;
1213
}
1214
1215
if (slopeClass == SURFACE_CLASS_VERY_SLIPPERY) {
1216
set_mario_animation(m, MARIO_ANIM_IDLE_WITH_LIGHT_OBJ);
1217
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
1218
adjust_sound_for_speed(m);
1219
m->particleFlags |= PARTICLE_DUST;
1220
} else {
1221
//! (Speed Crash) This crashes if Mario has more speed than 2^15 speed.
1222
if ((val0C = (s32)(m->forwardVel * 0x10000)) < 0x1000) {
1223
val0C = 0x1000;
1224
}
1225
1226
set_mario_anim_with_accel(m, MARIO_ANIM_WALK_WITH_LIGHT_OBJ, val0C);
1227
play_step_sound(m, 12, 62);
1228
}
1229
1230
return FALSE;
1231
}
1232
1233
s32 act_riding_shell_ground(struct MarioState *m) {
1234
s16 startYaw = m->faceAngle[1];
1235
1236
if (m->input & INPUT_A_PRESSED) {
1237
return set_mario_action(m, ACT_RIDING_SHELL_JUMP, 0);
1238
}
1239
1240
if (m->input & INPUT_Z_PRESSED) {
1241
mario_stop_riding_object(m);
1242
if (m->forwardVel < 24.0f) {
1243
mario_set_forward_vel(m, 24.0f);
1244
}
1245
return set_mario_action(m, ACT_CROUCH_SLIDE, 0);
1246
}
1247
1248
update_shell_speed(m);
1249
set_mario_animation(m, m->actionArg == 0 ? MARIO_ANIM_START_RIDING_SHELL : MARIO_ANIM_RIDING_SHELL);
1250
1251
switch (perform_ground_step(m)) {
1252
case GROUND_STEP_LEFT_GROUND:
1253
set_mario_action(m, ACT_RIDING_SHELL_FALL, 0);
1254
break;
1255
1256
case GROUND_STEP_HIT_WALL:
1257
mario_stop_riding_object(m);
1258
play_sound(m->flags & MARIO_METAL_CAP ? SOUND_ACTION_METAL_BONK : SOUND_ACTION_BONK,
1259
m->marioObj->header.gfx.cameraToObject);
1260
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1261
set_mario_action(m, ACT_BACKWARD_GROUND_KB, 0);
1262
break;
1263
}
1264
1265
tilt_body_ground_shell(m, startYaw);
1266
if (m->floor->type == SURFACE_BURNING) {
1267
play_sound(SOUND_MOVING_RIDING_SHELL_LAVA, m->marioObj->header.gfx.cameraToObject);
1268
} else {
1269
play_sound(SOUND_MOVING_TERRAIN_RIDING_SHELL + m->terrainSoundAddend,
1270
m->marioObj->header.gfx.cameraToObject);
1271
}
1272
1273
adjust_sound_for_speed(m);
1274
#if ENABLE_RUMBLE
1275
reset_rumble_timers();
1276
#endif
1277
return FALSE;
1278
}
1279
1280
s32 act_crawling(struct MarioState *m) {
1281
s32 val04;
1282
1283
if (should_begin_sliding(m)) {
1284
return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
1285
}
1286
1287
if (m->input & INPUT_FIRST_PERSON) {
1288
return set_mario_action(m, ACT_STOP_CRAWLING, 0);
1289
}
1290
1291
if (m->input & INPUT_A_PRESSED) {
1292
return set_jumping_action(m, ACT_JUMP, 0);
1293
}
1294
1295
if (check_ground_dive_or_punch(m)) {
1296
return TRUE;
1297
}
1298
1299
if (m->input & INPUT_UNKNOWN_5) {
1300
return set_mario_action(m, ACT_STOP_CRAWLING, 0);
1301
}
1302
1303
if (!(m->input & INPUT_Z_DOWN)) {
1304
return set_mario_action(m, ACT_STOP_CRAWLING, 0);
1305
}
1306
1307
m->intendedMag *= 0.1f;
1308
1309
update_walking_speed(m);
1310
1311
switch (perform_ground_step(m)) {
1312
case GROUND_STEP_LEFT_GROUND:
1313
set_mario_action(m, ACT_FREEFALL, 0);
1314
break;
1315
1316
case GROUND_STEP_HIT_WALL:
1317
if (m->forwardVel > 10.0f) {
1318
mario_set_forward_vel(m, 10.0f);
1319
}
1320
//! Possibly unintended missing break
1321
1322
case GROUND_STEP_NONE:
1323
align_with_floor(m);
1324
break;
1325
}
1326
1327
val04 = (s32)(m->intendedMag * 2.0f * 0x10000);
1328
set_mario_anim_with_accel(m, MARIO_ANIM_CRAWLING, val04);
1329
play_step_sound(m, 26, 79);
1330
return FALSE;
1331
}
1332
1333
s32 act_burning_ground(struct MarioState *m) {
1334
if (m->input & INPUT_A_PRESSED) {
1335
return set_mario_action(m, ACT_BURNING_JUMP, 0);
1336
}
1337
1338
m->marioObj->oMarioBurnTimer += 2;
1339
if (m->marioObj->oMarioBurnTimer > 160) {
1340
return set_mario_action(m, ACT_WALKING, 0);
1341
}
1342
1343
if (m->waterLevel - m->floorHeight > 50.0f) {
1344
play_sound(SOUND_GENERAL_FLAME_OUT, m->marioObj->header.gfx.cameraToObject);
1345
return set_mario_action(m, ACT_WALKING, 0);
1346
}
1347
1348
if (m->forwardVel < 8.0f) {
1349
m->forwardVel = 8.0f;
1350
}
1351
if (m->forwardVel > 48.0f) {
1352
m->forwardVel = 48.0f;
1353
}
1354
1355
m->forwardVel = approach_f32(m->forwardVel, 32.0f, 4.0f, 1.0f);
1356
1357
if (m->input & INPUT_NONZERO_ANALOG) {
1358
if (configImprovedControls) {
1359
m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
1360
}
1361
else {
1362
m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x600, 0x600);
1363
}
1364
}
1365
1366
apply_slope_accel(m);
1367
1368
if (perform_ground_step(m) == GROUND_STEP_LEFT_GROUND) {
1369
set_mario_action(m, ACT_BURNING_FALL, 0);
1370
}
1371
1372
set_mario_anim_with_accel(m, MARIO_ANIM_RUNNING, (s32)(m->forwardVel / 2.0f * 0x10000));
1373
play_step_sound(m, 9, 45);
1374
1375
m->particleFlags |= PARTICLE_FIRE;
1376
play_sound(SOUND_MOVING_LAVA_BURN, m->marioObj->header.gfx.cameraToObject);
1377
1378
m->health -= 10;
1379
if (m->health < 0x100) {
1380
set_mario_action(m, ACT_STANDING_DEATH, 0);
1381
}
1382
1383
m->marioBodyState->eyeState = MARIO_EYES_DEAD;
1384
#if ENABLE_RUMBLE
1385
reset_rumble_timers();
1386
#endif
1387
return FALSE;
1388
}
1389
1390
void tilt_body_butt_slide(struct MarioState *m) {
1391
s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
1392
m->marioBodyState->torsoAngle[0] = (s32)(5461.3335f * m->intendedMag / 32.0f * coss(intendedDYaw));
1393
m->marioBodyState->torsoAngle[2] = (s32)(-(5461.3335f * m->intendedMag / 32.0f * sins(intendedDYaw)));
1394
}
1395
1396
void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32 animation, u32 sound) {
1397
Vec3f pos;
1398
1399
vec3f_copy(pos, m->pos);
1400
if (sound)
1401
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
1402
1403
#if ENABLE_RUMBLE
1404
reset_rumble_timers();
1405
#endif
1406
1407
adjust_sound_for_speed(m);
1408
1409
switch (perform_ground_step(m)) {
1410
case GROUND_STEP_LEFT_GROUND:
1411
set_mario_action(m, airAction, 0);
1412
if (m->forwardVel < -50.0f || 50.0f < m->forwardVel) {
1413
play_sound(SOUND_MARIO_HOOHOO, m->marioObj->header.gfx.cameraToObject);
1414
}
1415
break;
1416
1417
case GROUND_STEP_NONE:
1418
set_mario_animation(m, animation);
1419
align_with_floor(m);
1420
m->particleFlags |= PARTICLE_DUST;
1421
break;
1422
1423
case GROUND_STEP_HIT_WALL:
1424
if (!mario_floor_is_slippery(m)) {
1425
#ifdef VERSION_JP
1426
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1427
#else
1428
if (m->forwardVel > 16.0f) {
1429
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1430
}
1431
#endif
1432
slide_bonk(m, ACT_GROUND_BONK, endAction);
1433
} else if (m->wall != NULL) {
1434
s16 wallAngle = atan2s(m->wall->normal.z, m->wall->normal.x);
1435
f32 slideSpeed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
1436
1437
if ((slideSpeed *= 0.9) < 4.0f) {
1438
slideSpeed = 4.0f;
1439
}
1440
1441
m->slideYaw = wallAngle - (s16)(m->slideYaw - wallAngle) + 0x8000;
1442
1443
m->vel[0] = m->slideVelX = slideSpeed * sins(m->slideYaw);
1444
m->vel[2] = m->slideVelZ = slideSpeed * coss(m->slideYaw);
1445
}
1446
1447
align_with_floor(m);
1448
break;
1449
}
1450
}
1451
1452
s32 common_slide_action_with_jump(struct MarioState *m, u32 stopAction, u32 jumpAction, u32 airAction,
1453
s32 animation, u32 sound) {
1454
if (m->actionTimer == 5) {
1455
if (m->input & INPUT_A_PRESSED) {
1456
return set_jumping_action(m, jumpAction, 0);
1457
}
1458
} else {
1459
m->actionTimer++;
1460
}
1461
1462
if (update_sliding(m, 4.0f)) {
1463
return set_mario_action(m, stopAction, 0);
1464
}
1465
1466
common_slide_action(m, stopAction, airAction, animation, sound);
1467
return FALSE;
1468
}
1469
1470
s32 act_butt_slide(struct MarioState *m) {
1471
s32 cancel = common_slide_action_with_jump(m, ACT_BUTT_SLIDE_STOP, ACT_JUMP, ACT_BUTT_SLIDE_AIR,
1472
MARIO_ANIM_SLIDE, TRUE);
1473
tilt_body_butt_slide(m);
1474
return cancel;
1475
}
1476
1477
s32 act_hold_butt_slide(struct MarioState *m) {
1478
s32 cancel;
1479
1480
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
1481
return drop_and_set_mario_action(m, ACT_BUTT_SLIDE, 0);
1482
}
1483
1484
cancel = common_slide_action_with_jump(m, ACT_HOLD_BUTT_SLIDE_STOP, ACT_HOLD_JUMP, ACT_HOLD_BUTT_SLIDE_AIR,
1485
MARIO_ANIM_SLIDING_ON_BOTTOM_WITH_LIGHT_OBJ, TRUE);
1486
tilt_body_butt_slide(m);
1487
return cancel;
1488
}
1489
1490
s32 act_crouch_slide(struct MarioState *m) {
1491
s32 cancel;
1492
1493
if (m->input & INPUT_ABOVE_SLIDE) {
1494
return set_mario_action(m, ACT_BUTT_SLIDE, 0);
1495
}
1496
1497
if (m->actionTimer < 30) {
1498
m->actionTimer++;
1499
if (m->input & INPUT_A_PRESSED) {
1500
if (m->forwardVel > 10.0f) {
1501
return set_jumping_action(m, ACT_LONG_JUMP, 0);
1502
}
1503
}
1504
}
1505
1506
if (m->input & INPUT_B_PRESSED) {
1507
if (configRolling) {
1508
return set_mario_action(m, ACT_ROLL, 0);
1509
}
1510
else if (m->forwardVel >= 10.0f) {
1511
return set_mario_action(m, ACT_SLIDE_KICK, 0);
1512
} else {
1513
return set_mario_action(m, ACT_MOVE_PUNCHING, 0x0009);
1514
}
1515
}
1516
1517
if (m->input & INPUT_A_PRESSED) {
1518
return set_jumping_action(m, ACT_JUMP, 0);
1519
}
1520
1521
if (m->input & INPUT_FIRST_PERSON) {
1522
return set_mario_action(m, ACT_BRAKING, 0);
1523
}
1524
1525
cancel = common_slide_action_with_jump(m, ACT_CROUCHING, ACT_JUMP, ACT_FREEFALL,
1526
MARIO_ANIM_START_CROUCHING, TRUE);
1527
return cancel;
1528
}
1529
1530
s32 act_slide_kick_slide(struct MarioState *m) {
1531
if (m->input & INPUT_A_PRESSED) {
1532
#if ENABLE_RUMBLE
1533
queue_rumble_data(5, 80);
1534
#endif
1535
if (configFlashbackGroundPound)
1536
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
1537
return set_jumping_action(m, ACT_FORWARD_ROLLOUT, 0);
1538
}
1539
1540
set_mario_animation(m, MARIO_ANIM_SLIDE_KICK);
1541
if (is_anim_at_end(m) && m->forwardVel < 1.0f) {
1542
return set_mario_action(m, ACT_SLIDE_KICK_SLIDE_STOP, 0);
1543
}
1544
1545
update_sliding(m, 1.0f);
1546
switch (perform_ground_step(m)) {
1547
case GROUND_STEP_LEFT_GROUND:
1548
set_mario_action(m, ACT_FREEFALL, 2);
1549
break;
1550
1551
case GROUND_STEP_HIT_WALL:
1552
mario_bonk_reflection(m, TRUE);
1553
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1554
set_mario_action(m, ACT_BACKWARD_GROUND_KB, 0);
1555
break;
1556
}
1557
1558
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
1559
m->particleFlags |= PARTICLE_DUST;
1560
return FALSE;
1561
}
1562
1563
s32 stomach_slide_action(struct MarioState *m, u32 stopAction, u32 airAction, s32 animation) {
1564
if (m->actionTimer == 5) {
1565
if (!(m->input & INPUT_ABOVE_SLIDE) && (m->input & (INPUT_A_PRESSED | INPUT_B_PRESSED))) {
1566
#if ENABLE_RUMBLE
1567
queue_rumble_data(5, 80);
1568
#endif
1569
if (configFlashbackGroundPound)
1570
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
1571
return drop_and_set_mario_action(
1572
m, m->forwardVel >= 0.0f ? ACT_FORWARD_ROLLOUT : ACT_BACKWARD_ROLLOUT, 0);
1573
}
1574
} else {
1575
m->actionTimer++;
1576
}
1577
1578
if (update_sliding(m, 4.0f)) {
1579
return set_mario_action(m, stopAction, 0);
1580
}
1581
1582
common_slide_action(m, stopAction, airAction, animation, TRUE);
1583
return FALSE;
1584
}
1585
1586
s32 act_stomach_slide(struct MarioState *m) {
1587
s32 cancel = stomach_slide_action(m, ACT_STOMACH_SLIDE_STOP, ACT_FREEFALL, MARIO_ANIM_SLIDE_DIVE);
1588
return cancel;
1589
}
1590
1591
s32 act_hold_stomach_slide(struct MarioState *m) {
1592
s32 cancel;
1593
1594
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
1595
return drop_and_set_mario_action(m, ACT_STOMACH_SLIDE, 0);
1596
}
1597
1598
cancel = stomach_slide_action(m, ACT_DIVE_PICKING_UP, ACT_HOLD_FREEFALL, MARIO_ANIM_SLIDE_DIVE);
1599
return cancel;
1600
}
1601
1602
s32 act_dive_slide(struct MarioState *m) {
1603
if (!(m->input & INPUT_ABOVE_SLIDE) && (m->input & (INPUT_A_PRESSED | INPUT_B_PRESSED))) {
1604
#if ENABLE_RUMBLE
1605
queue_rumble_data(5, 80);
1606
#endif
1607
if (configSunshineDive && m->input & INPUT_B_PRESSED) {
1608
mario_set_forward_vel(m, 20.0f);
1609
m->vel[1] = 21.0f;
1610
return set_mario_action(m, ACT_DIVE, 0);
1611
}
1612
else {
1613
if (configFlashbackGroundPound)
1614
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
1615
return set_mario_action(m, m->forwardVel > 0.0f ? ACT_FORWARD_ROLLOUT : ACT_BACKWARD_ROLLOUT,
1616
0);
1617
}
1618
}
1619
1620
play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
1621
1622
//! If the dive slide ends on the same frame that we pick up on object,
1623
// Mario will not be in the dive slide action for the call to
1624
// mario_check_object_grab, and so will end up in the regular picking action,
1625
// rather than the picking up after dive action.
1626
1627
if (update_sliding(m, 8.0f) && is_anim_at_end(m)) {
1628
mario_set_forward_vel(m, 0.0f);
1629
set_mario_action(m, ACT_STOMACH_SLIDE_STOP, 0);
1630
}
1631
1632
if (mario_check_object_grab(m)) {
1633
mario_grab_used_object(m);
1634
m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ;
1635
return TRUE;
1636
}
1637
1638
common_slide_action(m, ACT_STOMACH_SLIDE_STOP, ACT_FREEFALL, MARIO_ANIM_DIVE, TRUE);
1639
return FALSE;
1640
}
1641
1642
s32 act_roll(struct MarioState *m) {
1643
s32 cancel;
1644
1645
// Boosting
1646
if ((m->input & INPUT_Z_DOWN) && (m->input & INPUT_B_PRESSED) && m->forwardVel < 48.0f) {
1647
mario_set_forward_vel(m, 96.0f);
1648
m->particleFlags |= PARTICLE_VERTICAL_STAR;
1649
play_sound(SOUND_MARIO_HOOHOO, m->marioObj->header.gfx.cameraToObject);
1650
}
1651
1652
// Stop rolling after letting go of the trigger
1653
if ((!(m->input & INPUT_Z_DOWN) && m->forwardVel < 16.0f)
1654
|| (m->input & INPUT_Z_DOWN && m->forwardVel < 4.0f)) {
1655
return set_mario_action(m, ACT_BRAKING, 0);
1656
}
1657
1658
if (m->input & INPUT_A_PRESSED) {
1659
return set_jumping_action(m, ACT_LONG_JUMP, 0);
1660
}
1661
1662
if (m->marioObj->header.gfx.animInfo.animFrame == 7) {
1663
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
1664
}
1665
1666
cancel = common_slide_action_with_jump(m, ACT_CROUCHING, ACT_LONG_JUMP, ACT_ROLL_FALL,
1667
MARIO_ANIM_FORWARD_SPINNING, FALSE);
1668
1669
return cancel;
1670
}
1671
1672
s32 common_ground_knockback_action(struct MarioState *m, s32 animation, s32 arg2, s32 arg3, s32 arg4) {
1673
s32 animFrame;
1674
1675
if (arg3) {
1676
play_mario_heavy_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
1677
}
1678
1679
if (arg4 > 0) {
1680
play_sound_if_no_flag(m, SOUND_MARIO_ATTACKED, MARIO_MARIO_SOUND_PLAYED);
1681
} else {
1682
#ifdef VERSION_JP
1683
play_sound_if_no_flag(m, SOUND_MARIO_OOOF, MARIO_MARIO_SOUND_PLAYED);
1684
#else
1685
play_sound_if_no_flag(m, SOUND_MARIO_OOOF2, MARIO_MARIO_SOUND_PLAYED);
1686
#endif
1687
}
1688
1689
if (m->forwardVel > 32.0f) {
1690
m->forwardVel = 32.0f;
1691
}
1692
if (m->forwardVel < -32.0f) {
1693
m->forwardVel = -32.0f;
1694
}
1695
1696
animFrame = set_mario_animation(m, animation);
1697
if (animFrame < arg2) {
1698
apply_landing_accel(m, 0.9f);
1699
} else if (m->forwardVel >= 0.0f) {
1700
mario_set_forward_vel(m, 0.1f);
1701
} else {
1702
mario_set_forward_vel(m, -0.1f);
1703
}
1704
1705
if (perform_ground_step(m) == GROUND_STEP_LEFT_GROUND) {
1706
if (m->forwardVel >= 0.0f) {
1707
set_mario_action(m, ACT_FORWARD_AIR_KB, arg4);
1708
} else {
1709
set_mario_action(m, ACT_BACKWARD_AIR_KB, arg4);
1710
}
1711
} else if (is_anim_at_end(m)) {
1712
if (m->health < 0x100) {
1713
set_mario_action(m, ACT_STANDING_DEATH, 0);
1714
} else {
1715
if (arg4 > 0) {
1716
m->invincTimer = 30;
1717
}
1718
set_mario_action(m, ACT_IDLE, 0);
1719
}
1720
}
1721
1722
return animFrame;
1723
}
1724
1725
s32 act_hard_backward_ground_kb(struct MarioState *m) {
1726
s32 animFrame =
1727
common_ground_knockback_action(m, MARIO_ANIM_FALL_OVER_BACKWARDS, 43, TRUE, m->actionArg);
1728
if (animFrame == 43 && m->health < 0x100) {
1729
set_mario_action(m, ACT_DEATH_ON_BACK, 0);
1730
}
1731
1732
#ifndef VERSION_JP
1733
if (animFrame == 54 && m->prevAction == ACT_SPECIAL_DEATH_EXIT) {
1734
play_sound(SOUND_MARIO_MAMA_MIA, m->marioObj->header.gfx.cameraToObject);
1735
}
1736
#endif
1737
1738
if (animFrame == 69) {
1739
play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING);
1740
}
1741
1742
return FALSE;
1743
}
1744
1745
s32 act_hard_forward_ground_kb(struct MarioState *m) {
1746
s32 animFrame =
1747
common_ground_knockback_action(m, MARIO_ANIM_LAND_ON_STOMACH, 21, TRUE, m->actionArg);
1748
if (animFrame == 23 && m->health < 0x100) {
1749
set_mario_action(m, ACT_DEATH_ON_STOMACH, 0);
1750
}
1751
1752
return FALSE;
1753
}
1754
1755
s32 act_backward_ground_kb(struct MarioState *m) {
1756
common_ground_knockback_action(m, MARIO_ANIM_BACKWARD_KB, 22, TRUE, m->actionArg);
1757
return FALSE;
1758
}
1759
1760
s32 act_forward_ground_kb(struct MarioState *m) {
1761
common_ground_knockback_action(m, MARIO_ANIM_FORWARD_KB, 20, TRUE, m->actionArg);
1762
return FALSE;
1763
}
1764
1765
s32 act_soft_backward_ground_kb(struct MarioState *m) {
1766
common_ground_knockback_action(m, MARIO_ANIM_SOFT_BACK_KB, 100, FALSE, m->actionArg);
1767
return FALSE;
1768
}
1769
1770
s32 act_soft_forward_ground_kb(struct MarioState *m) {
1771
common_ground_knockback_action(m, MARIO_ANIM_SOFT_FRONT_KB, 100, FALSE, m->actionArg);
1772
return FALSE;
1773
}
1774
1775
s32 act_ground_bonk(struct MarioState *m) {
1776
s32 animFrame =
1777
common_ground_knockback_action(m, MARIO_ANIM_GROUND_BONK, 32, TRUE, m->actionArg);
1778
if (animFrame == 32) {
1779
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1780
}
1781
return FALSE;
1782
}
1783
1784
s32 act_death_exit_land(struct MarioState *m) {
1785
s32 animFrame;
1786
1787
apply_landing_accel(m, 0.9f);
1788
play_mario_heavy_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
1789
1790
animFrame = set_mario_animation(m, MARIO_ANIM_FALL_OVER_BACKWARDS);
1791
1792
if (animFrame == 54) {
1793
play_sound(SOUND_MARIO_MAMA_MIA, m->marioObj->header.gfx.cameraToObject);
1794
}
1795
if (animFrame == 68) {
1796
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
1797
}
1798
1799
if (is_anim_at_end(m)) {
1800
set_mario_action(m, ACT_IDLE, 0);
1801
}
1802
1803
return FALSE;
1804
}
1805
1806
u32 common_landing_action(struct MarioState *m, s16 animation, u32 airAction) {
1807
u32 stepResult;
1808
1809
if (m->input & INPUT_NONZERO_ANALOG) {
1810
apply_landing_accel(m, 0.98f);
1811
} else if (m->forwardVel >= 16.0f) {
1812
apply_slope_decel(m, 2.0f);
1813
} else {
1814
m->vel[1] = 0.0f;
1815
}
1816
1817
stepResult = perform_ground_step(m);
1818
switch (stepResult) {
1819
case GROUND_STEP_LEFT_GROUND:
1820
set_mario_action(m, airAction, 0);
1821
break;
1822
1823
case GROUND_STEP_HIT_WALL:
1824
set_mario_animation(m, MARIO_ANIM_PUSHING);
1825
break;
1826
}
1827
1828
if (m->forwardVel > 16.0f) {
1829
m->particleFlags |= PARTICLE_DUST;
1830
}
1831
1832
set_mario_animation(m, animation);
1833
play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING);
1834
1835
if (m->floor->type >= SURFACE_SHALLOW_QUICKSAND && m->floor->type <= SURFACE_MOVING_QUICKSAND) {
1836
m->quicksandDepth += (4 - m->actionTimer) * 3.5f - 0.5f;
1837
}
1838
1839
return stepResult;
1840
}
1841
1842
s32 common_landing_cancels(struct MarioState *m, struct LandingAction *landingAction,
1843
s32 (*setAPressAction)(struct MarioState *, u32, u32)) {
1844
//! Everything here, including floor steepness, is checked before checking
1845
// if Mario is actually on the floor. This leads to e.g. remote sliding.
1846
1847
if (m->floor->normal.y < 0.2923717f) {
1848
return mario_push_off_steep_floor(m, landingAction->verySteepAction, 0);
1849
}
1850
1851
m->doubleJumpTimer = landingAction->unk02;
1852
1853
if (should_begin_sliding(m)) {
1854
return set_mario_action(m, landingAction->slideAction, 0);
1855
}
1856
1857
if (m->input & INPUT_FIRST_PERSON) {
1858
return set_mario_action(m, landingAction->endAction, 0);
1859
}
1860
1861
if (++m->actionTimer >= landingAction->numFrames) {
1862
return set_mario_action(m, landingAction->endAction, 0);
1863
}
1864
1865
if (m->input & INPUT_A_PRESSED) {
1866
return setAPressAction(m, landingAction->aPressedAction, 0);
1867
}
1868
1869
if (m->input & INPUT_OFF_FLOOR) {
1870
return set_mario_action(m, landingAction->offFloorAction, 0);
1871
}
1872
1873
return FALSE;
1874
}
1875
1876
s32 act_jump_land(struct MarioState *m) {
1877
if (common_landing_cancels(m, &sJumpLandAction, set_jumping_action)) {
1878
return TRUE;
1879
}
1880
1881
common_landing_action(m, MARIO_ANIM_LAND_FROM_SINGLE_JUMP, ACT_FREEFALL);
1882
return FALSE;
1883
}
1884
1885
s32 act_freefall_land(struct MarioState *m) {
1886
if (common_landing_cancels(m, &sFreefallLandAction, set_jumping_action)) {
1887
return TRUE;
1888
}
1889
1890
common_landing_action(m, MARIO_ANIM_GENERAL_LAND, ACT_FREEFALL);
1891
return FALSE;
1892
}
1893
1894
s32 act_side_flip_land(struct MarioState *m) {
1895
if (common_landing_cancels(m, &sSideFlipLandAction, set_jumping_action)) {
1896
return TRUE;
1897
}
1898
1899
if (common_landing_action(m, MARIO_ANIM_SLIDEFLIP_LAND, ACT_FREEFALL) != GROUND_STEP_HIT_WALL) {
1900
m->marioObj->header.gfx.angle[1] += 0x8000;
1901
}
1902
return FALSE;
1903
}
1904
1905
s32 act_hold_jump_land(struct MarioState *m) {
1906
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
1907
return drop_and_set_mario_action(m, ACT_JUMP_LAND_STOP, 0);
1908
}
1909
1910
if (common_landing_cancels(m, &sHoldJumpLandAction, set_jumping_action)) {
1911
return TRUE;
1912
}
1913
1914
common_landing_action(m, MARIO_ANIM_JUMP_LAND_WITH_LIGHT_OBJ, ACT_HOLD_FREEFALL);
1915
return FALSE;
1916
}
1917
1918
s32 act_hold_freefall_land(struct MarioState *m) {
1919
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
1920
return drop_and_set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
1921
}
1922
1923
if (common_landing_cancels(m, &sHoldFreefallLandAction, set_jumping_action)) {
1924
return TRUE;
1925
}
1926
1927
common_landing_action(m, MARIO_ANIM_FALL_LAND_WITH_LIGHT_OBJ, ACT_HOLD_FREEFALL);
1928
return FALSE;
1929
}
1930
1931
s32 act_long_jump_land(struct MarioState *m) {
1932
#ifdef VERSION_SH
1933
// BLJ (Backwards Long Jump) speed build up fix, crushing SimpleFlips's dreams since July 1997
1934
if (m->forwardVel < 0.0f) {
1935
m->forwardVel = 0.0f;
1936
}
1937
#endif
1938
1939
// Sorry daddy...
1940
if (configApplyBugFixes > 2 && m->forwardVel < 0.0f) {
1941
m->forwardVel = 0.0f;
1942
}
1943
1944
if (!(m->input & INPUT_Z_DOWN)) {
1945
m->input &= ~INPUT_A_PRESSED;
1946
}
1947
1948
if (common_landing_cancels(m, &sLongJumpLandAction, set_jumping_action)) {
1949
return TRUE;
1950
}
1951
1952
if (!(m->input & INPUT_NONZERO_ANALOG)) {
1953
play_sound_if_no_flag(m, SOUND_MARIO_UH2_2, MARIO_MARIO_SOUND_PLAYED);
1954
}
1955
1956
common_landing_action(m,
1957
!m->marioObj->oMarioLongJumpIsSlow ? MARIO_ANIM_CROUCH_FROM_FAST_LONGJUMP
1958
: MARIO_ANIM_CROUCH_FROM_SLOW_LONGJUMP,
1959
ACT_FREEFALL);
1960
return FALSE;
1961
}
1962
1963
s32 act_double_jump_land(struct MarioState *m) {
1964
if (common_landing_cancels(m, &sDoubleJumpLandAction, set_triple_jump_action)) {
1965
return TRUE;
1966
}
1967
common_landing_action(m, MARIO_ANIM_LAND_FROM_DOUBLE_JUMP, ACT_FREEFALL);
1968
return FALSE;
1969
}
1970
1971
s32 act_triple_jump_land(struct MarioState *m) {
1972
m->input &= ~INPUT_A_PRESSED;
1973
1974
if (common_landing_cancels(m, &sTripleJumpLandAction, set_jumping_action)) {
1975
return TRUE;
1976
}
1977
1978
if (!(m->input & INPUT_NONZERO_ANALOG)) {
1979
play_sound_if_no_flag(m, SOUND_MARIO_HAHA, MARIO_MARIO_SOUND_PLAYED);
1980
}
1981
1982
common_landing_action(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_FREEFALL);
1983
return FALSE;
1984
}
1985
1986
s32 act_backflip_land(struct MarioState *m) {
1987
if (!(m->input & INPUT_Z_DOWN)) {
1988
m->input &= ~INPUT_A_PRESSED;
1989
}
1990
1991
if (common_landing_cancels(m, &sBackflipLandAction, set_jumping_action)) {
1992
return TRUE;
1993
}
1994
1995
if (!(m->input & INPUT_NONZERO_ANALOG)) {
1996
play_sound_if_no_flag(m, SOUND_MARIO_HAHA, MARIO_MARIO_SOUND_PLAYED);
1997
}
1998
1999
common_landing_action(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_FREEFALL);
2000
return FALSE;
2001
}
2002
2003
s32 quicksand_jump_land_action(struct MarioState *m, s32 animation1, s32 animation2, u32 endAction,
2004
u32 airAction) {
2005
if (m->actionTimer++ < 6) {
2006
m->quicksandDepth -= (7 - m->actionTimer) * 0.8f;
2007
if (m->quicksandDepth < 1.0f) {
2008
m->quicksandDepth = 1.1f;
2009
}
2010
2011
play_mario_jump_sound(m);
2012
set_mario_animation(m, animation1);
2013
} else {
2014
if (m->actionTimer >= 13) {
2015
return set_mario_action(m, endAction, 0);
2016
}
2017
2018
set_mario_animation(m, animation2);
2019
}
2020
2021
apply_landing_accel(m, 0.95f);
2022
if (perform_ground_step(m) == GROUND_STEP_LEFT_GROUND) {
2023
set_mario_action(m, airAction, 0);
2024
}
2025
2026
return FALSE;
2027
}
2028
2029
s32 act_quicksand_jump_land(struct MarioState *m) {
2030
s32 cancel = quicksand_jump_land_action(m, MARIO_ANIM_SINGLE_JUMP, MARIO_ANIM_LAND_FROM_SINGLE_JUMP,
2031
ACT_JUMP_LAND_STOP, ACT_FREEFALL);
2032
return cancel;
2033
}
2034
2035
s32 act_hold_quicksand_jump_land(struct MarioState *m) {
2036
s32 cancel = quicksand_jump_land_action(m, MARIO_ANIM_JUMP_WITH_LIGHT_OBJ,
2037
MARIO_ANIM_JUMP_LAND_WITH_LIGHT_OBJ, ACT_HOLD_JUMP_LAND_STOP,
2038
ACT_HOLD_FREEFALL);
2039
return cancel;
2040
}
2041
2042
s32 check_common_moving_cancels(struct MarioState *m) {
2043
if (m->pos[1] < m->waterLevel - 100) {
2044
return set_water_plunge_action(m);
2045
}
2046
2047
if (!(m->action & ACT_FLAG_INVULNERABLE) && (m->input & INPUT_STOMPED)) {
2048
return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
2049
}
2050
2051
if (m->input & INPUT_SQUISHED) {
2052
return drop_and_set_mario_action(m, ACT_SQUISHED, 0);
2053
}
2054
2055
if (!(m->action & ACT_FLAG_INVULNERABLE)) {
2056
if (m->health < 0x100) {
2057
return drop_and_set_mario_action(m, ACT_STANDING_DEATH, 0);
2058
}
2059
}
2060
2061
return FALSE;
2062
}
2063
2064
s32 mario_execute_moving_action(struct MarioState *m) {
2065
s32 cancel;
2066
2067
if (check_common_moving_cancels(m)) {
2068
return TRUE;
2069
}
2070
2071
if (mario_update_quicksand(m, 0.25f)) {
2072
return TRUE;
2073
}
2074
2075
/* clang-format off */
2076
switch (m->action) {
2077
case ACT_WALKING: cancel = act_walking(m); break;
2078
case ACT_HOLD_WALKING: cancel = act_hold_walking(m); break;
2079
case ACT_HOLD_HEAVY_WALKING: cancel = act_hold_heavy_walking(m); break;
2080
case ACT_TURNING_AROUND: cancel = act_turning_around(m); break;
2081
case ACT_FINISH_TURNING_AROUND: cancel = act_finish_turning_around(m); break;
2082
case ACT_BRAKING: cancel = act_braking(m); break;
2083
case ACT_RIDING_SHELL_GROUND: cancel = act_riding_shell_ground(m); break;
2084
case ACT_CRAWLING: cancel = act_crawling(m); break;
2085
case ACT_BURNING_GROUND: cancel = act_burning_ground(m); break;
2086
case ACT_DECELERATING: cancel = act_decelerating(m); break;
2087
case ACT_HOLD_DECELERATING: cancel = act_hold_decelerating(m); break;
2088
case ACT_BUTT_SLIDE: cancel = act_butt_slide(m); break;
2089
case ACT_STOMACH_SLIDE: cancel = act_stomach_slide(m); break;
2090
case ACT_HOLD_BUTT_SLIDE: cancel = act_hold_butt_slide(m); break;
2091
case ACT_HOLD_STOMACH_SLIDE: cancel = act_hold_stomach_slide(m); break;
2092
case ACT_DIVE_SLIDE: cancel = act_dive_slide(m); break;
2093
case ACT_MOVE_PUNCHING: cancel = act_move_punching(m); break;
2094
case ACT_CROUCH_SLIDE: cancel = act_crouch_slide(m); break;
2095
case ACT_SLIDE_KICK_SLIDE: cancel = act_slide_kick_slide(m); break;
2096
case ACT_ROLL: cancel = act_roll(m); break;
2097
case ACT_HARD_BACKWARD_GROUND_KB: cancel = act_hard_backward_ground_kb(m); break;
2098
case ACT_HARD_FORWARD_GROUND_KB: cancel = act_hard_forward_ground_kb(m); break;
2099
case ACT_BACKWARD_GROUND_KB: cancel = act_backward_ground_kb(m); break;
2100
case ACT_FORWARD_GROUND_KB: cancel = act_forward_ground_kb(m); break;
2101
case ACT_SOFT_BACKWARD_GROUND_KB: cancel = act_soft_backward_ground_kb(m); break;
2102
case ACT_SOFT_FORWARD_GROUND_KB: cancel = act_soft_forward_ground_kb(m); break;
2103
case ACT_GROUND_BONK: cancel = act_ground_bonk(m); break;
2104
case ACT_DEATH_EXIT_LAND: cancel = act_death_exit_land(m); break;
2105
case ACT_JUMP_LAND: cancel = act_jump_land(m); break;
2106
case ACT_FREEFALL_LAND: cancel = act_freefall_land(m); break;
2107
case ACT_DOUBLE_JUMP_LAND: cancel = act_double_jump_land(m); break;
2108
case ACT_SIDE_FLIP_LAND: cancel = act_side_flip_land(m); break;
2109
case ACT_HOLD_JUMP_LAND: cancel = act_hold_jump_land(m); break;
2110
case ACT_HOLD_FREEFALL_LAND: cancel = act_hold_freefall_land(m); break;
2111
case ACT_TRIPLE_JUMP_LAND: cancel = act_triple_jump_land(m); break;
2112
case ACT_BACKFLIP_LAND: cancel = act_backflip_land(m); break;
2113
case ACT_QUICKSAND_JUMP_LAND: cancel = act_quicksand_jump_land(m); break;
2114
case ACT_HOLD_QUICKSAND_JUMP_LAND: cancel = act_hold_quicksand_jump_land(m); break;
2115
case ACT_LONG_JUMP_LAND: cancel = act_long_jump_land(m); break;
2116
}
2117
/* clang-format on */
2118
2119
if (!cancel && (m->input & INPUT_IN_WATER)) {
2120
m->particleFlags |= PARTICLE_WAVE_TRAIL;
2121
m->particleFlags &= ~PARTICLE_DUST;
2122
}
2123
2124
return cancel;
2125
}
2126
2127