@@ -152,13 +152,13 @@ void clean_effect(Player* player, s8 playerIndex) {
152152
153153 if (((player -> effects & BANANA_SPINOUT_EFFECT ) == BANANA_SPINOUT_EFFECT ) ||
154154 (player -> effects & DRIVING_SPINOUT_EFFECT ) == DRIVING_SPINOUT_EFFECT ) {
155- func_8008C8C4 (player , playerIndex );
155+ remove_spinout_effects (player , playerIndex );
156156 }
157157 if ((player -> effects & BANANA_NEAR_SPINOUT_EFFECT ) == BANANA_NEAR_SPINOUT_EFFECT ) {
158- func_8008D0E4 (player , playerIndex );
158+ remove_banana_near_spinout_effect (player , playerIndex );
159159 }
160- if ((player -> kartProps & DRIVING_SPINOUT ) != 0 ) {
161- func_8008D3B0 (player , playerIndex );
160+ if ((player -> kartProps & DRIVING_NEAR_SPINOUT ) != 0 ) {
161+ remove_driving_near_spinout_effect (player , playerIndex );
162162 }
163163 if ((player -> effects & MUSHROOM_EFFECT ) == MUSHROOM_EFFECT ) {
164164 remove_mushroom_effect (player );
@@ -257,13 +257,13 @@ void func_8008C6D0(Player* player, s8 playerIndex) {
257257 player -> unk_042 = 0 ;
258258}
259259
260- void func_8008C73C (Player * player , s8 playerIndex ) {
260+ void add_spinout_effect (Player * player , s8 playerIndex ) {
261261 clean_effect (player , playerIndex );
262262 if (((player -> effects & BANANA_SPINOUT_EFFECT ) != BANANA_SPINOUT_EFFECT ) &&
263263 ((player -> effects & DRIVING_SPINOUT_EFFECT ) != DRIVING_SPINOUT_EFFECT )) {
264264 player -> effects &= ~DRIFTING_EFFECT ;
265265
266- if ((player -> unk_0C0 / 182 ) >= 0 ) {
266+ if ((player -> unk_0C0 / DEGREES_CONVERSION_FACTOR ) >= 0 ) {
267267 player -> effects |= DRIVING_SPINOUT_EFFECT ;
268268 } else {
269269 player -> effects |= BANANA_SPINOUT_EFFECT ;
@@ -293,7 +293,7 @@ void func_8008C73C(Player* player, s8 playerIndex) {
293293 }
294294}
295295
296- void func_8008C8C4 (Player * player , s8 playerId ) {
296+ void remove_spinout_effects (Player * player , s8 playerId ) {
297297 player -> effects &= ~BANANA_SPINOUT_EFFECT ;
298298 player -> effects &= ~DRIVING_SPINOUT_EFFECT ;
299299 player -> unk_0A8 = 0 ;
@@ -347,7 +347,7 @@ void func_8008C9EC(Player* player, s8 playerIndex) {
347347 if (gModeSelection == BATTLE ) {
348348 pop_player_balloon (player , playerIndex );
349349 }
350- func_8008C8C4 (player , playerIndex );
350+ remove_spinout_effects (player , playerIndex );
351351 }
352352 }
353353 } else {
@@ -357,7 +357,7 @@ void func_8008C9EC(Player* player, s8 playerIndex) {
357357 if (stackPadding2 == 0 ) {
358358 player -> unk_0B2 -- ;
359359 if (player -> unk_0B2 <= 0 ) {
360- func_8008C8C4 (player , playerIndex );
360+ remove_spinout_effects (player , playerIndex );
361361 if (gModeSelection == BATTLE ) {
362362 pop_player_balloon (player , playerIndex );
363363 }
@@ -372,141 +372,151 @@ void func_8008C9EC(Player* player, s8 playerIndex) {
372372 }
373373}
374374
375- void func_8008CDC0 (Player * player , s8 playerIndex ) {
375+ void trigger_hit_banana (Player * player , s8 playerIndex ) {
376376 clean_effect (player , playerIndex );
377377
378378 player -> triggers &= ~HIT_BANANA_TRIGGER ;
379- player -> unk_0B4 = 0 ;
380- player -> unk_0B8 = 3.0f ;
381- player -> unk_0AC = 1 ;
379+ player -> swerveTimer = 0 ;
380+ player -> swerveAccelInit = 3.0f ;
381+ player -> swerveDirection = 1 ;
382382 player -> effects &= ~DRIFTING_EFFECT ;
383383
384384 if (((player -> steerPosition >> 16 ) >= 20 ) || ((player -> steerPosition >> 16 ) <= -20 ) ||
385385 (((player -> speed / 18.0f ) * 216.0f ) <= 30.0f ) || ((player -> effects & MIDAIR_EFFECT ) != 0 ) ||
386386 (((player -> type & PLAYER_HUMAN ) == 0 ) && ((player -> effects & LOST_RACE_EFFECT ) == 0 ))) {
387- func_8008C73C (player , playerIndex );
387+ add_spinout_effect (player , playerIndex );
388388 } else {
389389 player -> effects |= BANANA_NEAR_SPINOUT_EFFECT ;
390390 }
391391}
392392
393- void func_8008CEB0 (Player * player , s8 playerIndex ) {
394- f32 var_f0 ;
395- s16 var_v1 ;
396- s16 var_a3 ;
397- s16 temp_f16 ;
398-
399- var_f0 = player -> unk_0B8 ;
400- var_v1 = player -> unk_0B4 ;
401- var_a3 = player -> unk_0AC ;
402- var_v1 ++ ;
403- temp_f16 = (var_v1 * var_f0 ) - (0.2 * (var_v1 * var_v1 ));
404- if ((var_v1 != 0 ) && (temp_f16 < 0 )) {
405- var_v1 = 0 ;
406- var_a3 = - var_a3 ;
407- var_f0 *= 0.8 ;
393+ // almost identical to apply_driving_near_spinout_effect, see there for more documentation
394+ void apply_banana_near_spinout_effect (Player * player , s8 playerIndex ) {
395+ f32 swerve_accel_init ;
396+ s16 swerve_timer ;
397+ s16 swerve_direction ;
398+ s16 swerve_velo_current ;
399+
400+ swerve_accel_init = player -> swerveAccelInit ;
401+ swerve_timer = player -> swerveTimer ;
402+ swerve_direction = player -> swerveDirection ;
403+ swerve_timer ++ ;
404+ swerve_velo_current = (swerve_timer * swerve_accel_init ) - (0.2 * (swerve_timer * swerve_timer ));
405+ if ((swerve_timer != 0 ) && (swerve_velo_current < 0 )) {
406+ swerve_timer = 0 ;
407+ swerve_direction = - swerve_direction ;
408+ swerve_accel_init *= 0.8 ;
409+ // requires braking to recover. A driving spinout allows just releasing gas as well
408410 if ((player -> effects & BRAKING_EFFECT ) == BRAKING_EFFECT ) {
409411 player -> effects |= BANANA_SPINOUT_SAVE_EFFECT ;
410412 }
411- if (var_f0 <= 1.0f ) {
413+ if (swerve_accel_init <= 1.0f ) {
412414 player -> effects &= ~BANANA_NEAR_SPINOUT_EFFECT ;
413415 if ((player -> effects & BANANA_SPINOUT_SAVE_EFFECT ) != BANANA_SPINOUT_SAVE_EFFECT ) {
414- func_8008C73C (player , playerIndex );
415- var_v1 = 0 ;
416+ add_spinout_effect (player , playerIndex );
417+ swerve_timer = 0 ;
416418 } else {
417419 player -> kartGraphics |= WHISTLE ;
418420 player -> effects &= ~BANANA_SPINOUT_SAVE_EFFECT ;
419421 if ((player -> type & PLAYER_HUMAN ) == PLAYER_HUMAN ) {
420422 func_800C90F4 (playerIndex , (player -> characterId * 0x10 ) + 0x29008008 );
421- var_v1 = 0 ;
423+ swerve_timer = 0 ;
422424 }
423425 }
424426 }
425427 }
426- temp_f16 *= var_a3 ;
427- if ((temp_f16 <= 0 ) && (var_a3 == 1 )) {
428- temp_f16 = 0 ;
428+ swerve_velo_current *= swerve_direction ;
429+ if ((swerve_velo_current <= 0 ) && (swerve_direction == 1 )) {
430+ swerve_velo_current = 0 ;
429431 }
430- if ((temp_f16 >= 0 ) && (var_a3 == -1 )) {
431- temp_f16 = 0 ;
432+ if ((swerve_velo_current >= 0 ) && (swerve_direction == -1 )) {
433+ swerve_velo_current = 0 ;
432434 }
433- player -> unk_078 += temp_f16 * 0x12 ;
434- player -> unk_0B8 = var_f0 ;
435- player -> unk_0B4 = var_v1 ;
436- player -> unk_0AC = var_a3 ;
435+ player -> unk_078 += swerve_velo_current * 18 ;
436+ player -> swerveAccelInit = swerve_accel_init ;
437+ player -> swerveTimer = swerve_timer ;
438+ player -> swerveDirection = swerve_direction ;
437439 if (player -> effects & MIDAIR_EFFECT ) {
438- func_8008C73C (player , playerIndex );
440+ add_spinout_effect (player , playerIndex );
439441 player -> effects &= ~BANANA_NEAR_SPINOUT_EFFECT ;
440442 }
441443}
442444
443- void func_8008D0E4 (Player * player , UNUSED s8 playerIndex ) {
445+ void remove_banana_near_spinout_effect (Player * player , UNUSED s8 playerIndex ) {
444446 player -> effects &= ~BANANA_NEAR_SPINOUT_EFFECT ;
445447}
446448
447- void func_8008D0FC (Player * player , s8 playerIndex ) {
449+ void trigger_driving_spinout (Player * player , s8 playerIndex ) {
448450 clean_effect (player , playerIndex );
449451
450452 player -> triggers &= ~DRIVING_SPINOUT_TRIGGER ;
451- player -> unk_0B4 = 0 ;
452- player -> unk_0B8 = 2.0f ;
453- player -> unk_0AC = 1 ;
453+ player -> swerveTimer = 0 ;
454+ player -> swerveAccelInit = 2.0f ;
455+ player -> swerveDirection = 1 ;
454456 player -> effects &= ~DRIFTING_EFFECT ;
455- player -> kartProps |= DRIVING_SPINOUT ;
457+ player -> kartProps |= DRIVING_NEAR_SPINOUT ;
456458}
457459
458- void func_8008D170 (Player * player , s8 playerIndex ) {
459- f32 var_f0 ;
460- s16 var_v1 ;
461- s16 var_a3 ;
462- s16 temp_f16 ;
463-
464- var_f0 = player -> unk_0B8 ;
465- var_v1 = player -> unk_0B4 ;
466- var_a3 = player -> unk_0AC ;
467- var_v1 ++ ;
468- temp_f16 = (var_v1 * var_f0 ) - (0.1 * (var_v1 * var_v1 ));
469- if ((var_v1 != 0 ) && (temp_f16 < 0 )) {
470- var_v1 = 0 ;
471- var_a3 = - var_a3 ;
472- var_f0 *= 0.9 ;
460+ void apply_driving_near_spinout_effect (Player * player , s8 playerIndex ) {
461+ f32 swerve_accel_init ;
462+ s16 swerve_timer ;
463+ s16 swerve_direction ;
464+ s16 swerve_velo_current ;
465+
466+ // These properties are only used for swerving before spinouts
467+ swerve_accel_init = player -> swerveAccelInit ;
468+ swerve_timer = player -> swerveTimer ;
469+ swerve_direction = player -> swerveDirection ;
470+ swerve_timer ++ ;
471+
472+ // Standard physics formula: Velo_current = velo_init + (accel_init * time) + (accel_jerk * time**2) / 2
473+ swerve_velo_current = (swerve_accel_init * swerve_timer ) - (0.1 * (swerve_timer * swerve_timer ));
474+
475+ // Once one swerve finishes, setup to start a smaller one in the opposite direction
476+ if ((swerve_timer != 0 ) && (swerve_velo_current < 0 )) { // (10 * swerve_accel_init < swerve_timer))
477+ swerve_timer = 0 ;
478+ swerve_direction = - swerve_direction ;
479+ swerve_accel_init *= 0.9 ;
473480 if (((player -> effects & BRAKING_EFFECT ) == BRAKING_EFFECT ) || !(player -> kartProps & THROTTLE )) {
474481 player -> effects |= BANANA_SPINOUT_SAVE_EFFECT ;
475482 }
476- if (var_f0 <= 1.3 ) {
477- player -> kartProps &= ~DRIVING_SPINOUT ;
483+ // stop swerving once they are small enough
484+ if (swerve_accel_init <= 1.3 ) {
485+ player -> kartProps &= ~DRIVING_NEAR_SPINOUT ;
478486 if ((player -> effects & BANANA_SPINOUT_SAVE_EFFECT ) != BANANA_SPINOUT_SAVE_EFFECT ) {
479- func_8008C73C (player , playerIndex );
480- var_v1 = 0 ;
487+ add_spinout_effect (player , playerIndex );
488+ swerve_timer = 0 ;
481489 } else {
482490 player -> kartGraphics |= WHISTLE ;
483491 player -> effects &= ~BANANA_SPINOUT_SAVE_EFFECT ;
484492 if ((player -> type & PLAYER_HUMAN ) == PLAYER_HUMAN ) {
485493 func_800C90F4 (playerIndex , (player -> characterId * 0x10 ) + 0x29008008 );
486- var_v1 = 0 ;
494+ swerve_timer = 0 ;
487495 }
488496 }
489497 }
490498 }
491- temp_f16 *= var_a3 ;
492- if ((temp_f16 <= 0 ) && (var_a3 == 1 )) {
493- temp_f16 = 0 ;
499+ swerve_velo_current *= swerve_direction ;
500+ if ((swerve_velo_current <= 0 ) && (swerve_direction == 1 )) {
501+ swerve_velo_current = 0 ;
494502 }
495- if ((temp_f16 >= 0 ) && (var_a3 == -1 )) {
496- temp_f16 = 0 ;
503+ if ((swerve_velo_current >= 0 ) && (swerve_direction == -1 )) {
504+ swerve_velo_current = 0 ;
497505 }
498- player -> unk_078 += temp_f16 * 0x14 ;
499- player -> unk_0B8 = var_f0 ;
500- player -> unk_0B4 = var_v1 ;
501- player -> unk_0AC = var_a3 ;
506+ /* unk_078 contributes to rotational velocity (spin). It looks to be set each frame in steering code
507+ (e.g. func_80033AE0), so it does not accumulate values from swerve_velo_current over multiple frames */
508+ player -> unk_078 += swerve_velo_current * 20 ;
509+ player -> swerveAccelInit = swerve_accel_init ;
510+ player -> swerveTimer = swerve_timer ;
511+ player -> swerveDirection = swerve_direction ;
502512 if (player -> effects & MIDAIR_EFFECT ) {
503- func_8008C73C (player , playerIndex );
504- player -> kartProps &= ~DRIVING_SPINOUT ;
513+ add_spinout_effect (player , playerIndex );
514+ player -> kartProps &= ~DRIVING_NEAR_SPINOUT ;
505515 }
506516}
507517
508- void func_8008D3B0 (Player * player , UNUSED s8 playerIndex ) {
509- player -> kartProps &= ~DRIVING_SPINOUT ;
518+ void remove_driving_near_spinout_effect (Player * player , UNUSED s8 playerIndex ) {
519+ player -> kartProps &= ~DRIVING_NEAR_SPINOUT ;
510520}
511521
512522void trigger_shroom (Player * player , s8 playerIndex ) {
0 commit comments