Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
lakilester.c
Go to the documentation of this file.
1#include "common.h"
2#include "../partners.h"
3#include "effects.h"
4#include "sprite/npc/WorldLakilester.h"
5#include "sprite/player.h"
6
7#define NAMESPACE world_lakilester
8
20BSS s32 N(D_802BFF2C); // unused (padding?)
21
22enum {
29 RIDE_STATE_START_RIDING = 104, // cannot dismount until this state is done
36};
37
38// states for putting lakilester away, paralleling ride states
39enum {
46};
47
48enum {
52};
53
55
59 f32 speed;
60
62 speed = playerStatus->curSpeed;
64 speed *= 0.5f;
65 }
66
67 add_vec2D_polar(&lakilester->pos.x, &lakilester->pos.z, speed, playerStatus->heading);
68 lakilester->yaw = playerStatus->targetYaw;
69 }
70
71 playerStatus->pos.x = lakilester->pos.x;
72 playerStatus->pos.y = lakilester->pos.y + 10.0f + abs(N(PlayerBounceOffset)) * 0.34f;
73 playerStatus->pos.z = lakilester->pos.z;
75}
76
77void N(init)(Npc* lakilester) {
78 lakilester->collisionHeight = 38;
79 lakilester->collisionDiameter = 36;
80 lakilester->collisionChannel = COLLIDER_FLAG_IGNORE_PLAYER;
81 N(PlayerBounceOffset) = 0;
82 N(LockingPlayerInput) = false;
83 N(PlayerCollisionDisabled) = false;
85 N(UpdatePushingWall) = true;
86 N(MoveSoundsTime) = 0;
88 N(MountingDeltaY) = 0;
89 N(CurrentGroundPitch) = 0;
90 lakilester->moveToPos.x = lakilester->pos.x;
91 lakilester->moveToPos.y = lakilester->pos.y;
92 lakilester->moveToPos.z = lakilester->pos.z;
93}
94
95API_CALLABLE(N(TakeOut)) {
96 Npc* lakilester = script->owner2.npc;
97
98 if (isInitialCall) {
100 }
101
103 return ApiStatus_DONE1;
104 } else {
105 return ApiStatus_BLOCK;
106 }
107}
108
114
117
118API_CALLABLE(N(Update)) {
120 Npc* lakilester = script->owner2.npc;
122 Entity* entity;
123
124 if (isInitialCall) {
127 TweesterTouchingPartner = nullptr;
128 }
129
130 playerData->partnerUsedTime[PARTNER_LAKILESTER]++;
133
134 if (entity == nullptr) {
137 return ApiStatus_BLOCK;
138 }
139
140 switch (N(TweesterPhysicsPtr)->state) {
142 N(TweesterPhysicsPtr)->state++;
143 N(TweesterPhysicsPtr)->prevFlags = lakilester->flags;
144 N(TweesterPhysicsPtr)->radius = fabsf(dist2D(lakilester->pos.x, lakilester->pos.z, entity->pos.x, entity->pos.z));
145 N(TweesterPhysicsPtr)->angle = atan2(entity->pos.x, entity->pos.z, lakilester->pos.x, lakilester->pos.z);
146 N(TweesterPhysicsPtr)->angularVel = 6.0f;
147 N(TweesterPhysicsPtr)->liftoffVelPhase = 50.0f;
148 N(TweesterPhysicsPtr)->countdown = 120;
153 lakilester->pos.x = entity->pos.x + (sinAngle * N(TweesterPhysicsPtr)->radius);
154 lakilester->pos.z = entity->pos.z - (cosAngle * N(TweesterPhysicsPtr)->radius);
155 N(TweesterPhysicsPtr)->angle = clamp_angle(N(TweesterPhysicsPtr)->angle - N(TweesterPhysicsPtr)->angularVel);
156
157 if (N(TweesterPhysicsPtr)->radius > 20.0f) {
158 N(TweesterPhysicsPtr)->radius--;
159 } else if (N(TweesterPhysicsPtr)->radius < 19.0f) {
160 N(TweesterPhysicsPtr)->radius++;
161 }
162
163 liftoffVelocity = sin_rad(DEG_TO_RAD(N(TweesterPhysicsPtr)->liftoffVelPhase)) * 3.0f;
164 N(TweesterPhysicsPtr)->liftoffVelPhase += 3.0f;
165
166 if (N(TweesterPhysicsPtr)->liftoffVelPhase > 150.0f) {
167 N(TweesterPhysicsPtr)->liftoffVelPhase = 150.0f;
168 }
169
170 lakilester->pos.y += liftoffVelocity;
171 lakilester->renderYaw = clamp_angle(360.0f - N(TweesterPhysicsPtr)->angle);
172 N(TweesterPhysicsPtr)->angularVel += 0.8;
173
174 if (N(TweesterPhysicsPtr)->angularVel > 40.0f) {
175 N(TweesterPhysicsPtr)->angularVel = 40.0f;
176 }
177
178 if (--N(TweesterPhysicsPtr)->countdown == 0) {
179 N(TweesterPhysicsPtr)->state++;
180 }
181 break;
183 lakilester->flags = N(TweesterPhysicsPtr)->prevFlags;
184 N(TweesterPhysicsPtr)->countdown = 30;
185 N(TweesterPhysicsPtr)->state++;
186 break;
190
191 if (--N(TweesterPhysicsPtr)->countdown == 0) {
193 TweesterTouchingPartner = nullptr;
194 }
195 break;
196 }
197 return ApiStatus_BLOCK;
198}
199
205
214
217 f32 stickX = partnerStatus->stickX;
218 f32 stickY = partnerStatus->stickY;
219 f32 moveAngle = clamp_angle(atan2(0.0f, 0.0f, stickX, -stickY) + gCameras[CAM_DEFAULT].curYaw);
220 f32 moveSpeed = 0.0f;
221
222 if (dist2D(0.0f, 0.0f, stickX, -stickY) >= 1.0) {
223 moveSpeed = 3.0f;
224 if (SQ(stickX) + SQ(stickY) > SQ(55)) {
225 moveSpeed = 6.0f;
226 }
227 }
228
229 *outAngle = moveAngle;
230 *outSpeed = moveSpeed;
231}
232
237 f32 hitRx, hitRz;
240 s32 temp;
241 HitID hitID;
243 s32 entityType;
244
245 if (playerStatus->animFlags & PA_FLAG_DISMOUNTING_ALLOWED) {
247 return true;
248 }
249
250 canDismount = false;
251 outLength = 16.0f;
252 outY = lakilester->moveToPos.y + 7.0f;
253 outX = playerStatus->pos.x;
254 outZ = playerStatus->pos.z;
256 add_vec2D_polar(&outX, &outZ, 2.0f, currentCamera->curYaw);
258 &hitDirX, &hitDirZ);
259 temp = hitID;
260
261 //TODO find better match
264 (entityType = get_entity_type(temp),
265 !(entityType == ENTITY_TYPE_SIMPLE_SPRING || entityType == ENTITY_TYPE_SCRIPT_SPRING))
266 ) {
267 temp = get_collider_flags(temp) & COLLIDER_FLAGS_SURFACE_TYPE_MASK; //TODO 'temp' is now 'surfaceType'
269 if (temp != SURFACE_TYPE_SLIDE) {
270 lakilester->moveToPos.x = outX;
271 lakilester->moveToPos.y = outY;
272 lakilester->moveToPos.z = outZ;
273 canDismount = true;
274 }
275 }
276 }
277 }
278 return canDismount;
279}
280
281#if !VERSION_JP
284 f32 y = gPlayerStatus.pos.y + height;
286 f32 depth = dist;
287 f32 hitRx, hitRz;
289 f32 deltaY;
290
291 N(MountingDeltaY) = 0;
292
293 if (player_raycast_below_cam_relative(&gPlayerStatus, &x, &y, &z, &depth,
295 {
296 deltaY = y - lakilester->moveToPos.y;
297 if (deltaY != 0.0f) {
298 if (fabs(deltaY) < 10.0) {
300 lakilester->moveToPos.y = y;
301 return true;
302 } else {
303 return false;
304 }
305 }
306 return true;
307 }
308 return false;
309}
310#endif
311
313 f32 radius = lakilester->collisionDiameter * 0.8f;
314 f32 x, y, z, yaw;
315
316 // combine testing boilerplate
317 #define TEST_MOVE_AT_ANGLE(testFunc, angle) \
318 ( \
319 yaw = clamp_angle(angle), \
320 x = lakilester->pos.x, \
321 y = lakilester->moveToPos.y, \
322 z = lakilester->pos.z, \
323 testFunc(lakilester->collisionChannel, &x, &y, &z, 0.0f, yaw, lakilester->collisionHeight, radius) \
324 )
325
329 lakilester->pos.x = x;
330 lakilester->pos.z = z;
331 } else {
333 }
334
336 lakilester->pos.x = x;
337 lakilester->pos.z = z;
339 } else {
341 }
342
344 lakilester->pos.x = x;
345 lakilester->pos.z = z;
347 } else {
349 }
350
353 lakilester->pos.x = x;
354 lakilester->pos.z = z;
355 } else {
357 }
358
361 lakilester->pos.x = x;
362 lakilester->pos.z = z;
363 } else {
365 }
366}
367
373 f32 moveAngle, moveSpeed;
374 f32 x, y, z;
378 s32 pitchShift;
379 f32 height;
380
381 moveAngle = 0.0f;
382 moveSpeed = 0.0f;
383 N(get_movement_from_input)(&moveAngle, &moveSpeed);
384
387 moveSpeed *= 0.5f;
388 }
389
390 if (N(CurrentGroundPitch) >= 20.0f) {
391 moveSpeed *= 0.8f;
392 }
393
394 lakilester->moveSpeed = moveSpeed;
395
396 if (moveSpeed != 0.0f) {
397 N(MoveSoundsTime)++;
399 if (N(MoveSoundsTime) % 8 == 0) {
400 if (N(MovePitchAdjustment) >= 120) {
401 N(MovePitchAdjustment) = 0;
402 }
403
404 if (N(MovePitchAdjustment) < 60) {
405 pitchShift = update_lerp(EASING_LINEAR, 0.0f, 100.0f, N(MovePitchAdjustment), 60);
406 sfx_play_sound_with_params(SOUND_FLIGHT, 0, 64, pitchShift);
407 } else {
408 pitchShift = update_lerp(EASING_LINEAR, 100.0f, 0.0f, N(MovePitchAdjustment) - 60, 60);
409 sfx_play_sound_with_params(SOUND_FLIGHT, 0, 64, pitchShift);
410 }
411 }
412 }
413
414 x = lakilester->pos.x;
415 y = lakilester->moveToPos.y;
416 z = lakilester->pos.z;
417
418 if (npc_test_move_taller_with_slipping(lakilester->collisionChannel, &x, &y, &z,
419 lakilester->collisionDiameter, lakilester->yaw, lakilester->collisionHeight, lakilester->collisionDiameter))
420 {
421 collisionStatus->curInspect = (partnerStatus->pressedButtons & BUTTON_A) ? NpcHitQueryColliderID : NO_COLLIDER;
422 }
423
424 if (moveSpeed != 0.0f) {
425 lakilester->yaw = moveAngle;
426 x = lakilester->pos.x;
427 y = lakilester->moveToPos.y;
428 z = lakilester->pos.z;
429 if (npc_test_move_complex_with_slipping(lakilester->collisionChannel, &x, &y, &z,
430 lakilester->moveSpeed, lakilester->yaw, lakilester->collisionHeight, lakilester->collisionDiameter))
431 {
432 if (N(UpdatePushingWall)) {
433 collisionStatus->pushingAgainstWall = NpcHitQueryColliderID;
434 }
435 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
436 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
437 } else {
438 npc_move_heading(lakilester, lakilester->moveSpeed, moveAngle);
439 if (N(UpdatePushingWall)) {
440 collisionStatus->pushingAgainstWall = NO_COLLIDER;
441 }
442 }
443
444 moveAngle = clamp_angle(lakilester->yaw - 30.0f);
445 x = lakilester->pos.x;
446 y = lakilester->moveToPos.y;
447 z = lakilester->pos.z;
448 if (npc_test_move_taller_with_slipping(lakilester->collisionChannel, &x, &y, &z,
449 lakilester->moveSpeed, moveAngle, lakilester->collisionHeight, lakilester->collisionDiameter))
450 {
451 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
452 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
453 }
454
455 moveAngle = clamp_angle(lakilester->yaw + 30.0f);
456 x = lakilester->pos.x;
457 y = lakilester->moveToPos.y;
458 z = lakilester->pos.z;
459 if (npc_test_move_taller_with_slipping(lakilester->collisionChannel, &x, &y, &z,
460 lakilester->moveSpeed, moveAngle, lakilester->collisionHeight, lakilester->collisionDiameter))
461 {
462 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
463 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
464 }
465
467
468 } else {
469 moveAngle = 90.0f;
470 x = lakilester->pos.x;
471 y = lakilester->moveToPos.y;
472 z = lakilester->pos.z;
473 if (npc_test_move_taller_with_slipping(lakilester->collisionChannel, &x, &y, &z,
474 4.0f, moveAngle, lakilester->collisionHeight, lakilester->collisionDiameter))
475 {
476 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
477 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
478 }
479
480 moveAngle = 270.0f;
481 x = lakilester->pos.x;
482 y = lakilester->moveToPos.y;
483 z = lakilester->pos.z;
484 if (npc_test_move_taller_with_slipping(lakilester->collisionChannel, &x, &y, &z,
485 4.0f, moveAngle, lakilester->collisionHeight, lakilester->collisionDiameter))
486 {
487 lakilester->pos.x += (x - lakilester->pos.x) / 5.0f;
488 lakilester->pos.z += (z - lakilester->pos.z) / 5.0f;
489 }
490 }
491
493 lakilester->moveToPos.y -= lakilester->jumpScale;
494 hitDepth = lakilester->collisionHeight + 2;
495 y = lakilester->moveToPos.y + 12.0f;
496 x = playerStatus->pos.x;
497 z = playerStatus->pos.z;
498 add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw);
500 &sp44, &sp48, &sp4C);
502 height = 12.0f;
503
504 if (N(CurrentGroundPitch) != 0.0f) {
505 height = 32.0f;
506 }
507
508 if (N(CurrentGroundPitch) > 0.0f && raycastBelowResult >= 0) {
510 lakilester->pos.y = (lakilester->pos.y + fabs((sinAngle / cosAngle) * playerStatus->runSpeed));
511 }
512
514 playerStatus->lastGoodPos.x = lakilester->pos.x;
515 playerStatus->lastGoodPos.y = lakilester->pos.y;
516 playerStatus->lastGoodPos.z = lakilester->pos.z;
518
519 lakilester->curFloor = raycastBelowResult;
520 lakilester->moveToPos.y = y;
521 lakilester->moveToPos.x = x;
522 lakilester->moveToPos.z = z;
523 lakilester->jumpScale = 0.0f;
524 playerStatus->timeInAir = 0;
525
529 lakilester->moveSpeed = moveSpeed * 0.5f;
530 } else {
532 lakilester->moveSpeed = moveSpeed;
533 }
534 return;
535 }
536
537 collisionStatus->curFloor = NO_COLLIDER;
538 playerStatus->timeInAir++;
539 lakilester->curFloor = NO_COLLIDER;
540 lakilester->jumpScale += 1.8;
541
542 if (lakilester->jumpScale > 12.0f) {
543 lakilester->jumpScale = 12.0f;
544 }
545}
546
547#if VERSION_JP
550 f32 y = gPlayerStatus.pos.y + height;
552 f32 depth = dist;
553 f32 hitRx, hitRz;
555 f32 deltaY;
556
557 N(MountingDeltaY) = 0;
558
559 if (npc_raycast_down_around(0, &x, &y, &z, &depth,
560 lakilester->yaw, lakilester->collisionDiameter))
561 {
562 deltaY = y - lakilester->moveToPos.y;
563 if (deltaY != 0.0f) {
564 if (fabs(deltaY) < 10.0) {
566 lakilester->moveToPos.y = y;
567 return true;
568 } else {
569 return false;
570 }
571 }
572 return true;
573 }
574 return false;
575}
576#endif
577
579 f32 colliderHeight = gPlayerStatus.colliderHeight;
581 f32 hitRx, hitRz;
582 f32 posX, posZ;
583
584 *posY = gPlayerStatus.pos.y + colliderHeight;
585 posX = gPlayerStatus.pos.x;
586 posZ = gPlayerStatus.pos.z;
587
588 return player_raycast_below_cam_relative(&gPlayerStatus, &posX, posY, &posZ,
589 &colliderHeight, &hitRx, &hitRz, &hitDirX, &hitDirZ);
590}
591
592API_CALLABLE(N(UseAbility)) {
596 Npc* lakilester = script->owner2.npc;
597 f32 x, y, z, dist;
598 f32 yaw, camYaw;
599 s32 i;
600
602
603 if (isInitialCall) {
605 if (!(playerStatus->animFlags & PA_FLAG_CHANGING_MAP)) {
607 lakilester->moveToPos.x = lakilester->pos.x;
608 lakilester->moveToPos.y = lakilester->pos.y;
609 lakilester->moveToPos.z = lakilester->pos.z;
610
613 ) {
616 }
618 } else {
620 }
621
622 if (!partnerStatus->shouldResumeAbility) {
624 if (playerStatus->actionState == ACTION_STATE_RIDE
625 || playerStatus->actionState == ACTION_STATE_IDLE
626 || playerStatus->actionState == ACTION_STATE_WALK
627 || playerStatus->actionState == ACTION_STATE_RUN
628 || playerStatus->actionState == ACTION_STATE_FALLING
629 ) {
631 } else {
632 return ApiStatus_DONE2;
633 }
634 }
635 } else {
636 partnerStatus->shouldResumeAbility = false;
643 N(MountState) = MOUNT_STATE_IN_PROGRESS; // unexpected
646 partnerStatus->actingPartner = PARTNER_LAKILESTER;
647 partnerStatus->partnerActionState = PARTNER_ACTION_LAKILESTER_1;
649 lakilester->pos.x = playerStatus->pos.x;
650 lakilester->pos.y = lakilester->moveToPos.y;
651 lakilester->pos.z = playerStatus->pos.z;
653 playerStatus->pos.y = lakilester->pos.y + 10.0f;
654 lakilester->moveSpeed = 3.0f;
655 lakilester->jumpScale = 0.0f;
656 lakilester->yaw = playerStatus->targetYaw;
660 N(PlayerCollisionDisabled) = true;
661
662 if (!N(LockingPlayerInput)) {
664 N(LockingPlayerInput) = true;
665 }
666
667 N(PlayerBounceOffset) = 0;
670 }
671 } else {
672 return ApiStatus_DONE2;
673 }
674 }
675
676 switch (N(AbilityState)) {
677 case RIDE_STATE_BEGIN:
678#if VERSION_JP
679 if (playerStatus->inputDisabledCount != 0) {
680#else
681 if (playerStatus->flags & PS_FLAG_HIT_FIRE || playerStatus->inputDisabledCount != 0) {
682#endif
684 return ApiStatus_DONE2;
685 }
686 script->functionTemp[1] = 3;
687 script->functionTemp[2] = disable_player_input();
688 N(LockingPlayerInput) = true;
689 N(AbilityState)++; // RIDE_STATE_DELAY
690 break;
691 case RIDE_STATE_DELAY:
692#if !VERSION_JP
693 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
695 if (N(LockingPlayerInput)) {
697 N(LockingPlayerInput) = false;
698 }
699 return ApiStatus_DONE2;
700 }
701#endif
702
703 if (playerStatus->animFlags & PA_FLAG_CHANGING_MAP) {
704 if (script->functionTemp[2] < playerStatus->inputDisabledCount) {
706 N(LockingPlayerInput) = false;
707 }
709 return ApiStatus_DONE2;
710 }
711
712 if (script->functionTemp[1] == 0) {
713 if (script->functionTemp[2] < playerStatus->inputDisabledCount) {
715 N(LockingPlayerInput) = false;
717 return ApiStatus_DONE2;
718 }
720 break;
721 }
722 script->functionTemp[1]--;
723 break;
724 }
725
726 switch (N(AbilityState)) {
729 N(PlayerCollisionDisabled) = true;
730
731 if (!N(LockingPlayerInput)) {
733 N(LockingPlayerInput) = true;
734 }
735
741 lakilester->moveToPos.x = playerStatus->pos.x;
742 lakilester->moveToPos.y = playerStatus->pos.y;
743 lakilester->moveToPos.z = playerStatus->pos.z;
744 yaw = 0.0f;
745
746 for (i = 0; i < 4; i++) {
747 x = lakilester->moveToPos.x;
748 y = lakilester->moveToPos.y;
749 z = lakilester->moveToPos.z;
751 yaw, lakilester->collisionHeight, lakilester->collisionDiameter);
752 lakilester->moveToPos.x = x;
753 lakilester->moveToPos.y = y;
754 lakilester->moveToPos.z = z;
755 yaw += 90.0f;
756 }
757
758 lakilester->yaw = atan2(lakilester->pos.x, lakilester->pos.z, lakilester->moveToPos.x, lakilester->moveToPos.z);
759 lakilester->duration = 12;
761 lakilester->jumpVel = 8.0f;
762 lakilester->jumpScale = 1.4f;
765 break;
769 // fallthrough
771 N(AbilityState)++;
772 // fallthrough
774#if !VERSION_JP
775 if (!(playerStatus->flags & PS_FLAG_HIT_FIRE)) {
776#endif
777 lakilester->pos.x += (lakilester->moveToPos.x - lakilester->pos.x) / lakilester->duration;
778 lakilester->pos.z += (lakilester->moveToPos.z - lakilester->pos.z) / lakilester->duration;
779 lakilester->pos.y += (lakilester->moveToPos.y - lakilester->pos.y) / lakilester->duration;
780 playerStatus->pos.y += lakilester->jumpVel;
781 N(test_mounting_height_adjustment)(lakilester, playerStatus->colliderHeight, 2 * playerStatus->colliderHeight);
782 playerStatus->pos.y += N(MountingDeltaY);
783 lakilester->pos.y += N(MountingDeltaY);
784 lakilester->jumpVel -= lakilester->jumpScale;
785
786 if (lakilester->jumpVel <= 0.0f) {
788 }
789
790 lakilester->duration--;
791
792 if (lakilester->duration > 0) {
793 if (lakilester->duration == 1) {
794 add_vec2D_polar(&lakilester->pos.x, &lakilester->pos.z, -2.0f,
796 }
797 } else {
798 playerStatus->pos.y = lakilester->pos.y + 10.0f;
799 lakilester->moveSpeed = playerStatus->runSpeed;
800 lakilester->jumpScale = 0.0f;
801 lakilester->yaw = playerStatus->targetYaw;
802 lakilester->duration = 3;
806 partnerStatus->actingPartner = PARTNER_LAKILESTER;
807 partnerStatus->partnerActionState = PARTNER_ACTION_LAKILESTER_1;
810 N(PlayerBounceOffset) = 0;
815 }
816#if !VERSION_JP
817 } else {
819 }
820#endif
821 break;
823#if !VERSION_JP
824 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
826 break;
827 }
828#endif
829 lakilester->duration--;
830 if (lakilester->duration != 0) {
831#if VERSION_JP
832 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
834 break;
835 }
836#endif
837 if (partnerStatus->pressedButtons & (BUTTON_B | D_CBUTTONS)) {
838 if (N(can_dismount)()) {
840 }
841 }
842 break;
843 } else {
846 }
847 // fallthrough
851 lakilester->pos.y = lakilester->moveToPos.y + 2.0f;
852
854 if (N(PlayerBounceOffset) >= 10) {
855 N(PlayerBounceOffset) -= 18;
856 }
857
858 if (partnerStatus->inputDisabledCount == 0) {
859 playerStatus->targetYaw = lakilester->yaw;
860 }
861 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
863 break;
864 }
865 if (partnerStatus->pressedButtons & (BUTTON_B | D_CBUTTONS)) {
866 if (N(can_dismount)()) {
868 } else {
871 }
873 }
874 }
875 break;
879 N(can_dismount)();
880 camYaw = camera->curYaw;
881 if (playerStatus->spriteFacingAngle >= 90.0f && playerStatus->spriteFacingAngle < 270.0f) {
882 yaw = (180.0f + camYaw) - 90.0f;
883 } else {
884 yaw = (0.0f + camYaw) - 90.0f;
885 }
886 lakilester->yaw = yaw;
887 dist = dist2D(playerStatus->pos.x, playerStatus->pos.z,
888 lakilester->moveToPos.x, lakilester->moveToPos.z);
889 lakilester->yaw = atan2(playerStatus->pos.x, playerStatus->pos.z,
890 lakilester->moveToPos.x, lakilester->moveToPos.z);
891 lakilester->duration = 14;
892 lakilester->jumpScale = 1.2f;
893
894 if (lakilester->moveToPos.y > lakilester->pos.y) {
895 lakilester->jumpVel = 6.0f + (lakilester->moveToPos.y - lakilester->pos.y) / 14.0f;
896 } else {
897 lakilester->jumpVel = 6.0f;
898 }
899
900 lakilester->moveSpeed = dist / lakilester->duration;
902 N(AbilityState)++;
903 break;
906 N(AbilityState)++;
907 // fallthrough
910 playerStatus->pos.y += lakilester->jumpVel;
911 dist = playerStatus->colliderHeight * 0.5f;
912
913 x = playerStatus->pos.x;
914 y = playerStatus->pos.y + (playerStatus->colliderHeight * 0.5f);
915 z = playerStatus->pos.z;
916
917 yaw = playerStatus->spriteFacingAngle - 90.0f + gCameras[gCurrentCameraID].curYaw;
918
919 if (player_raycast_up_corners(playerStatus, &x, &y, &z, &dist, yaw) > NO_COLLIDER) {
921 break;
922 }
923
924 lakilester->jumpVel -= lakilester->jumpScale;
925 add_vec2D_polar(&playerStatus->pos.x, &playerStatus->pos.z, lakilester->moveSpeed, lakilester->yaw);
926
928 if (N(test_dismount_height)(&y) > NO_COLLIDER) {
930 playerStatus->pos.y = y;
931 }
932 break;
933 }
934
936 gCameras[CAM_DEFAULT].targetPos.y = lakilester->moveToPos.y;
938
942
944 N(PlayerCollisionDisabled) = false;
946 }
947
950
951 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
952 partnerStatus->actingPartner = PARTNER_NONE;
953 partnerStatus->partnerActionState = PARTNER_ACTION_NONE;
954
955 if (N(LockingPlayerInput)) {
956 N(LockingPlayerInput) = false;
958 }
959
963 return ApiStatus_DONE1;
964 }
965
969 return ApiStatus_BLOCK;
970 }
971
974 partnerStatus->actingPartner = PARTNER_NONE;
975 partnerStatus->partnerActionState = PARTNER_ACTION_NONE;
977 if (N(LockingPlayerInput)) {
978 N(LockingPlayerInput) = false;
980 }
981
984 func_800EF3D4(2);
985 return ApiStatus_DONE1;
986 }
987
988 return ApiStatus_BLOCK;
989}
990
996
997API_CALLABLE(N(PutAway)) {
1001 Npc* lakilester = script->owner2.npc;
1002 f32 sp20, sp24, sp28, sp2C;
1003 f32 yaw;
1004
1005 if (isInitialCall) {
1008 N(can_dismount)();
1011 }
1012
1013 switch (N(PutAwayState)) {
1015 N(can_dismount)();
1016 yaw = cam->curYaw;
1017 if ((playerStatus->spriteFacingAngle >= 90.0f) && (playerStatus->spriteFacingAngle < 270.0f)) {
1018 lakilester->yaw = (yaw + 180.0f) - 90.0f;
1019 } else {
1020 lakilester->yaw = (yaw + 0.0f) - 90.0f;
1021 }
1022
1023 sp2C = dist2D(playerStatus->pos.x, playerStatus->pos.z,
1024 lakilester->moveToPos.x, lakilester->moveToPos.z);
1025 lakilester->duration = 14;
1026
1027 if (lakilester->moveToPos.y > lakilester->pos.y ) {
1028 lakilester->jumpVel = (lakilester->moveToPos.y - lakilester->pos.y) / 14.0f + 6.0f;
1029 } else {
1030 lakilester->jumpVel = 6.0f;
1031 }
1032 lakilester->jumpScale = 1.2f;
1033 lakilester->moveSpeed = sp2C / lakilester->duration;
1034 lakilester->yaw = atan2(playerStatus->pos.x, playerStatus->pos.z,
1035 lakilester->moveToPos.x, lakilester->moveToPos.z);
1037 N(PutAwayState)++;
1038 break;
1041 N(PutAwayState)++;
1043 playerStatus->pos.y += lakilester->jumpVel;
1044 lakilester->jumpVel -= lakilester->jumpScale;
1045 add_vec2D_polar(&playerStatus->pos.x, &playerStatus->pos.z,
1046 lakilester->moveSpeed, lakilester->yaw);
1048 if (lakilester->jumpVel <= 0.0f) {
1049 playerStatus->flags |= PS_FLAG_FALLING;
1050 if (lakilester->jumpVel < -10.0) {
1051 lakilester->jumpVel = -10.0f;
1052 }
1053 }
1054 sp20 = playerStatus->pos.x;
1055 sp24 = playerStatus->pos.y + playerStatus->colliderHeight;
1056 sp28 = playerStatus->pos.z;
1057 sp2C = playerStatus->colliderHeight;
1059 lakilester->yaw, lakilester->collisionDiameter)) {
1060
1062 playerStatus->pos.y = sp24;
1063 }
1064 break;
1065 }
1066
1070
1071 switch (N(PutAwayState)) {
1072 case PUT_AWAY_FINISH_1:
1074
1075 if (N(PlayerCollisionDisabled)) {
1076 N(PlayerCollisionDisabled) = false;
1078 }
1079
1081
1082 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
1083 partnerStatus->actingPartner = PARTNER_NONE;
1084 partnerStatus->partnerActionState = PARTNER_ACTION_NONE;
1085 if (N(LockingPlayerInput)) {
1086 N(LockingPlayerInput) = false;
1088 }
1089
1094 return ApiStatus_DONE1;
1095 }
1096
1097 if (N(MountState) == MOUNT_STATE_NONE) {
1099 } else {
1102 }
1103
1104 N(PutAwayState)++;
1105 break;
1106 case PUT_AWAY_FINISH_2:
1107 partnerStatus->actingPartner = PARTNER_NONE;
1108 partnerStatus->partnerActionState = PARTNER_ACTION_NONE;
1110
1111 if (N(LockingPlayerInput)) {
1112 N(LockingPlayerInput) = false;
1114 }
1118 N(PutAwayState)++;
1119 break;
1120 case PUT_AWAY_FINISH_3:
1122 return ApiStatus_DONE1;
1123 }
1124 break;
1125 }
1126 return ApiStatus_BLOCK;
1127}
1128
1134
1150
1153
1154 if (partnerStatus->shouldResumeAbility) {
1155 if (N(MountState) != MOUNT_STATE_NONE) {
1159 partnerStatus->actingPartner = PARTNER_NONE;
1160 partnerStatus->partnerActionState = PARTNER_ACTION_NONE;
1163 }
1164 }
1165}
1166
1173
1174API_CALLABLE(N(EnterMap)) {
1179 f32* temp_s0_2;
1180
1181 if (isInitialCall) {
1182 script->functionTemp[0] = 0;
1183 }
1184
1185 switch (script->functionTemp[0]) {
1186 case 0:
1187 if (!script->varTable[12]) {
1188 temp_f0 = playerStatus->pos.x;
1189 lakilester->pos.x = temp_f0;
1190 lakilester->moveToPos.x = temp_f0;
1191 temp_f4 = playerStatus->pos.z;
1192 lakilester->pos.z = temp_f4;
1193 lakilester->moveToPos.z = temp_f4;
1194 playerStatus->pos.y = lakilester->pos.y + 10.0f;
1196 } else {
1200 lakilester->moveToPos.x = lakilester->pos.x = playerStatus->pos.x;
1201 lakilester->moveToPos.y = lakilester->pos.y = playerStatus->pos.y;
1202 lakilester->moveToPos.z = lakilester->pos.z = playerStatus->pos.z;
1203 playerStatus->pos.y = lakilester->pos.y + 10.0f;
1204 }
1205
1206 script->functionTemp[1] = script->varTable[4];
1207 temp_s0_2 = (f32*)&script->varTable[5];
1208 temp_f2 = atan2(lakilester->pos.x, lakilester->pos.z, script->varTable[1], script->varTable[3]);
1209 lakilester->yaw = temp_f2;
1210
1211 if (script->varTable[12]) {
1212 if (temp_f2 >= 0.0f && temp_f2 <= 180.0f) {
1213 lakilester->yawCamOffset = temp_f2;
1214 lakilester->isFacingAway = true;
1215 }
1216 }
1217
1220 playerStatus->animNotifyValue = 0;
1225 lakilester->moveSpeed = *temp_s0_2;
1226 lakilester->jumpScale = 0.0f;
1227 N(UpdatePushingWall) = false;
1228 N(PlayerBounceOffset) = 0;
1229 script->functionTemp[0] = 1;
1230 break;
1231
1232 case 1:
1234 playerStatus->pos.x = lakilester->pos.x;
1235 playerStatus->pos.y = lakilester->pos.y + 10.0f;
1236 playerStatus->pos.z = lakilester->pos.z;
1237 playerStatus->targetYaw = lakilester->yaw;
1239 script->functionTemp[1]--;
1240
1241 if (script->functionTemp[1] == 0) {
1242 if (script->varTable[12]) {
1243 partnerStatus->shouldResumeAbility = true;
1245 partnerStatus->actingPartner = PARTNER_NONE;
1246 partnerStatus->partnerActionState = PARTNER_ACTION_NONE;
1250 }
1251 return ApiStatus_DONE2;
1252 }
1253 }
1254
1255 return ApiStatus_BLOCK;
1256}
1257
s32 partner_use_ability(void)
Definition partners.c:964
BSS s32 PopupMenu_SelectedIndex
b8 keepUsingPartnerOnMapChange
s32 b32
s32 HitID
Bytecode EvtScript[]
#define clamp_angle
#define atan2
#define mem_clear
@ TWEESTER_PARTNER_HOLD
Definition enums.h:2463
@ TWEESTER_PARTNER_ATTRACT
Definition enums.h:2462
@ TWEESTER_PARTNER_INIT
Definition enums.h:2461
@ TWEESTER_PARTNER_RELEASE
Definition enums.h:2464
@ BUTTON_A
Definition enums.h:2776
@ BUTTON_B
Definition enums.h:2775
@ SURFACE_TYPE_WATER
Definition enums.h:4256
@ SURFACE_TYPE_SLIDE
Definition enums.h:4260
@ SURFACE_TYPE_LAVA
Definition enums.h:4258
@ SURFACE_TYPE_SPIKES
Definition enums.h:4257
@ PS_FLAG_FALLING
Definition enums.h:3070
@ PS_FLAG_ENTERING_BATTLE
Definition enums.h:3095
@ PS_FLAG_PAUSE_DISABLED
Definition enums.h:3078
@ PS_FLAG_CUTSCENE_MOVEMENT
Definition enums.h:3088
@ PS_FLAG_HIT_FIRE
Definition enums.h:3084
@ PS_FLAG_FACE_FORWARD
Definition enums.h:3113
@ PARTNER_ACTION_LAKILESTER_1
Definition enums.h:2975
@ PARTNER_ACTION_NONE
Definition enums.h:2966
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4281
@ COLLIDER_FLAGS_SURFACE_TYPE_MASK
Definition enums.h:4278
@ NPC_PARTNER
Definition enums.h:2514
@ ENTITY_TYPE_SCRIPT_SPRING
Definition enums.h:2570
@ ENTITY_TYPE_SIMPLE_SPRING
Definition enums.h:2569
@ PLAYER_COLLISION_0
Definition enums.h:4297
@ EASING_LINEAR
Definition enums.h:510
@ PA_FLAG_DISMOUNTING_ALLOWED
Definition enums.h:3157
@ PA_FLAG_RIDING_PARTNER
Definition enums.h:3150
@ PA_FLAG_CHANGING_MAP
Definition enums.h:3146
@ PA_FLAG_PARTNER_USAGE_FORCED
Definition enums.h:3149
@ PA_FLAG_FORCED_PARTNER_ABILITY_END
Definition enums.h:3159
@ SOUND_FLIGHT
Definition enums.h:1015
@ SOUND_QUICK_PLAYER_JUMP
Definition enums.h:1427
@ SOUND_MENU_ERROR
Definition enums.h:936
@ PARTNER_NONE
Definition enums.h:2919
@ PARTNER_LAKILESTER
Definition enums.h:2927
@ ACTION_STATE_RIDE
Definition enums.h:2447
@ ACTION_STATE_IDLE
Definition enums.h:2412
@ ACTION_STATE_FALLING
Definition enums.h:2421
@ ACTION_STATE_WALK
Definition enums.h:2413
@ ACTION_STATE_HIT_FIRE
Causes Mario to fly up and take damage. Used for fire bars.
Definition enums.h:2435
@ ACTION_STATE_RUN
Definition enums.h:2414
@ CAMERA_MOVE_IGNORE_PLAYER_Y
Definition enums.h:4317
@ SURFACE_INTERACT_RUN
Definition enums.h:4270
@ SOUND_SPACE_DEFAULT
Definition enums.h:1740
@ CAM_DEFAULT
Definition enums.h:1826
@ NPC_FLAG_FLYING
Definition enums.h:3035
@ NPC_FLAG_TOUCHES_GROUND
Definition enums.h:3054
@ NPC_FLAG_IGNORE_WORLD_COLLISION
Definition enums.h:3038
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:3040
@ NPC_FLAG_COLLDING_FORWARD_WITH_WORLD
Definition enums.h:3046
@ NPC_FLAG_DIRTY_SHADOW
Definition enums.h:3048
@ NPC_FLAG_IGNORE_CAMERA_FOR_YAW
Definition enums.h:3050
@ NPC_FLAG_COLLDING_WITH_WORLD
Definition enums.h:3045
#define ApiStatus_DONE2
Definition evt.h:119
#define ApiStatus_DONE1
Definition evt.h:118
#define ApiStatus_BLOCK
Definition evt.h:117
f32 update_lerp(s32 easing, f32 start, f32 end, s32 elapsed, s32 duration)
Definition 43F0.c:735
f32 fabsf(f32 f)
b32 npc_raycast_down_around(s32, f32 *, f32 *, f32 *, f32 *, f32, f32)
f64 fabs(f64 f)
HitID player_raycast_below_cam_relative(PlayerStatus *playerStatus, f32 *outX, f32 *outY, f32 *outZ, f32 *outLength, f32 *hitRx, f32 *hitRz, f32 *hitDirX, f32 *hitDirZ)
Definition 77480.c:192
s32 npc_test_move_complex_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
void suggest_player_anim_always_forward(AnimID anim)
Definition 77480.c:912
void func_800EF3D4(s32)
Definition partners.c:2411
void partner_clear_player_tracking(Npc *partner)
Definition partners.c:2433
void partner_flying_update_player_tracking(Npc *partner)
Definition partners.c:1748
s32 disable_player_input(void)
Definition 77480.c:989
s32 get_collider_flags(s32 colliderID)
Definition collision.c:481
s32 disable_player_static_collisions(void)
Definition 77480.c:971
s32 enable_player_input(void)
Definition 77480.c:997
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
void partner_kill_ability_script(void)
Definition partners.c:1109
void phys_main_collision_below(void)
Definition 7BB60.c:863
void gravity_use_fall_parms(void)
Definition 7BB60.c:301
u32 get_entity_type(s32 arg0)
Definition entity.c:568
void enable_player_shadow(void)
Definition 77480.c:963
b32 npc_test_move_simple_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
void set_action_state(s32 actionState)
Definition 7E9D0.c:209
b32 npc_test_move_taller_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
HitID player_raycast_up_corners(PlayerStatus *, f32 *, f32 *, f32 *, f32 *, f32)
Definition 77480.c:254
void suggest_player_anim_allow_backward(AnimID anim)
Definition 77480.c:893
void partner_flying_update_motion(Npc *partner)
Definition partners.c:1774
void partner_flying_enable(Npc *partner, s32 val)
Definition partners.c:1704
f32 sin_rad(f32 x)
Definition 43F0.c:713
f32 get_player_normal_pitch(void)
Definition 43F0.c:662
s32 enable_player_static_collisions(void)
Definition 77480.c:979
void sin_cos_rad(f32 rad, f32 *outSinTheta, f32 *outCosTheta)
Definition 43F0.c:706
void add_vec2D_polar(f32 *x, f32 *y, f32 r, f32 theta)
Definition 43F0.c:685
void func_800E4AD8(s32 arg0)
Definition 7BB60.c:978
void disable_player_shadow(void)
Definition 77480.c:967
void npc_surface_spawn_fx(Npc *npc, SurfaceInteractMode mode)
Definition surfaces.c:394
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:992
void npc_move_heading(Npc *npc, f32 speed, f32 yaw)
Definition npc.c:983
s32 partner_init_get_out(Npc *npc)
Definition partners.c:2249
s32 partner_init_put_away(Npc *partner)
Definition partners.c:2175
s32 partner_put_away(Npc *partner)
Definition partners.c:2182
s32 partner_force_player_flip_done(void)
Definition partners.c:2451
s32 partner_get_out(Npc *partner)
Definition partners.c:2256
void sfx_play_sound_at_npc(s32 soundID, s32 arg1, s32 npcID)
void sfx_play_sound_with_params(s32 soundID, u8 volume, u8 pan, s16 pitchShift)
#define End
Signals the end of EVT script data. A script missing this will likely crash on load.
Definition macros.h:214
#define COLLISION_WITH_ENTITY_BIT
Definition macros.h:163
#define BSS
Definition macros.h:6
#define DEG_TO_RAD(deg)
Definition macros.h:145
#define SQ(x)
Definition macros.h:177
#define NO_COLLIDER
Definition macros.h:167
#define Call(FUNC, ARGS...)
Calls a given C EVT API function with any number of arguments.
Definition macros.h:577
#define Return
Kills the current EVT thread.
Definition macros.h:218
Vec3f targetPos
Entity * TweesterTouchingPartner
Definition 7B440.c:4
CollisionStatus gCollisionStatus
Definition 7BB60.c:5
PartnerStatus gPartnerStatus
Definition partners.c:42
GameStatus * gGameStatusPtr
Definition main_loop.c:31
s32 NpcHitQueryColliderID
Camera gCameras[4]
Definition cam_main.c:16
PlayerData gPlayerData
Definition 77480.c:39
PlayerStatus gPlayerStatus
Definition 77480.c:38
s32 gCurrentCameraID
Definition cam_math.c:5
@ MOUNT_STATE_IN_PROGRESS
Definition lakilester.c:50
@ MOUNT_STATE_DONE
Definition lakilester.c:51
@ MOUNT_STATE_NONE
Definition lakilester.c:49
s32 N test_dismount_height(f32 *posY)
Definition lakilester.c:578
void N try_cancel_tweester(Npc *lakilester)
Definition lakilester.c:206
@ RIDE_STATE_MOUNT_1
Definition lakilester.c:25
@ RIDE_STATE_START_RIDING
Definition lakilester.c:29
@ RIDE_STATE_DISMOUNT_1
Definition lakilester.c:31
@ RIDE_STATE_MOUNT_4
Definition lakilester.c:28
@ RIDE_STATE_DELAY
Definition lakilester.c:24
@ RIDE_STATE_BEGIN
Definition lakilester.c:23
@ RIDE_STATE_DISMOUNT_2
Definition lakilester.c:32
@ RIDE_STATE_FINISH_1
Definition lakilester.c:34
@ RIDE_STATE_RIDING
Definition lakilester.c:30
@ RIDE_STATE_MOUNT_3
Definition lakilester.c:27
@ RIDE_STATE_FINISH_2
Definition lakilester.c:35
@ RIDE_STATE_DISMOUNT_3
Definition lakilester.c:33
@ RIDE_STATE_MOUNT_2
Definition lakilester.c:26
EvtScript EVS_WorldLakilester_PutAway
void N pre_battle(Npc *lakilester)
#define TEST_MOVE_AT_ANGLE(testFunc, angle)
void N post_battle(Npc *lakilester)
@ PUT_AWAY_FINISH_2
Definition lakilester.c:44
@ PUT_AWAY_FINISH_3
Definition lakilester.c:45
@ PUT_AWAY_DISMOUNT_3
Definition lakilester.c:42
@ PUT_AWAY_DISMOUNT_2
Definition lakilester.c:41
@ PUT_AWAY_FINISH_1
Definition lakilester.c:43
@ PUT_AWAY_DISMOUNT_1
Definition lakilester.c:40
EvtScript EVS_WorldLakilester_TakeOut
Definition lakilester.c:109
EvtScript EVS_WorldLakilester_UseAbility
Definition lakilester.c:991
s32 N test_mounting_height_adjustment(Npc *lakilester, f32 height, f32 dist)
Definition lakilester.c:282
void N sync_player_position(void)
Definition lakilester.c:56
void N get_movement_from_input(f32 *outAngle, f32 *outSpeed)
Definition lakilester.c:215
void N update_riding_physics(Npc *lakilester)
Definition lakilester.c:368
void N apply_riding_static_collisions(Npc *lakilester)
Definition lakilester.c:312
s32 N can_dismount(void)
Definition lakilester.c:233
void N offset_player_from_camera(f32 arg0)
EvtScript EVS_WorldLakilester_Update
Definition lakilester.c:200
void N init(Npc *lakilester)
Definition lakilester.c:77
EvtScript EVS_WorldLakilester_EnterMap