Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
parakarry.c
Go to the documentation of this file.
1#include "common.h"
2#include "../src/world/partners.h"
3#include "sprite/npc/WorldParakarry.h"
4#include "sprite/player.h"
5
6#define NAMESPACE world_parakarry
7
8BSS b32 N(UsingAbility);
9BSS b32 N(LockingPlayerInput);
10BSS b32 N(PlayerCollisionDisabled); // minor bug: never gets properly reset to FALSE
11BSS b32 N(PlayerWasFacingLeft);
12BSS s32 N(AbilityState);
13BSS s32 N(AbilityStateTime);
14BSS TweesterPhysics N(TweesterPhysicsData);
15
16enum {
17 AIR_LIFT_NONE = 0, // only used for initial value
18 // next two states lock input for a few frames, during which the ability can be canceled
23 AIR_LIFT_PICKUP = 1, // pick up the player and lift them into the air
24 AIR_LIFT_CARRY = 2, // carry the player through the air
25 AIR_LIFT_HOLD = 6, // remain in one position for a short period of time
26 AIR_LIFT_JUMP = 20, // player jumped off while being carried
27 AIR_LIFT_DROP = 21, // dropping the player
29};
30
31void N(init)(Npc* parakarry) {
32 parakarry->collisionHeight = 37;
33 parakarry->collisionDiameter = 40;
34 N(UsingAbility) = FALSE;
35 N(AbilityState) = AIR_LIFT_NONE;
36 N(LockingPlayerInput) = FALSE;
37 N(PlayerCollisionDisabled) = FALSE;
38 N(PlayerWasFacingLeft) = FALSE;
39 N(AbilityStateTime) = 0;
40}
41
42API_CALLABLE(N(TakeOut)) {
43 Npc* parakarry = script->owner2.npc;
44
45 if (isInitialCall) {
46 partner_init_get_out(parakarry);
47 }
48
49 if (partner_get_out(parakarry)) {
50 return ApiStatus_DONE1;
51 } else {
52 return ApiStatus_BLOCK;
53 }
54}
55
57 Call(N(TakeOut))
58 Return
59 End
60};
61
62TweesterPhysics* N(TweesterPhysicsPtr) = &N(TweesterPhysicsData);
63
64API_CALLABLE(N(Update)) {
65 PlayerData* playerData = &gPlayerData;
66 Npc* parakarry = script->owner2.npc;
67 f32 sinAngle, cosAngle, liftoffVelocity;
68 Entity* entity;
69
70 if (isInitialCall) {
71 partner_flying_enable(parakarry, 1);
72 mem_clear(N(TweesterPhysicsPtr), sizeof(TweesterPhysics));
74 }
75
78
79 if (entity == NULL) {
82 return ApiStatus_BLOCK;
83 }
84
85 switch (N(TweesterPhysicsPtr)->state) {
87 N(TweesterPhysicsPtr)->state++;
88 N(TweesterPhysicsPtr)->prevFlags = parakarry->flags;
89 N(TweesterPhysicsPtr)->radius = fabsf(dist2D(parakarry->pos.x, parakarry->pos.z,
90 entity->pos.x, entity->pos.z));
91 N(TweesterPhysicsPtr)->angle = atan2(entity->pos.x, entity->pos.z,
92 parakarry->pos.x, parakarry->pos.z);
93 N(TweesterPhysicsPtr)->angularVel = 6.0f;
94 N(TweesterPhysicsPtr)->liftoffVelPhase = 50.0f;
95 N(TweesterPhysicsPtr)->countdown = 120;
97 parakarry->flags &= ~NPC_FLAG_GRAVITY;
99 sin_cos_rad(DEG_TO_RAD(N(TweesterPhysicsPtr)->angle), &sinAngle, &cosAngle);
100 parakarry->pos.x = entity->pos.x + (sinAngle * N(TweesterPhysicsPtr)->radius);
101 parakarry->pos.z = entity->pos.z - (cosAngle * N(TweesterPhysicsPtr)->radius);
102 N(TweesterPhysicsPtr)->angle = clamp_angle(N(TweesterPhysicsPtr)->angle - N(TweesterPhysicsPtr)->angularVel);
103
104 if (N(TweesterPhysicsPtr)->radius > 20.0f) {
105 N(TweesterPhysicsPtr)->radius--;
106 } else if (N(TweesterPhysicsPtr)->radius < 19.0f) {
107 N(TweesterPhysicsPtr)->radius++;
108 }
109
110 liftoffVelocity = sin_rad(DEG_TO_RAD(N(TweesterPhysicsPtr)->liftoffVelPhase)) * 3.0f;
111 N(TweesterPhysicsPtr)->liftoffVelPhase += 3.0f;
112
113 if (N(TweesterPhysicsPtr)->liftoffVelPhase > 150.0f) {
114 N(TweesterPhysicsPtr)->liftoffVelPhase = 150.0f;
115 }
116
117 parakarry->pos.y += liftoffVelocity;
118 parakarry->renderYaw = clamp_angle(360.0f - N(TweesterPhysicsPtr)->angle);
119 N(TweesterPhysicsPtr)->angularVel += 0.8;
120
121 if (N(TweesterPhysicsPtr)->angularVel > 40.0f) {
122 N(TweesterPhysicsPtr)->angularVel = 40.0f;
123 }
124
125 if (--N(TweesterPhysicsPtr)->countdown == 0) {
126 N(TweesterPhysicsPtr)->state++;
127 }
128 break;
130 parakarry->flags = N(TweesterPhysicsPtr)->prevFlags;
131 N(TweesterPhysicsPtr)->countdown = 30;
132 N(TweesterPhysicsPtr)->state++;
133 break;
137
138 if (--N(TweesterPhysicsPtr)->countdown == 0) {
139 N(TweesterPhysicsPtr)->state = TWEESTER_PARTNER_INIT;
141 }
142 break;
143 }
144 return ApiStatus_BLOCK;
145}
146
148 Call(N(Update))
149 Return
150 End
151};
152
153void N(try_cancel_tweester)(Npc* parakarry) {
156 parakarry->flags = N(TweesterPhysicsPtr)->prevFlags;
157 N(TweesterPhysicsPtr)->state = TWEESTER_PARTNER_INIT;
159 }
160}
161
163 f32 x, y, z, length, hitRx, hitRz, hitDirX, hitDirZ;
164 f32 colliderBaseHeight = gPlayerStatus.colliderHeight;
165 HitID hitID;
166 s32 surfaceType;
167
168 x = gPlayerStatus.pos.x;
169 y = gPlayerStatus.pos.y + (colliderBaseHeight * 0.5);
170 z = gPlayerStatus.pos.z;
171 length = colliderBaseHeight / 2.0f;
172
173 hitID = player_raycast_below_cam_relative(&gPlayerStatus, &x, &y, &z, &length, &hitRx,
174 &hitRz, &hitDirX, &hitDirZ);
175
177 if (surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) {
180 N(AbilityState) = AIR_LIFT_DROP;
181 }
182
183 return hitID;
184}
185
186API_CALLABLE(N(UseAbility)) {
187 PlayerStatus* playerStatus = &gPlayerStatus;
188 PartnerStatus* partnerStatus = &gPartnerStatus;
189 Npc* parakarry = script->owner2.npc;
190 s32 buttonTemp = BUTTON_A;
191 f32 x, y, z, yaw, length;
192 f32 playerDeltaX, playerDeltaZ;
193 f32 parakarryDeltaX, parakarryDeltaZ;
194 f32 halfCollisionHeight;
195 s32 hitCount;
196 b32 hitAbove;
197
198 if (gCurrentEncounter.unk_08 != 0) {
199 return ApiStatus_BLOCK;
200 }
201
202 if (isInitialCall) {
203 N(try_cancel_tweester)(parakarry);
204 if ((playerStatus->animFlags & PA_FLAG_CHANGING_MAP)) {
205 return ApiStatus_DONE2;
206 }
207
208 if (!partnerStatus->shouldResumeAbility) {
210 return ApiStatus_DONE2;
211 }
212 N(AbilityState) = AIR_LIFT_INIT;
213 parakarry->flags &= ~NPC_FLAG_COLLDING_FORWARD_WITH_WORLD;
215 } else {
216 partnerStatus->shouldResumeAbility = FALSE;
218 parakarry->flags &= ~(NPC_FLAG_JUMPING | NPC_FLAG_GRAVITY);
219 N(UsingAbility) = TRUE;
221 parakarry->curAnim = ANIM_WorldParakarry_CarryLight;
222 partnerStatus->actingPartner = PARTNER_PARAKARRY;
224 parakarry->flags &= ~NPC_FLAG_COLLDING_FORWARD_WITH_WORLD;
226 }
227 }
228
229 switch (N(AbilityState)) {
230 case AIR_LIFT_INIT:
231 if (playerStatus->inputDisabledCount != 0) {
232 return ApiStatus_DONE2;
233 }
234 N(AbilityStateTime) = 3;
235 N(AbilityState) = AIR_LIFT_DELAY;
236 script->functionTemp[2] = playerStatus->inputDisabledCount;
237 // fallthrough
238 case AIR_LIFT_DELAY:
239 if (N(AbilityStateTime) == 0) {
240 if (script->functionTemp[2] < playerStatus->inputDisabledCount || !func_800EA52C(PARTNER_PARAKARRY)) {
241 return ApiStatus_DONE2;
242 }
243 N(AbilityState) = AIR_LIFT_BEGIN;
244 } else {
245 N(AbilityStateTime)--;
246 }
247 break;
248 }
249
250 switch (N(AbilityState)) {
251 case AIR_LIFT_BEGIN:
255 script->functionTemp[2] = playerStatus->inputDisabledCount;
256 N(LockingPlayerInput) = TRUE;
257 N(PlayerCollisionDisabled) = TRUE;
258 N(UsingAbility) = TRUE;
260 parakarry->flags &= ~(NPC_FLAG_JUMPING | NPC_FLAG_GRAVITY);
262 partnerStatus->actingPartner = PARTNER_PARAKARRY;
264 N(PlayerWasFacingLeft) = partner_force_player_flip_done();
265 enable_npc_blur(parakarry);
266 parakarry->yaw = atan2(parakarry->pos.x, parakarry->pos.z, playerStatus->pos.x, playerStatus->pos.z);
267 parakarry->duration = 4;
268 N(AbilityState)++; // AIR_LIFT_GATHER
269 break;
270 case AIR_LIFT_GATHER:
271 if (playerStatus->actionState == ACTION_STATE_HIT_FIRE
272 || playerStatus->actionState == ACTION_STATE_HIT_LAVA
273 || playerStatus->actionState == ACTION_STATE_KNOCKBACK
274 || playerStatus->actionState == ACTION_STATE_JUMP
275 || playerStatus->actionState == ACTION_STATE_HOP
276 ) {
277 disable_npc_blur(parakarry);
278 N(AbilityState) = AIR_LIFT_DROP;
279 } else {
280 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
281 parakarry->moveToPos.x = playerStatus->pos.x;
282 parakarry->moveToPos.y = playerStatus->pos.y + 32.0f;
283 parakarry->moveToPos.z = playerStatus->pos.z;
284 parakarry->curAnim = ANIM_WorldParakarry_Run;
285 add_vec2D_polar(&parakarry->moveToPos.x, &parakarry->moveToPos.z, 0.0f, playerStatus->targetYaw);
286 yaw = playerStatus->targetYaw;
287
288 yaw += !N(PlayerWasFacingLeft) ? 90.0f : -90.0f;
289
290 add_vec2D_polar(&parakarry->moveToPos.x, &parakarry->moveToPos.z, 5.0f, clamp_angle(yaw));
291
292 parakarry->pos.x += (parakarry->moveToPos.x - parakarry->pos.x) / parakarry->duration;
293 parakarry->pos.y += (parakarry->moveToPos.y - parakarry->pos.y) / parakarry->duration;
294 parakarry->pos.z += (parakarry->moveToPos.z - parakarry->pos.z) / parakarry->duration;
295 parakarry->duration--;
296 if (parakarry->duration != 0) {
297 if (script->functionTemp[2] < playerStatus->inputDisabledCount) {
298 disable_npc_blur(parakarry);
299 N(AbilityState) = AIR_LIFT_CANCEL;
300 }
301 } else {
302 disable_npc_blur(parakarry);
303 parakarry->yaw = playerStatus->targetYaw;
304 parakarry->moveSpeed = 0.2f;
305 parakarry->curAnim = ANIM_WorldParakarry_CarryHeavy;
306 parakarry->planarFlyDist = 0;
307 suggest_player_anim_always_forward(ANIM_MarioW2_HoldOnto);
311 parakarry->curFloor = NO_COLLIDER;
312 N(AbilityStateTime) = 20;
313 N(AbilityState) = AIR_LIFT_PICKUP;
314 }
315 }
316 break;
317 case AIR_LIFT_PICKUP:
318 if (playerStatus->actionState == ACTION_STATE_HIT_FIRE
319 || playerStatus->actionState == ACTION_STATE_HIT_LAVA
320 || playerStatus->actionState == ACTION_STATE_KNOCKBACK
321 ) {
322 N(AbilityState) = AIR_LIFT_DROP;
323 break;
324 }
325 // handle jump/cancel inputs
326 if (partnerStatus->pressedButtons & (BUTTON_A | BUTTON_B | BUTTON_C_DOWN)) {
327 N(AbilityState) = (partnerStatus->pressedButtons & BUTTON_A) ? AIR_LIFT_JUMP : AIR_LIFT_DROP;
328 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
329 break;
330 }
331
332 if (gGameStatusPtr->frameCounter % 6 == 0) {
334 }
335
336 length = fabsf(sin_rad(DEG_TO_RAD((20 - N(AbilityStateTime)) * 18))) * 1.3;
337 playerStatus->pos.y += length;
338 parakarry->pos.y += length;
339 x = parakarry->pos.x;
340 y = parakarry->pos.y + parakarry->collisionHeight / 2.0f;
341 z = parakarry->pos.z;
342 length = parakarry->collisionHeight / 2.0f;
343 halfCollisionHeight = length;
344
345 if (npc_raycast_up(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &length)) {
346 if (length < halfCollisionHeight) {
347 N(AbilityStateTime) = 0;
348 }
349 }
350
351 length = playerStatus->colliderHeight / 2.0f;
352 x = playerStatus->pos.x;
353 y = playerStatus->pos.y + playerStatus->colliderHeight / 2.0f;
354 z = playerStatus->pos.z;
355 halfCollisionHeight = playerStatus->spriteFacingAngle - 90.0f + gCameras[gCurrentCameraID].curYaw;
356 if (player_raycast_up_corners(playerStatus, &x, &y, &z, &length, halfCollisionHeight) > NO_COLLIDER) {
357 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
358 N(AbilityState) = AIR_LIFT_DROP;
359 break;
360 }
361
362 x = playerStatus->pos.x;
363 y = playerStatus->pos.y;
364 z = playerStatus->pos.z;
365 hitCount = npc_test_move_complex_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, parakarry->moveSpeed, parakarry->yaw, playerStatus->colliderHeight, playerStatus->colliderDiameter);
366 if (hitCount > 1) {
367 playerStatus->pos.x += (x - playerStatus->pos.x) / 8.0f;
368 playerStatus->pos.z += (z - playerStatus->pos.z) / 8.0f;
369 parakarry->pos.x += (x - parakarry->pos.x) / 8.0f;
370 parakarry->pos.z += (z - parakarry->pos.z) / 8.0f;
371 }
372
373 x = parakarry->pos.x;
374 y = parakarry->pos.y;
375 z = parakarry->pos.z;
376 hitCount = npc_test_move_complex_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, parakarry->moveSpeed, parakarry->yaw, parakarry->collisionHeight, parakarry->collisionDiameter);
377 if (hitCount > 1) {
378 playerDeltaX = (x - playerStatus->pos.x) / 8.0f;
379 playerDeltaZ = (z - playerStatus->pos.z) / 8.0f;
380 parakarryDeltaX = (x - parakarry->pos.x) / 8.0f;
381 parakarryDeltaZ = (z - parakarry->pos.z) / 8.0f;
382
383 x = parakarry->pos.x + parakarryDeltaX;
384 z = parakarry->pos.z + parakarryDeltaZ;
385
386 x = parakarry->pos.x;
387 y = parakarry->pos.y;
388 z = parakarry->pos.z;
389 hitCount = npc_test_move_complex_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, parakarry->moveSpeed, parakarry->yaw, parakarry->collisionHeight, parakarry->collisionDiameter);
390 if (hitCount == 0) {
391 playerStatus->pos.x += playerDeltaX;
392 playerStatus->pos.z += playerDeltaZ;
393 parakarry->pos.x += parakarryDeltaX;
394 parakarry->pos.z += parakarryDeltaZ;
395 }
396 }
397
398 if (hitCount == 0 && !(playerStatus->animFlags & PA_FLAG_NPC_COLLIDED)) {
399 add_vec2D_polar(&parakarry->pos.x, &parakarry->pos.z, parakarry->moveSpeed, parakarry->yaw);
400 add_vec2D_polar(&playerStatus->pos.x, &playerStatus->pos.z, parakarry->moveSpeed, parakarry->yaw);
401 parakarry->planarFlyDist += parakarry->moveSpeed;
402 }
403
404 x = playerStatus->pos.x;
405 y = playerStatus->pos.y + playerStatus->colliderHeight / 2.0f;
406 z = playerStatus->pos.z;
407 length = playerStatus->colliderHeight / 2.0f;
408 if (npc_raycast_down_around(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &length, parakarry->yaw, parakarry->collisionDiameter)) {
410 if (surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) {
411 playerStatus->hazardType = HAZARD_TYPE_SPIKES;
412 playerStatus->flags |= PS_FLAG_HIT_FIRE;
413 N(AbilityState) = AIR_LIFT_DROP;
414 }
415
416 playerStatus->pos.y += (y - playerStatus->pos.y) / 4.0f;
417 parakarry->pos.y = playerStatus->pos.y + 32.0f;
418 }
419
421 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
422 N(AbilityState) = AIR_LIFT_DROP;
423 break;
424 }
425
426 gCameras[CAM_DEFAULT].targetPos.x = playerStatus->pos.x;
427 gCameras[CAM_DEFAULT].targetPos.y = playerStatus->pos.y;
428 gCameras[CAM_DEFAULT].targetPos.z = playerStatus->pos.z;
429 if (N(AbilityStateTime) != 0) {
430 N(AbilityStateTime)--;
431 } else {
432 parakarry->jumpVel = -0.5f;
433 parakarry->jumpScale = -0.01f;
434 parakarry->moveToPos.y = playerStatus->pos.y;
435 parakarry->duration = 0;
436 parakarry->curAnim = ANIM_WorldParakarry_CarryHeavy;
437 parakarry->animationSpeed = 1.8f;
439 N(AbilityState)++; // AIR_LIFT_CARRY
440 }
441 break;
442 case AIR_LIFT_CARRY:
444 if (playerStatus->actionState == ACTION_STATE_HIT_FIRE
445 || playerStatus->actionState == ACTION_STATE_HIT_LAVA
446 || playerStatus->actionState == ACTION_STATE_KNOCKBACK
447 ) {
448 N(AbilityState) = AIR_LIFT_DROP;
449 break;
450 }
451
452 suggest_player_anim_always_forward(ANIM_MarioW2_HoldOnto);
453 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
454 N(AbilityState) = AIR_LIFT_JUMP;
455 break;
456 }
457
458 // handle jump/cancel inputs
459 if (partnerStatus->pressedButtons & (BUTTON_A | BUTTON_B | BUTTON_C_DOWN)) {
460 if (partnerStatus->pressedButtons & buttonTemp) { // TODO find a way to remove this while still loading 0x15 instead of moving it from register
461 if (!parakarry->pos.x) {
462
463 }
464 }
465 N(AbilityState) = (partnerStatus->pressedButtons & BUTTON_A) ? AIR_LIFT_JUMP : AIR_LIFT_DROP;
466 break;
467 }
468
469 if (gGameStatusPtr->frameCounter % 6 == 0) {
471 }
472
473 parakarry->jumpVel -= parakarry->jumpScale;
474 if (parakarry->jumpVel > 0.0) {
475 parakarry->jumpVel = 0.0f;
476 }
477
478 parakarry->pos.y += parakarry->jumpVel;
479 playerStatus->pos.y += parakarry->jumpVel;
480 if (!(playerStatus->animFlags & PA_FLAG_NPC_COLLIDED)) {
481 parakarry->moveSpeed += 0.1;
482 if (parakarry->moveSpeed > 2.0) {
483 parakarry->moveSpeed = 2.0f;
484 }
485
486 add_vec2D_polar(&parakarry->pos.x, &parakarry->pos.z, parakarry->moveSpeed, parakarry->yaw);
487 add_vec2D_polar(&playerStatus->pos.x, &playerStatus->pos.z, parakarry->moveSpeed, parakarry->yaw);
488 parakarry->planarFlyDist += parakarry->moveSpeed;
489 parakarry->animationSpeed -= 0.05;
490 if (parakarry->animationSpeed < 1.5) {
491 parakarry->animationSpeed = 1.5f;
492 }
493 if (parakarry->planarFlyDist > 80.0f) {
494 parakarry->animationSpeed += 0.5;
495 }
496 if (!(playerStatus->animFlags & PA_FLAG_NPC_COLLIDED)) {
497 x = playerStatus->pos.x;
498 y = playerStatus->pos.y;
499 z = playerStatus->pos.z;
501 &x, &y, &z, parakarry->moveSpeed, parakarry->yaw,
502 playerStatus->colliderHeight, playerStatus->colliderDiameter)
503 ) {
504 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
505 N(AbilityState) = AIR_LIFT_DROP;
506 break;
507 }
508
509 x = parakarry->pos.x;
510 y = parakarry->pos.y;
511 z = parakarry->pos.z;
513 &x, &y, &z, parakarry->moveSpeed, parakarry->yaw,
514 parakarry->collisionHeight, parakarry->collisionDiameter)
515 ) {
516 hitAbove = FALSE;
517 x = parakarry->pos.x;
518 y = parakarry->pos.y + parakarry->collisionHeight / 2.0f;
519 z = parakarry->pos.z;
520 length = parakarry->collisionHeight / 2.0f;
521
522 halfCollisionHeight = length;
523 if (npc_raycast_up(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &length) && (length < halfCollisionHeight)) {
524 parakarry->pos.y = y - parakarry->collisionHeight;
525 playerStatus->pos.y = parakarry->pos.y - 32.0f;
526 hitAbove = TRUE;
527 }
528 x = playerStatus->pos.x;
529 y = playerStatus->pos.y + playerStatus->colliderHeight / 2.0f;
530 z = playerStatus->pos.z;
531 length = playerStatus->colliderHeight / 2.0f;
532
533 if (npc_raycast_down_around(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &length, parakarry->yaw, parakarry->collisionDiameter)) {
534 playerStatus->pos.y += (y - playerStatus->pos.y) / 4.0f;
535 parakarry->pos.y = playerStatus->pos.y + 32.0f;
536 y = parakarry->pos.y;
537 parakarry->pos.y = playerStatus->pos.y;
539 parakarry->pos.y = y;
540
541 if (hitAbove) {
542 N(AbilityState) = AIR_LIFT_DROP;
543 break;
544 }
545 }
546
548 gCameras[CAM_DEFAULT].moveFlags &= ~CAMERA_MOVE_NO_INTERP_Y;
549 }
550 gCameras[CAM_DEFAULT].targetPos.x = playerStatus->pos.x;
551 gCameras[CAM_DEFAULT].targetPos.y = playerStatus->pos.y;
552 gCameras[CAM_DEFAULT].targetPos.z = playerStatus->pos.z;
553 if (!(parakarry->flags & NPC_FLAG_COLLDING_FORWARD_WITH_WORLD)) {
554 parakarry->duration++;
555 if (!(parakarry->planarFlyDist < 100.0f)) {
556 N(AbilityStateTime) = 5;
557 N(AbilityState) = AIR_LIFT_HOLD;
558 }
559 break;
560 }
561 }
562 }
563 }
564 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
565 N(AbilityState) = AIR_LIFT_DROP;
566 break;
567 case AIR_LIFT_HOLD:
568 if (N(AbilityStateTime) != 0) {
569 N(AbilityStateTime)--;
570 } else {
571 N(AbilityState) = AIR_LIFT_DROP;
572 }
573 break;
574 }
575
576 if (N(AbilityState) == AIR_LIFT_JUMP
577 || N(AbilityState) == AIR_LIFT_DROP
578 || N(AbilityState) == AIR_LIFT_CANCEL
579 ) {
580 parakarry->curAnim = ANIM_WorldParakarry_Idle;
581 N(UsingAbility) = FALSE;
582 parakarry->jumpVel = 0.0f;
583 parakarry->flags &= ~NPC_FLAG_JUMPING;
584 parakarry->animationSpeed = 1.0f;
586 partnerStatus->actingPartner = PARTNER_NONE;
590 if (N(LockingPlayerInput)) {
592 }
593 if (N(PlayerCollisionDisabled)) {
595 }
596 if ((playerStatus->flags & PS_FLAG_HIT_FIRE)) {
598 } else if (N(AbilityState) == AIR_LIFT_JUMP) {
600 } else if (N(AbilityState) == AIR_LIFT_DROP) {
603 playerStatus->flags |= PS_FLAG_SCRIPTED_FALL;
604 } else {
606 }
607 return ApiStatus_DONE2;
608 }
609
610 return ApiStatus_BLOCK;
611}
612
614 Call(N(UseAbility))
615 Return
616 End
617};
618
619API_CALLABLE(N(PutAway)) {
620 Npc* parakarry = script->owner2.npc;
621
622 if (isInitialCall) {
623 partner_init_put_away(parakarry);
624 }
625
626 if (partner_put_away(parakarry)) {
627 return ApiStatus_DONE1;
628 } else {
629 return ApiStatus_BLOCK;
630 }
631}
632
634 Call(N(PutAway))
635 Return
636 End
637};
638
639void N(pre_battle)(Npc* parakarry) {
640 PartnerStatus* partnerStatus = &gPartnerStatus;
641
642 if (N(UsingAbility)) {
643 if (N(PlayerCollisionDisabled)) {
645 }
646
647 if (N(LockingPlayerInput)) {
649 }
650
652 partnerStatus->npc = *parakarry;
653 partnerStatus->shouldResumeAbility = TRUE;
655 }
656
657 partnerStatus->actingPartner = PARTNER_PARAKARRY;
658}
659
660void N(post_battle)(Npc* parakarry) {
661 PartnerStatus* partnerStatus = &gPartnerStatus;
662
663 if (partnerStatus->shouldResumeAbility) {
664 if (N(PlayerCollisionDisabled)) {
666 }
667 if (N(LockingPlayerInput)) {
669 }
670
672 *parakarry = partnerStatus->npc;
673 partnerStatus->actingPartner = PARTNER_NONE;
677 }
678}
s32 partner_use_ability(void)
Definition partners.c:964
s32 partnerUsedTime[12]
s32 b32
s32 HitID
Bytecode EvtScript[]
#define clamp_angle
#define atan2
#define mem_clear
@ TWEESTER_PARTNER_HOLD
Definition enums.h:2477
@ TWEESTER_PARTNER_ATTRACT
Definition enums.h:2476
@ TWEESTER_PARTNER_INIT
Definition enums.h:2475
@ TWEESTER_PARTNER_RELEASE
Definition enums.h:2478
@ BUTTON_A
Definition enums.h:2790
@ BUTTON_C_DOWN
Definition enums.h:2779
@ BUTTON_B
Definition enums.h:2789
@ SURFACE_TYPE_LAVA
Definition enums.h:4673
@ SURFACE_TYPE_SPIKES
Definition enums.h:4672
@ PS_FLAG_SCRIPTED_FALL
Definition enums.h:3071
@ PS_FLAG_HIT_FIRE
Definition enums.h:3050
@ PARTNER_ACTION_PARAKARRY_HOVER
Definition enums.h:2939
@ PARTNER_ACTION_NONE
Definition enums.h:2932
@ LANDING_CAM_NEVER_ADJUST
Definition enums.h:6419
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4696
@ COLLIDER_FLAGS_SURFACE_TYPE_MASK
Definition enums.h:4693
@ NPC_PARTNER
Definition enums.h:2528
@ HAZARD_TYPE_SPIKES
Definition enums.h:3501
@ PA_FLAG_NPC_COLLIDED
Definition enums.h:3106
@ PA_FLAG_CHANGING_MAP
Definition enums.h:3112
@ SOUND_PARAKARRY_FLAP
Definition enums.h:1318
@ PARTNER_NONE
Definition enums.h:2885
@ PARTNER_PARAKARRY
Definition enums.h:2889
@ ACTION_STATE_RIDE
Definition enums.h:2461
@ ACTION_STATE_HIT_LAVA
Definition enums.h:2451
@ ACTION_STATE_JUMP
Definition enums.h:2430
@ ACTION_STATE_IDLE
Definition enums.h:2426
@ ACTION_STATE_HOP
Released A before apex of jump.
Definition enums.h:2432
@ ACTION_STATE_KNOCKBACK
Definition enums.h:2450
@ ACTION_STATE_HIT_FIRE
Causes Mario to fly up and take damage. Used for fire bars.
Definition enums.h:2449
@ CAMERA_MOVE_IGNORE_PLAYER_Y
Definition enums.h:4732
@ SURFACE_INTERACT_WALK
Definition enums.h:4684
@ SOUND_SPACE_DEFAULT
Definition enums.h:1737
@ CAM_DEFAULT
Definition enums.h:1800
@ NPC_FLAG_FLYING
Definition enums.h:3001
@ NPC_FLAG_JUMPING
Definition enums.h:3009
@ NPC_FLAG_IGNORE_WORLD_COLLISION
Definition enums.h:3004
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:3006
@ NPC_FLAG_COLLDING_FORWARD_WITH_WORLD
Definition enums.h:3012
@ NPC_FLAG_GRAVITY
Definition enums.h:3007
@ NPC_FLAG_IGNORE_CAMERA_FOR_YAW
Definition enums.h:3016
@ NPC_FLAG_COLLDING_WITH_WORLD
Definition enums.h:3011
#define ApiStatus_DONE2
Definition evt.h:118
#define ApiStatus_DONE1
Definition evt.h:117
#define ApiStatus_BLOCK
Definition evt.h:116
void start_falling(void)
Definition 7E9D0.c:293
f32 fabsf(f32 f)
b32 npc_raycast_down_around(s32, f32 *, f32 *, f32 *, f32 *, f32, f32)
void disable_npc_blur(Npc *npc)
Definition npc.c:1088
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:193
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:913
void partner_clear_player_tracking(Npc *partner)
Definition partners.c:2436
void partner_flying_update_player_tracking(Npc *partner)
Definition partners.c:1751
s32 disable_player_input(void)
Definition 77480.c:990
s32 get_collider_flags(s32 colliderID)
Definition collision.c:481
void enable_npc_blur(Npc *npc)
Definition npc.c:1067
s32 disable_player_static_collisions(void)
Definition 77480.c:972
s32 enable_player_input(void)
Definition 77480.c:998
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
s32 phys_adjust_cam_on_landing(void)
Definition 7E9D0.c:46
void gravity_use_fall_parms(void)
Definition 7BB60.c:302
void start_bounce_b(void)
Definition 7E9D0.c:310
void set_action_state(s32 actionState)
Definition 7E9D0.c:209
void enable_partner_ai(void)
Definition partners.c:2390
b32 npc_raycast_up(s32, f32 *, f32 *, f32 *, f32 *)
HitID player_raycast_up_corners(PlayerStatus *, f32 *, f32 *, f32 *, f32 *, f32)
Definition 77480.c:255
void suggest_player_anim_allow_backward(AnimID anim)
Definition 77480.c:894
void partner_flying_update_motion(Npc *partner)
Definition partners.c:1777
void partner_flying_enable(Npc *partner, s32 val)
Definition partners.c:1706
f32 sin_rad(f32 x)
Definition 43F0.c:713
s32 enable_player_static_collisions(void)
Definition 77480.c:980
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 npc_surface_spawn_fx(Npc *npc, SurfaceInteractMode mode)
Definition surfaces.c:394
EncounterStatus gCurrentEncounter
Definition encounter.c:176
s32 func_800EA52C(s32 partnerID)
Definition partners.c:537
s32 partner_init_get_out(Npc *npc)
Definition partners.c:2252
s32 partner_init_put_away(Npc *partner)
Definition partners.c:2178
s32 partner_put_away(Npc *partner)
Definition partners.c:2185
s32 partner_force_player_flip_done(void)
Definition partners.c:2454
s32 partner_get_out(Npc *partner)
Definition partners.c:2259
void sfx_play_sound_at_npc(s32 soundID, s32 arg1, s32 npcID)
Definition sfx.c:527
void sfx_stop_sound(s32 soundID)
Definition sfx.c:507
#define End
Signals the end of EVT script data. A script missing this will likely crash on load.
Definition macros.h:213
#define BSS
Definition macros.h:7
#define DEG_TO_RAD(deg)
Definition macros.h:134
#define NO_COLLIDER
Definition macros.h:156
#define Call(FUNC, ARGS...)
Calls a given C EVT API function with any number of arguments.
Definition macros.h:576
#define Return
Kills the current EVT thread.
Definition macros.h:217
Vec3f targetPos
s16 collisionDiameter
f32 jumpScale
f32 jumpVel
f32 animationSpeed
s32 flags
f32 renderYaw
AnimID curAnim
Vec3f moveToPos
f32 planarFlyDist
s16 collisionHeight
Vec3f pos
s16 curFloor
f32 moveSpeed
s16 duration
Entity * TweesterTouchingPartner
Definition 7B440.c:5
CollisionStatus gCollisionStatus
Definition 7BB60.c:6
PartnerStatus gPartnerStatus
Definition partners.c:42
GameStatus * gGameStatusPtr
Definition main_loop.c:32
s32 NpcHitQueryColliderID
Camera gCameras[4]
Definition cam_main.c:17
PlayerData gPlayerData
Definition 77480.c:40
PlayerStatus gPlayerStatus
Definition 77480.c:39
s32 gCurrentCameraID
Definition cam_math.c:4
EvtScript EVS_WorldParakarry_UseAbility
Definition parakarry.c:613
void N pre_battle(Npc *parakarry)
Definition parakarry.c:639
void N post_battle(Npc *parakarry)
Definition parakarry.c:660
@ AIR_LIFT_HOLD
Definition parakarry.c:25
@ AIR_LIFT_GATHER
Definition parakarry.c:22
@ AIR_LIFT_DROP
Definition parakarry.c:27
@ AIR_LIFT_CANCEL
Definition parakarry.c:28
@ AIR_LIFT_INIT
Definition parakarry.c:19
@ AIR_LIFT_DELAY
Definition parakarry.c:20
@ AIR_LIFT_JUMP
Definition parakarry.c:26
@ AIR_LIFT_PICKUP
Definition parakarry.c:23
@ AIR_LIFT_CARRY
Definition parakarry.c:24
@ AIR_LIFT_BEGIN
Definition parakarry.c:21
@ AIR_LIFT_NONE
Definition parakarry.c:17
EvtScript EVS_WorldParakarry_PutAway
Definition parakarry.c:633
HitID N update_current_floor(void)
Definition parakarry.c:162
EvtScript EVS_WorldParakarry_Update
Definition parakarry.c:147
void N init(Npc *parakarry)
Definition parakarry.c:31
EvtScript EVS_WorldParakarry_TakeOut
Definition parakarry.c:56
void N try_cancel_tweester(Npc *parakarry)
Definition parakarry.c:153