11/* *
22 * @file d_a_e_sm2.cpp
3- *
3+ * ChuChu Slime Enemy
44*/
55
66#include " d/dolzel_rel.h" // IWYU pragma: keep
@@ -143,7 +143,8 @@ static void sm2_delete(e_sm2_class* i_this) {
143143 } else {
144144 i_this->action = ACTION_ROOF;
145145 i_this->mode = 0 ;
146- i_this->timers [0 ] = 30 .0f + cM_rndF (60 .0f );
146+ // Wait timer before appearing from ceiling (SCALE_TIME)
147+ i_this->timers [0 ] = (30 .0f + cM_rndF (60 .0f )) * SCALE_TIME;
147148 actor->current .pos = actor->home .pos ;
148149 i_this->color_alpha = 1 .0f ;
149150 i_this->field_0x6b0 = 1 .0f ;
@@ -236,9 +237,11 @@ static void normal_move(e_sm2_class* i_this) {
236237 if (i_this->timers [0 ] == 0 ) {
237238 if (i_this->field_0x6a8 == 0 ) {
238239 i_this->mCurrentAngleYTarget = cM_rndF (65536 .0f );
239- i_this->timers [0 ] = 23 .0f + cM_rndF (3 .0f );
240+ // Wait timer before moving on ceiling (SCALE_TIME)
241+ i_this->timers [0 ] = (23 .0f + cM_rndF (3 .0f )) * SCALE_TIME;
240242 } else {
241- i_this->timers [0 ] = 8 .0f + cM_rndF (3 .0f );
243+ // Wait timer for damaged state (SCALE_TIME)
244+ i_this->timers [0 ] = (8 .0f + cM_rndF (3 .0f )) * SCALE_TIME;
242245 }
243246
244247 i_this->mCurrentAngleYTargetStep = 0 ;
@@ -262,14 +265,16 @@ static void normal_move(e_sm2_class* i_this) {
262265 }
263266
264267 if (i_this->field_0x6a8 == 0 ) {
265- i_this->timers [0 ] = 23 .0f + cM_rndF (3 .0f );
268+ // Return to wait timer after moving (SCALE_TIME)
269+ i_this->timers [0 ] = (23 .0f + cM_rndF (3 .0f )) * SCALE_TIME;
266270 } else {
267271 s16 sp8 = actor->current .angle .y - i_this->mCurrentAngleYTarget ;
268272 if (sp8 < 0x1000 && sp8 > -0x1000 && i_this->dist_to_pl < (400 .0f + (100 .0f * i_this->size ))) {
269273 i_this->action = ACTION_ATTACK;
270274 i_this->mode = 0 ;
271275 } else {
272- i_this->timers [0 ] = 8 .0f + cM_rndF (3 .0f );
276+ // Return to wait timer for damaged state (SCALE_TIME)
277+ i_this->timers [0 ] = (8 .0f + cM_rndF (3 .0f )) * SCALE_TIME;
273278 }
274279 }
275280 }
@@ -329,7 +334,8 @@ static void attack(e_sm2_class* i_this) {
329334
330335 if (i_this->acch .ChkGroundHit ()) {
331336 i_this->mode = 2 ;
332- i_this->timers [0 ] = BREG_S (3 ) + 10 ;
337+ // Ground impact recovery timer after jump (SCALE_TIME)
338+ i_this->timers [0 ] = (BREG_S (3 ) + 10 ) * SCALE_TIME;
333339 i_this->field_0x82c = 5 .0f ;
334340 i_this->field_0x6aa = 23 ;
335341
@@ -348,7 +354,8 @@ static void attack(e_sm2_class* i_this) {
348354 if (actor->speedF < 1 .0f ) {
349355 i_this->action = ACTION_NORMAL_MOVE;
350356 i_this->mode = 0 ;
351- i_this->timers [0 ] = cM_rndF (20 .0f );
357+ // Wait timer before next movement (SCALE_TIME)
358+ i_this->timers [0 ] = cM_rndF (20 .0f ) * SCALE_TIME;
352359 }
353360 break ;
354361 case 10 :
@@ -389,7 +396,8 @@ static s8 combine(e_sm2_class* i_this) {
389396 if (combine_actor == NULL || combine_actor->action != ACTION_COMBINE) {
390397 i_this->action = ACTION_NORMAL_MOVE;
391398 i_this->mode = 0 ;
392- i_this->timers [0 ] = 20 .0f + cM_rndF (20 .0f );
399+ // Fallback timer when combine partner is lost (SCALE_TIME)
400+ i_this->timers [0 ] = (20 .0f + cM_rndF (20 .0f )) * SCALE_TIME;
393401 return cc_co_ON;
394402 }
395403
@@ -409,7 +417,8 @@ static s8 combine(e_sm2_class* i_this) {
409417 switch (i_this->mode ) {
410418 case 0 :
411419 if (i_this->timers [0 ] == 0 ) {
412- i_this->timers [0 ] = 8 .0f + cM_rndF (3 .0f );
420+ // Wait timer during combine mode (SCALE_TIME)
421+ i_this->timers [0 ] = (8 .0f + cM_rndF (3 .0f )) * SCALE_TIME;
413422 i_this->mode = 1 ;
414423 }
415424 break ;
@@ -419,7 +428,8 @@ static s8 combine(e_sm2_class* i_this) {
419428
420429 if (i_this->timers [0 ] == 0 ) {
421430 i_this->mode = 0 ;
422- i_this->timers [0 ] = 8 .0f + cM_rndF (3 .0f );
431+ // Return to wait in combine mode (SCALE_TIME)
432+ i_this->timers [0 ] = (8 .0f + cM_rndF (3 .0f )) * SCALE_TIME;
423433 }
424434 break ;
425435 case 5 :
@@ -497,17 +507,22 @@ static s8 roof(e_sm2_class* i_this) {
497507 if (i_this->field_0x5b8 != 0 ) {
498508 if (dComIfGs_isSwitch (i_this->field_0x5b8 , fopAcM_GetRoomNo (actor))) {
499509 i_this->mode = 2 ;
500- i_this->timers [0 ] = 2 .0f + cM_rndF (50 .0f );
501- i_this->timers [1 ] = i_this->timers [0 ] + 50 ;
510+ // Delay before emerging from ground via switch (SCALE_TIME)
511+ i_this->timers [0 ] = (2 .0f + cM_rndF (50 .0f )) * SCALE_TIME;
512+ // Extended timer for full emergence sequence (SCALE_TIME)
513+ i_this->timers [1 ] = i_this->timers [0 ] + 50 * SCALE_TIME;
502514 }
503515 } else if (fopAcM_searchPlayerDistanceXZ (actor) < (100 .0f * i_this->field_0x5b6 )) {
504516 i_this->mode = 2 ;
505517 if (strcmp (dComIfGp_getStartStageName (), " D_SB07" ) == 0 ) {
506- i_this->timers [0 ] = 2 .0f + cM_rndF (50 .0f );
518+ // Delay before emerging from ground near player (SCALE_TIME)
519+ i_this->timers [0 ] = (2 .0f + cM_rndF (50 .0f )) * SCALE_TIME;
507520 } else {
508- i_this->timers [0 ] = 2 ;
521+ // Quick emergence in other stages (SCALE_TIME)
522+ i_this->timers [0 ] = 2 * SCALE_TIME;
509523 }
510- i_this->timers [1 ] = i_this->timers [0 ] + 50 ;
524+ // Extended timer for full emergence sequence (SCALE_TIME)
525+ i_this->timers [1 ] = i_this->timers [0 ] + 50 * SCALE_TIME;
511526 }
512527 break ;
513528 case 2 :
@@ -530,7 +545,8 @@ static s8 roof(e_sm2_class* i_this) {
530545
531546 if (i_this->field_0x830 > 0 .9f * (1 .3f + KREG_F (17 ))) {
532547 i_this->mode = 3 ;
533- i_this->timers [0 ] = 5 ;
548+ // Brief pause after emerging fully from ground (SCALE_TIME)
549+ i_this->timers [0 ] = 5 * SCALE_TIME;
534550 }
535551 }
536552 break ;
@@ -542,7 +558,8 @@ static s8 roof(e_sm2_class* i_this) {
542558 if (i_this->acch .ChkGroundHit ()) {
543559 i_this->action = ACTION_NORMAL_MOVE;
544560 i_this->mode = 0 ;
545- i_this->timers [0 ] = 40 .0f + cM_rndF (30 .0f );
561+ // Wait timer after landing from ground emergence (SCALE_TIME)
562+ i_this->timers [0 ] = (40 .0f + cM_rndF (30 .0f )) * SCALE_TIME;
546563 i_this->field_0x6a8 = 0 ;
547564 i_this->field_0x830 = 1 .0f ;
548565 i_this->field_0x6aa = 20 ;
@@ -645,7 +662,8 @@ static void fail(e_sm2_class* i_this) {
645662 if (i_this->acch .ChkGroundHit ()) {
646663 if (i_this->mode == 0 ) {
647664 i_this->mode = 1 ;
648- i_this->timers [1 ] = 25 ;
665+ // Death animation duration timer (SCALE_TIME)
666+ i_this->timers [1 ] = 25 * SCALE_TIME;
649667 }
650668
651669 cLib_addCalc2 (&i_this->field_0x6b0 , 0 .5f + BREG_F (9 ), 0 .05f , 0 .05f + VREG_F (7 ));
@@ -664,7 +682,8 @@ static void fail(e_sm2_class* i_this) {
664682 if (i_this->mode == 1 ) {
665683 if (actor->eventInfo .checkCommandCatch ()) {
666684 i_this->mode = 2 ;
667- i_this->timers [0 ] = KREG_S (7 ) + 9 ;
685+ // Bottle catch sequence timer (SCALE_TIME)
686+ i_this->timers [0 ] = (KREG_S (7 ) + 9 ) * SCALE_TIME;
668687 } else {
669688 static u8 item_no[] = {
670689 fpcNm_ITEM_CHUCHU_GREEN,
@@ -861,7 +880,8 @@ static void damage_check(e_sm2_class* i_this) {
861880 i_this->type = new_color_type;
862881 sm_hit_actor->type = new_color_type;
863882
864- sm_hit_actor->timers [0 ] = 100 ;
883+ // Invulnerability timer for other ChuChu after combining (SCALE_TIME)
884+ sm_hit_actor->timers [0 ] = 100 * SCALE_TIME;
865885 sm_hit_actor->combine_actor_pid = fopAcM_GetID (actor);
866886 return ;
867887 }
@@ -1053,12 +1073,14 @@ static void action(e_sm2_class* i_this) {
10531073 MtxPosition (&work, &offset);
10541074 actor->speed .x = offset.x ;
10551075 actor->speed .z = offset.z ;
1056- actor->speed .y += actor->gravity ;
1076+ // Frame-based accumulator: Gravity velocity increments each frame
1077+ actor->speed .y += actor->gravity * DELTA_TIME;
10571078 if (actor->speed .y < -100 .0f ) {
10581079 actor->speed .y = -100 .0f ;
10591080 }
10601081
1061- actor->current .pos += actor->speed ;
1082+ // Frame-based accumulator: Position increments each frame based on velocity
1083+ actor->current .pos += actor->speed * DELTA_TIME;
10621084
10631085 cXyz* cc_move_p = i_this->ccStts .GetCCMoveP ();
10641086 if (cc_move_p != NULL ) {
@@ -1276,7 +1298,8 @@ static void action(e_sm2_class* i_this) {
12761298 static f32 asp[] = {500 .0f , 400 .0f , 300 .0f , 200 .0f , 100 .0f };
12771299 static f32 asp2[] = {3500 .0f , 3000 .0f , 2500 .0f , 2000 .0f , 1500 .0f };
12781300
1279- i_this->field_0x828 += (s16)(asp2[i_this->sizetype ] + (i_this->field_0x82c * asp[i_this->sizetype ]));
1301+ // Frame-based accumulator: Wobble rotation angle increments each frame
1302+ i_this->field_0x828 += (s16)((asp2[i_this->sizetype ] + (i_this->field_0x82c * asp[i_this->sizetype ])) * DELTA_TIME);
12801303
12811304 for (int i = 0 ; i < 8 ; i++) {
12821305 if (i_this->action != ACTION_FAIL) {
@@ -1612,7 +1635,8 @@ static int daE_SM2_Create(fopAc_ac_c* i_this) {
16121635 a_this->is_roof = TRUE ;
16131636 } else {
16141637 a_this->action = ACTION_NORMAL_MOVE;
1615- a_this->timers [0 ] = cM_rndF (20 .0f );
1638+ // Initial wait timer after spawning (SCALE_TIME)
1639+ a_this->timers [0 ] = cM_rndF (20 .0f ) * SCALE_TIME;
16161640 a_this->combine_off_timer = 100 .0f + cM_rndF (100 .0f );
16171641 }
16181642
0 commit comments