Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
npc_api.c
Go to the documentation of this file.
1#include "common.h"
2#include "npc.h"
3#include "world/partners.h"
4
7
9 if (npcIdOrPtr == NPC_SELF) {
10 return get_npc_safe(script->owner2.npcID);
11 } else if (npcIdOrPtr >= EVT_LIMIT) {
13 } else {
14 return (Npc*) npcIdOrPtr;
15 }
16}
17
18void set_npc_animation(Npc* npc, u32 animID) {
20
21 if (PARTNER_ANIM_STILL <= animID && animID <= PARTNER_ANIM_HURT) {
22 npc->curAnim = gPartnerAnimations[playerData->curPartner].anims[animID - PARTNER_ANIM_STILL];
23 } else if (ENEMY_ANIM_IDLE <= animID && animID <= ENEMY_ANIM_F) {
24 npc->curAnim = get_enemy(npc->npcID)->animList[animID - ENEMY_ANIM_IDLE];
25 } else {
26 npc->curAnim = animID;
27 }
28}
29
30API_CALLABLE(CreateNpc) {
31 Bytecode* args = script->ptrReadPos;
32 s32 npcID = evt_get_variable(script, *args++);
33 s32 initialAnim = evt_get_variable(script, *args++);
34 NpcBlueprint blueprint;
35 Npc *npc;
36
37 blueprint.flags = 0;
38 blueprint.initialAnim = initialAnim;
39 blueprint.onUpdate = nullptr;
40 blueprint.onRender = nullptr;
41
42 npc = get_npc_by_index(create_basic_npc(&blueprint));
43 npc->npcID = npcID;
45 return ApiStatus_DONE2;
46}
47
48API_CALLABLE(DeleteNpc) {
49 Bytecode* args = script->ptrReadPos;
50 Npc* npc = get_npc_unsafe(evt_get_variable(script, *args++));
51
52 if (npc == nullptr) {
53 return ApiStatus_DONE2;
54 }
55
56 free_npc(npc);
57 return ApiStatus_DONE2;
58}
59
60API_CALLABLE(GetNpcPointer) {
61 Bytecode* args = script->ptrReadPos;
62 s32 npcID = evt_get_variable(script, *args++);
63 Bytecode varNPC = *args++;
64
66 return ApiStatus_DONE2;
67}
68
69API_CALLABLE(SetNpcPos) {
70 Bytecode* args = script->ptrReadPos;
71 s32 npcID = evt_get_variable(script, *args++);
72 f32 x = evt_get_variable(script, *args++);
73 f32 y = evt_get_variable(script, *args++);
74 f32 z = evt_get_variable(script, *args++);
75 Npc* npc = resolve_npc(script, npcID);
76
77 if (npc == nullptr) {
78 return ApiStatus_DONE2;
79 }
80
81 npc->pos.x = x;
82 npc->pos.y = y;
83 npc->pos.z = z;
84 npc->colliderPos.x = npc->pos.x;
85 npc->colliderPos.y = npc->pos.y;
86 npc->colliderPos.z = npc->pos.z;
88
89 return ApiStatus_DONE2;
90}
91
92API_CALLABLE(SetNpcRotation) {
93 Bytecode* args = script->ptrReadPos;
94 s32 npcID = evt_get_variable(script, *args++);
95 f32 rotX = evt_get_float_variable(script, *args++);
96 f32 rotY = evt_get_float_variable(script, *args++);
97 f32 rotZ = evt_get_float_variable(script, *args++);
98 Npc* npc = resolve_npc(script, npcID);
99
100 if (npc == nullptr) {
101 return ApiStatus_DONE2;
102 }
103
104 npc->rot.x = rotX;
105 npc->rot.y = rotY;
106 npc->rot.z = rotZ;
107 return ApiStatus_DONE2;
108}
109
110API_CALLABLE(SetNpcRotationPivot) {
111 Bytecode* args = script->ptrReadPos;
112 s32 npcId = evt_get_variable(script, *args++);
113 f32 value = evt_get_float_variable(script, *args++);
114 Npc* npc;
115
116 npc = resolve_npc(script, npcId);
117 if (npc == nullptr) {
118 return ApiStatus_DONE2;
119 }
120
121 npc->rotPivotOffsetY = value;
122 return ApiStatus_DONE2;
123}
124
125API_CALLABLE(SetNpcScale) {
126 Bytecode* ptrReadPos = script->ptrReadPos;
127 s32 npcID = evt_get_variable(script, *ptrReadPos++);
128 f32 scaleX = evt_get_float_variable(script, *ptrReadPos++);
129 f32 scaleY = evt_get_float_variable(script, *ptrReadPos++);
130 f32 scaleZ = evt_get_float_variable(script, *ptrReadPos++);
131 Npc* npc = resolve_npc(script, npcID);
132
133 if (npc == nullptr) {
134 return ApiStatus_DONE2;
135 }
136
137 npc->scale.x = scaleX;
138 npc->scale.y = scaleY;
139 npc->scale.z = scaleZ;
140 return ApiStatus_DONE2;
141}
142
143API_CALLABLE(SetNpcCollisionSize) {
144 Bytecode* ptrReadPos = script->ptrReadPos;
145 s32 npcID = evt_get_variable(script, *ptrReadPos++);
146 s32 height = evt_get_variable(script, *ptrReadPos++);
147 s32 radius = evt_get_variable(script, *ptrReadPos++);
148 Npc* npc = resolve_npc(script, npcID);
149
150 if (npc == nullptr) {
151 return ApiStatus_DONE2;
152 }
153
154 npc->collisionHeight = height;
155 npc->collisionDiameter = radius;
156 return ApiStatus_DONE2;
157}
158
159API_CALLABLE(SetNpcSpeed) {
160 Bytecode* ptrReadPos = script->ptrReadPos;
161 s32 npcID = evt_get_variable(script, *ptrReadPos++);
162 f32 speed = evt_get_float_variable(script, *ptrReadPos);
163 Npc* npc = resolve_npc(script, npcID);
164
165 if (npc == nullptr) {
166 return ApiStatus_DONE2;
167 }
168
169 npc->moveSpeed = speed;
170 return ApiStatus_DONE2;
171}
172
173API_CALLABLE(SetNpcJumpscale) {
174 Bytecode* ptrReadPos = script->ptrReadPos;
175 s32 npcID = evt_get_variable(script, *ptrReadPos++);
176 f32 jumpScale = evt_get_float_variable(script, *ptrReadPos);
177 Npc* npc = resolve_npc(script, npcID);
178
179 if (npc == nullptr) {
180 return ApiStatus_DONE2;
181 }
182
183 npc->jumpScale = jumpScale;
184 return ApiStatus_DONE2;
185}
186
187API_CALLABLE(SetNpcAnimation) {
188 Bytecode* ptrReadPos = script->ptrReadPos;
189 s32 npcID = evt_get_variable(script, *ptrReadPos++);
190 s32 animation = evt_get_variable(script, *ptrReadPos);
191 Npc* npc = resolve_npc(script, npcID);
192
193 if (npc == nullptr) {
194 return ApiStatus_DONE2;
195 }
196
198 return ApiStatus_DONE2;
199}
200
201API_CALLABLE(GetNpcAnimation) {
202 Bytecode* ptrReadPos = script->ptrReadPos;
203 s32 npcID = evt_get_variable(script, *ptrReadPos++);
204 Bytecode outVar = *ptrReadPos++;
205 Npc* npc = resolve_npc(script, npcID);
206
207 if (npc == nullptr) {
208 return ApiStatus_DONE2;
209 }
210
212 return ApiStatus_DONE2;
213}
214
215API_CALLABLE(SetNpcAnimationSpeed) {
216 Bytecode* ptrReadPos = script->ptrReadPos;
217 s32 npcID = evt_get_variable(script, *ptrReadPos++);
218 f32 animationSpeed = evt_get_float_variable(script, *ptrReadPos++);
219 Npc* npc = resolve_npc(script, npcID);
220
221 if (npc == nullptr) {
222 return ApiStatus_DONE2;
223 }
224
225 npc->animationSpeed = animationSpeed;
226 return ApiStatus_DONE2;
227}
228
229API_CALLABLE(NpcMoveTo) {
230 Bytecode* args = script->ptrReadPos;
231 Npc* npc;
232 f32 dist;
233 f32 moveSpeed;
234
235 if (isInitialCall) {
236 script->functionTemp[0] = 0;
237 }
238
239 if (script->functionTemp[0] == 0) {
240 s32 npcID = evt_get_variable(script, *args++);
241 f32 goalX = evt_get_variable(script, *args++);
242 f32 goalZ = evt_get_variable(script, *args++);
243 s32 duration = evt_get_variable(script, *args++);
244
245 npc = resolve_npc(script, npcID);
246 if (npc == nullptr) {
247 return ApiStatus_DONE2;
248 }
249
250 script->functionTempPtr[1] = npc;
251 npc->moveToPos.x = goalX;
252 npc->moveToPos.z = goalZ;
253 npc->duration = duration;
254 dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
255
256 if (npc->duration == 0) {
257 npc->duration = dist / npc->moveSpeed;
258 } else {
259 npc->moveSpeed = dist / npc->duration;
260 }
261 if (npc->duration == 0) {
262 npc->duration = 1;
263 }
264 script->functionTemp[0] = 1;
265 }
266
267 npc = script->functionTempPtr[1];
268 npc->yaw = atan2(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
269 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
270
271 if (npc->moveSpeed < 4.0) {
273 } else {
275 }
276
277 dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
278
279 moveSpeed = npc->moveSpeed;
280 if (moveSpeed < 1.0) {
281 moveSpeed = 1.0f;
282 }
283
284 if (dist <= moveSpeed) {
285 return ApiStatus_DONE1;
286 }
287 return ApiStatus_BLOCK;
288}
289
291 Bytecode* args = script->ptrReadPos;
292 f32* yaw = &script->functionTempF[2];
293 Npc* npc;
294
295 if (isInitialCall) {
296 script->functionTemp[0] = 0;
297 }
298
299 if (script->functionTemp[0] == 0) {
300 s32 npcID = evt_get_variable(script, *args++);
301 f32 goalX = evt_get_variable(script, *args++);
302 f32 goalY = evt_get_variable(script, *args++);
303 f32 goalZ = evt_get_variable(script, *args++);
304 s32 duration = evt_get_variable(script, *args++);
305 f32 dist;
306
307 npc = resolve_npc(script, npcID);
308
309 if (npc == nullptr) {
310 return ApiStatus_DONE2;
311 }
312
313 script->functionTempPtr[1] = npc;
314 npc->moveToPos.x = goalX;
315 npc->moveToPos.y = goalY;
316 npc->moveToPos.z = goalZ;
317
318 npc->duration = duration;
319 dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
320 *yaw = 0.0f;
321 if (dist > 2.0) {
322 *yaw = atan2(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
323 if (snapYaw == 0) {
324 npc->yaw = *yaw;
325 }
326 }
327
328 goalY = npc->moveToPos.y - npc->pos.y;
329
330 if (npc->duration == 0) {
331 npc->duration = dist / npc->moveSpeed;
332 } else {
333 npc->moveSpeed = dist / npc->duration;
334 }
335
336 npc->flags |= NPC_FLAG_JUMPING;
337 npc->jumpVel = (npc->jumpScale * npc->duration * 0.5f) + (goalY / npc->duration);
338 script->functionTemp[0] =1;
339 }
340
341 npc = script->functionTempPtr[1];
342 npc_move_heading(npc, npc->moveSpeed, *yaw);
343
344 npc->pos.y += npc->jumpVel;
345 npc->jumpVel -= npc->jumpScale;
346
347 npc->duration--;
348 if (npc->duration < 0) {
349 npc->jumpVel = 0.0f;
350 npc->pos.x = npc->moveToPos.x;
351 npc->pos.y = npc->moveToPos.y;
352 npc->pos.z = npc->moveToPos.z;
353 npc->flags &= ~NPC_FLAG_JUMPING;
355 return ApiStatus_DONE1;
356 }
357 return ApiStatus_BLOCK;
358}
359
360API_CALLABLE(NpcJump0) {
362}
363
364API_CALLABLE(NpcJump1) {
366}
367
368API_CALLABLE(NpcFlyTo) {
369 Bytecode* args = script->ptrReadPos;
370 f32* outX = (f32*)&script->varTable[3];
371 f32* outY = (f32*)&script->varTable[4];
372 f32* outZ = (f32*)&script->varTable[5];
373 Npc* npc;
374 f32 dist;
375 f32 yDelta;
376
377 if (isInitialCall) {
378 npc = resolve_npc(script, evt_get_variable(script, *args++));
379 if (npc == nullptr) {
380 return ApiStatus_DONE2;
381 }
382
383 script->functionTempPtr[1] = npc;
384 npc->moveToPos.x = evt_get_float_variable(script, *args++);
385 npc->moveToPos.y = evt_get_float_variable(script, *args++);
386 npc->moveToPos.z = evt_get_float_variable(script, *args++);
387 script->varTable[6] = evt_get_variable(script, *args++);
388 script->functionTemp[2] = evt_get_variable(script, *args++);
389 script->functionTemp[3] = evt_get_variable(script, *args++);
390 npc->duration = 0;
391 *outX = npc->pos.x;
392 *outY = npc->pos.y;
393 *outZ = npc->pos.z;
394 npc->yaw = atan2(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
395 dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
396 npc->planarFlyDist = dist;
397
398 if (script->varTable[6] == 0) {
399 script->varTable[6] = (dist / npc->moveSpeed);
400 } else {
401 npc->moveSpeed = dist / script->varTable[6];
402 }
403 }
404
405 npc = script->functionTempPtr[1];
406 npc->pos.x = update_lerp(script->functionTemp[3], *outX, npc->moveToPos.x, npc->duration, script->varTable[6]);
407 npc->pos.y = update_lerp(script->functionTemp[3], *outY, npc->moveToPos.y, npc->duration, script->varTable[6]);
408 npc->pos.z = update_lerp(script->functionTemp[3], *outZ, npc->moveToPos.z, npc->duration, script->varTable[6]);
409
410 npc->duration++;
411 if (npc->duration >= script->varTable[6]) {
412 npc->pos.x = npc->moveToPos.x;
413 npc->pos.y = npc->moveToPos.y;
414 npc->pos.z = npc->moveToPos.z;
415 return ApiStatus_DONE2;
416 }
417
418 dist = dist2D(npc->pos.x, npc->pos.z, npc->moveToPos.x, npc->moveToPos.z);
419 if (dist == 0.0f) {
420 dist = 1.0f;
421 }
422 if (npc->planarFlyDist == 0.0f) {
423 npc->planarFlyDist = 1.0f;
424 }
425
426 yDelta = sin_deg((1.0 - (dist / npc->planarFlyDist)) * 180.0);
427 if (script->functionTemp[2] == 0) {
428 yDelta = 0.0f;
429 }
430 if (script->functionTemp[2] < 0) {
431 yDelta = -yDelta * -script->functionTemp[2];
432 }
433 if (script->functionTemp[2] > 0) {
434 yDelta *= script->functionTemp[2];
435 }
436 npc->pos.y += yDelta;
437 return ApiStatus_BLOCK;
438}
439
440API_CALLABLE(GetNpcYaw) {
441 Bytecode* ptrReadPos = script->ptrReadPos;
442 s32 npcID = evt_get_variable(script, *ptrReadPos++);
443 Bytecode outVar = *ptrReadPos++;
444 Npc* npc = resolve_npc(script, npcID);
445
446 if (npc == nullptr) {
447 return ApiStatus_DONE2;
448 }
449
451 return ApiStatus_DONE2;
452}
453
454API_CALLABLE(SetNpcYaw) {
455 Bytecode* ptrReadPos = script->ptrReadPos;
456 s32 npcID = evt_get_variable(script, *ptrReadPos++);
457 Npc* npc = resolve_npc(script, npcID);
458
459 if (npc == nullptr) {
460 return ApiStatus_DONE2;
461 }
462
463 set_npc_yaw(npc, evt_get_variable(script, *ptrReadPos++));
464 return ApiStatus_DONE2;
465}
466
467API_CALLABLE(InterpNpcYaw) {
468 Bytecode* args = script->ptrReadPos;
469 f32* initialYaw = &script->functionTempF[1];
470 f32* deltaYaw = &script->functionTempF[2];
471 s32* turnTime = &script->functionTemp[3];
472 Npc* npc;
473
474 if (isInitialCall) {
475 s32 npcID = evt_get_variable(script, *args++);
476
477 npc = resolve_npc(script, npcID);
478 if (npc == nullptr) {
479 return ApiStatus_DONE2;
480 }
481
482 *initialYaw = npc->yaw;
484 script->functionTempPtr[0] = npc;
485 *turnTime = evt_get_variable(script, *args++);
486
487 if (*turnTime == 0) {
488 npc->yaw += *deltaYaw;
489 return ApiStatus_DONE2;
490 }
491
492 npc->duration = 0;
493
494 if (*deltaYaw < -180.0f) {
495 *deltaYaw += 360.0f;
496 }
497 if (*deltaYaw > 180.0f) {
498 *deltaYaw -= 360.0f;
499 }
500 }
501
502 npc = script->functionTempPtr[0];
503 if (*turnTime > 0) {
504 npc->duration++;
505 npc->yaw = *initialYaw + ((*deltaYaw * npc->duration) / *turnTime);
506 npc->yaw = clamp_angle(npc->yaw);
507 return !(npc->duration < *turnTime) * ApiStatus_DONE1;
508 }
509
510 npc->yaw += *deltaYaw;
511 return ApiStatus_DONE2;
512}
513
514API_CALLABLE(NpcFacePlayer) {
516 Bytecode* args = script->ptrReadPos;
517 f32* initialYaw = &script->functionTempF[1];
518 f32* deltaYaw = &script->functionTempF[2];
519 s32* turnTime = &script->functionTemp[3];
520 Npc* npc;
521
522 if (isInitialCall) {
523 s32 npcID = evt_get_variable(script, *args++);
524
525 npc = resolve_npc(script, npcID);
526 if (npc == nullptr) {
527 return ApiStatus_DONE2;
528 }
529
530 *initialYaw = npc->yaw;
531 *deltaYaw = atan2(npc->pos.x, npc->pos.z, playerStatus->pos.x, playerStatus->pos.z) - *initialYaw;
532 script->functionTempPtr[0] = npc;
533 *turnTime = evt_get_variable(script, *args++);
534 npc->duration = 0;
535
536 if (*deltaYaw < -180.0f) {
537 *deltaYaw += 360.0f;
538 }
539 if (*deltaYaw > 180.0f) {
540 *deltaYaw -= 360.0f;
541 }
542 }
543
544 npc = script->functionTempPtr[0];
545 if (*turnTime > 0) {
546 npc->duration++;
547 npc->yaw = *initialYaw + ((*deltaYaw * npc->duration) / *turnTime);
548 npc->yaw = clamp_angle(npc->yaw);
549 return !(npc->duration < *turnTime) * ApiStatus_DONE1;
550 }
551
552 npc->yaw += *deltaYaw;
553 return ApiStatus_DONE2;
554}
555
556API_CALLABLE(NpcFaceNpc) {
557 Bytecode* args = script->ptrReadPos;
558 f32* initialYaw = &script->functionTempF[1];
559 f32* deltaYaw = &script->functionTempF[2];
560 s32* turnTime = &script->functionTemp[3];
561 Npc* targetNpc;
563
564 if (isInitialCall) {
566 s32 targetNpcID = evt_get_variable(script, *args++);
567
568 targetNpc = resolve_npc(script, targetNpcID);
569 if (targetNpc == nullptr) {
570 return ApiStatus_DONE2;
571 }
572
574 if (turningNpc == nullptr) {
575 return ApiStatus_DONE2;
576 }
577
578 *initialYaw = turningNpc->yaw;
579 *deltaYaw = atan2(turningNpc->pos.x, turningNpc->pos.z, targetNpc->pos.x, targetNpc->pos.z) - *initialYaw;
580 script->functionTempPtr[0] = turningNpc;
581 *turnTime = evt_get_variable(script, *args++);
582 turningNpc->duration = 0;
583
584 if (*deltaYaw < -180.0f) {
585 *deltaYaw += 360.0f;
586 }
587 if (*deltaYaw > 180.0f) {
588 *deltaYaw -= 360.0f;
589 }
590 }
591
592 turningNpc = script->functionTempPtr[0];
593 if (*turnTime > 0) {
594 turningNpc->duration++;
595 turningNpc->yaw = *initialYaw + ((*deltaYaw * turningNpc->duration) / *turnTime);
596 turningNpc->yaw = clamp_angle(turningNpc->yaw);
597 return !(turningNpc->duration < *turnTime) * ApiStatus_DONE1;
598 }
599
600 turningNpc->yaw += *deltaYaw;
601 return ApiStatus_DONE2;
602}
603
604API_CALLABLE(SetNpcFlagBits) {
605 Bytecode* args = script->ptrReadPos;
606 s32 npcID = evt_get_variable(script, *args++);
607 s32 bits = *args++;
608 s32 mode = evt_get_variable(script, *args++);
609 Npc* npc = resolve_npc(script, npcID);
610
611 if (npc == nullptr) {
612 return ApiStatus_DONE2;
613 }
614
615 if (mode) {
616 npc->flags |= bits;
617 } else {
618 npc->flags &= ~bits;
619 }
620
621 return ApiStatus_DONE2;
622}
623
624API_CALLABLE(GetNpcPos) {
625 Bytecode* args = script->ptrReadPos;
626 s32 npcID = evt_get_variable(script, *args++);
627 s32 outX = *args++;
628 s32 outY = *args++;
629 s32 outZ = *args++;
630 Npc* npc = resolve_npc(script, npcID);
631
632 if (npc == nullptr) {
633 return ApiStatus_DONE2;
634 }
635
639 return ApiStatus_DONE2;
640}
641
642API_CALLABLE(SetNpcCollisionChannel) {
643 Bytecode* args = script->ptrReadPos;
644 s32 npcID = evt_get_variable(script, *args++);
645 Bytecode channel = *args;
646 Npc* npc = resolve_npc(script, npcID);
647
648 if (npc == nullptr) {
649 return ApiStatus_DONE2;
650 }
651
653 return ApiStatus_DONE2;
654}
655
656API_CALLABLE(SetNpcSprite) {
657 Bytecode* args = script->ptrReadPos;
658 s32 npcID = evt_get_variable(script, *args++);
659 Bytecode animID = *args;
660 Npc* npc = resolve_npc(script, npcID);
661
662 if (npc == nullptr) {
663 return ApiStatus_DONE2;
664 }
665
666 set_npc_sprite(npc, animID, nullptr);
667 return ApiStatus_DONE2;
668}
669
670API_CALLABLE(EnableNpcShadow) {
671 Bytecode* ptrReadPos = script->ptrReadPos;
672 s32 npcID = evt_get_variable(script, *ptrReadPos++);
673 s32 enableShadow = evt_get_variable(script, *ptrReadPos++);
674 Npc* npc = resolve_npc(script, npcID);
675
676 if (npc == nullptr) {
677 return ApiStatus_DONE2;
678 }
679
680 if (enableShadow) {
682 } else {
684 }
685 return ApiStatus_DONE2;
686}
687
688API_CALLABLE(EnableNpcBlur) {
689 Bytecode* ptrReadPos = script->ptrReadPos;
690 s32 npcID = evt_get_variable(script, *ptrReadPos++);
691 s32 enableBlur = evt_get_variable(script, *ptrReadPos++);
692 Npc* npc = resolve_npc(script, npcID);
693
694 if (npc == nullptr) {
695 return ApiStatus_DONE2;
696 }
697
698 if (enableBlur) {
699 enable_npc_blur(npc);
700 } else {
701 disable_npc_blur(npc);
702 }
703 return ApiStatus_DONE2;
704}
705
706API_CALLABLE(ClearPartnerMoveHistory) {
707 Bytecode* ptrReadPos = script->ptrReadPos;
708 s32 npcID = evt_get_variable(script, *ptrReadPos++);
709 Npc* npc = resolve_npc(script, npcID);
710
711 if (npc == nullptr) {
712 return ApiStatus_DONE2;
713 }
714
716 return ApiStatus_DONE2;
717}
718
719API_CALLABLE(NpcSetHomePosToCurrent) {
720 Npc* npc = resolve_npc(script, evt_get_variable(script, *script->ptrReadPos));
721
722 if (npc == nullptr) {
723 return ApiStatus_DONE2;
724 }
725
726 npc->homePos.x = npc->pos.x;
727 npc->homePos.y = npc->pos.y;
728 npc->homePos.z = npc->pos.z;
729 return ApiStatus_DONE2;
730}
731
732API_CALLABLE(GetPartnerPos) {
733 Bytecode* ptrReadPos = script->ptrReadPos;
734 Bytecode posX = *ptrReadPos++;
735 Bytecode posY = *ptrReadPos++;
736 Bytecode posZ = *ptrReadPos++;
738
739 if (npc == nullptr) {
740 return ApiStatus_DONE2;
741 }
742
743 evt_set_variable(script, posX, npc->pos.x);
744 evt_set_variable(script, posY, npc->pos.y);
745 evt_set_variable(script, posZ, npc->pos.z);
746 return ApiStatus_DONE2;
747}
748
749API_CALLABLE(DisablePartnerAI) {
750 Bytecode* ptrReadPos = script->ptrReadPos;
751
752 if (evt_get_variable(script, *ptrReadPos++) == 0) {
754 } else {
756 }
757 return ApiStatus_DONE2;
758}
759
760API_CALLABLE(EnablePartnerAI) {
762 return ApiStatus_DONE2;
763}
764
765API_CALLABLE(func_802CF54C) {
767 return ApiStatus_DONE2;
768}
769
770API_CALLABLE(func_802CF56C) {
771 Bytecode* ptrReadPos = script->ptrReadPos;
772 s32 value = evt_get_variable(script, *ptrReadPos++);
773
774 if (value == 2) {
776 } else {
777 func_800EF3D4(value);
778 }
779 return ApiStatus_DONE2;
780}
781
782API_CALLABLE(BringPartnerOut) {
783 Bytecode* args = script->ptrReadPos;
788 Npc* partner;
789 Npc* npc;
790 f32 duration;
791 f32 playerZ;
792 f32 targetZ;
793 f32 playerX;
794 f32 targetX;
795 f32 targetY;
796 f32 playerY;
797
798 if (isInitialCall) {
800 if (playerData->curPartner == wExtraPartnerID) {
801 wExtraPartnerID = 0;
802 return ApiStatus_DONE2;
803 }
804
806 partner->npcID = -5;
807
809 bpPointer->initialAnim = gPartnerAnimations[wExtraPartnerID].fly;
810 bpPointer->onUpdate = nullptr;
811 bpPointer->onRender = nullptr;
812
815 npc->collisionDiameter = 10;
816 npc->collisionHeight = 10;
817 npc->npcID = NPC_PARTNER;
818 npc->scale.x = 0.0f;
819 npc->scale.y = 0.0f;
820 npc->scale.z = 0.0f;
821
822 npc->moveToPos.x = targetX = partner->pos.x;
823 playerY = playerStatus->pos.y;
824 npc->moveToPos.y = playerStatus->pos.y;
825 npc->moveToPos.z = targetZ = partner->pos.z + 30.0f;
826 npc->pos.x = playerX = playerStatus->pos.x;
827 npc->pos.y = targetY = playerStatus->pos.y + (playerStatus->colliderHeight / 2);
828 playerZ = playerStatus->pos.z;
829 npc->moveSpeed = 4.0f;
830 npc->jumpScale = 1.6f;
831 npc->pos.z = playerZ;
832
833 npc->planarFlyDist = dist2D(playerX, npc->pos.z, targetX, targetZ);
834 npc->yaw = atan2(playerX, playerZ, targetX, targetZ);
835 npc->duration = npc->planarFlyDist / npc->moveSpeed;
836
837 if (npc->duration < 10) {
838 npc->duration = 10;
839 npc->moveSpeed = npc->planarFlyDist / npc->duration;
840 }
841
842 npc->jumpVel = ((playerY - targetY) + (npc->jumpScale * npc->duration * npc->duration * 0.5f)) / npc->duration;
844 return ApiStatus_BLOCK;
845 }
846
848 npc->jumpVel -= npc->jumpScale;
849 npc->pos.y += npc->jumpVel;
850 if (npc->jumpVel <= 0.0f) {
852 }
853 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
854 duration = npc->duration;
855 if (duration > 10.0f) {
856 duration = 10.0f;
857 }
858 npc->scale.x = (10.0f - duration) / 10.0f;
859 npc->scale.y = npc->scale.x;
860 npc->scale.z = npc->scale.x;
861
862 npc->duration--;
863 if (npc->duration < 0) {
865 npc->jumpVel = 0.0f;
866 npc->pos.y = npc->moveToPos.y;
867 npc->scale.x = 1.0f;
868 npc->scale.y = 1.0f;
869 npc->scale.z = 1.0f;
870 npc->yaw = clamp_angle(npc->yaw + 180.0f);
871 return ApiStatus_DONE2;
872 }
873 return ApiStatus_BLOCK;
874}
875
876API_CALLABLE(PutPartnerAway) {
879 f32 scale;
880 f32 targetX;
881 f32 targetY;
882 f32 targetZ;
886
887 if (isInitialCall) {
888 if (wExtraPartnerID != 0) {
890 partner->flags &= ~NPC_FLAG_FLYING;
891 targetX = playerStatus->pos.x;
892 partner->moveToPos.x = targetX;
893 partnerX = partner->pos.x;
894 targetY = playerStatus->pos.y + (playerStatus->colliderHeight / 2);
895 partner->moveToPos.y = targetY;
896 partnerY = partner->pos.y;
897 targetZ = playerStatus->pos.z;
898 partner->moveToPos.z = targetZ;
899 partnerZ = partner->pos.z;
900 partner->moveSpeed = 4.0f;
901 partner->jumpScale = 2.6f;
902 partner->planarFlyDist = dist2D(partnerX, partnerZ, targetX, targetZ);
903 partner->yaw = atan2(partnerX, partnerZ, targetX, targetZ);
904 partner->duration = partner->planarFlyDist / partner->moveSpeed;
905
906 if (partner->duration < 10) {
907 partner->duration = 10;
908 partner->moveSpeed = partner->planarFlyDist / partner->duration;
909 }
910
911 partnerY = targetY - partnerY;
912 partner->jumpVel = (partnerY + (partner->jumpScale * partner->duration * partner->duration * 0.5f)) / partner->duration;
914 return ApiStatus_BLOCK;
915 } else {
916 return ApiStatus_DONE2;
917 }
918 }
919
920 partner->jumpVel -= partner->jumpScale;
921 partner->pos.y += partner->jumpVel;
922 if (partner->jumpVel <= 0.0f) {
924 }
925 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
926
927 scale = partner->duration;
928 if (scale > 10.0f) {
929 scale = 10.0f;
930 }
931
932 partner->scale.x = scale / 10.0f;
933 partner->scale.y = partner->scale.x;
934 partner->scale.z = partner->scale.x;
935
936 partner->duration--;
937 if (partner->duration < 0) {
939 partner->jumpVel = 0.0f;
940 partner->pos.y = partner->moveToPos.y;
943 return ApiStatus_DONE2;
944 }
945 return ApiStatus_BLOCK;
946}
947
948API_CALLABLE(GetCurrentPartnerID) {
950 return ApiStatus_DONE2;
951}
952
953API_CALLABLE(PartnerCanUseAbility) {
954 Bytecode outVar = *script->ptrReadPos;
955
957 return ApiStatus_DONE2;
958}
959
960API_CALLABLE(PartnerIsFlying) {
961 Bytecode outVar = *script->ptrReadPos;
962
964 return ApiStatus_DONE2;
965}
966
967API_CALLABLE(SetNpcImgFXParams) {
968 Bytecode* args = script->ptrReadPos;
969 s32 npcId = evt_get_variable(script, *args++);
970 Bytecode imgfxType = evt_get_variable(script, *args++);
971 Bytecode var2 = evt_get_variable(script, *args++);
972 Bytecode var3 = evt_get_variable(script, *args++);
975 Npc* npc = resolve_npc(script, npcId);
976
977 if (npc == nullptr) {
978 return ApiStatus_DONE2;
979 }
980
981 npc_set_imgfx_params(npc, imgfxType, var2, var3, var4, var5, npc->imgfxFlags);
982 return ApiStatus_DONE2;
983}
984
985API_CALLABLE(SetNpcImgFXFlags) {
986 Bytecode* args = script->ptrReadPos;
987 s32 npcId = evt_get_variable(script, *args++);
988 Bytecode flags = *args;
989 Npc* npc = resolve_npc(script, npcId);
990
991 if (npc == nullptr) {
992 return ApiStatus_DONE2;
993 }
994
995 npc->imgfxFlags = flags;
996 return ApiStatus_DONE2;
997}
998
999API_CALLABLE(SetNpcPaletteSwapMode) {
1000 Bytecode* args = script->ptrReadPos;
1001 s32 npcId = evt_get_variable(script, *args++);
1003 Npc* npc = resolve_npc(script, npcId);
1004
1005 if (npc == nullptr) {
1006 return ApiStatus_DONE2;
1007 }
1008
1010 return ApiStatus_DONE2;
1011}
1012
1013API_CALLABLE(SetNpcPaletteSwapLower) {
1014 Bytecode* args = script->ptrReadPos;
1015 s32 npcId = evt_get_variable(script, *args++);
1016 Bytecode var1 = evt_get_variable(script, *args++);
1017 Bytecode var2 = evt_get_variable(script, *args++);
1018 Bytecode var3 = evt_get_variable(script, *args++);
1020 Npc* npc = resolve_npc(script, npcId);
1021
1022 if (npc == nullptr) {
1023 return ApiStatus_DONE2;
1024 }
1025
1026 npc_set_palswap_1(npc, var1, var2, var3, var4);
1027 return ApiStatus_DONE2;
1028}
1029
1030API_CALLABLE(SetNpcPaletteSwapping) {
1031 Bytecode* args = script->ptrReadPos;
1032 s32 npcId = evt_get_variable(script, *args++);
1033 Bytecode var1 = evt_get_variable(script, *args++);
1034 Bytecode var2 = evt_get_variable(script, *args++);
1035 Bytecode var3 = evt_get_variable(script, *args++);
1041 Npc* npc = resolve_npc(script, npcId);
1042
1043 if (npc == nullptr) {
1044 return ApiStatus_DONE2;
1045 }
1046
1047 npc_set_palswap_1(npc, var1, var2, var3, var4);
1049 return ApiStatus_DONE2;
1050}
1051
1052API_CALLABLE(SetNpcDecoration) {
1053 Bytecode* ptrReadPos = script->ptrReadPos;
1054 s32 npcID = evt_get_variable(script, *ptrReadPos++);
1055 s32 value1 = evt_get_variable(script, *ptrReadPos++);
1056 s32 value2 = evt_get_variable(script, *ptrReadPos++);
1057 Npc* npc = resolve_npc(script, npcID);
1058
1059 if (npc == nullptr) {
1060 return ApiStatus_DONE2;
1061 }
1062
1064 return ApiStatus_DONE2;
1065}
1066
1067API_CALLABLE(PlaySoundAtNpc) {
1068 Bytecode* ptrReadPos = script->ptrReadPos;
1069 s32 npcID = evt_get_variable(script, *ptrReadPos++);
1070 s32 soundID = evt_get_variable(script, *ptrReadPos++);
1071 s32 flags = evt_get_variable(script, *ptrReadPos++);
1072 Npc* npc = resolve_npc(script, npcID);
1073
1074 if (npc == nullptr) {
1075 return ApiStatus_DONE2;
1076 }
1077
1078 sfx_play_sound_at_position(soundID, flags, npc->pos.x, npc->pos.y, npc->pos.z);
1079 return ApiStatus_DONE2;
1080}
1081
1082API_CALLABLE(SetNpcRenderMode) {
1083 Bytecode* ptrReadPos = script->ptrReadPos;
1084 s32 npcID = evt_get_variable(script, *ptrReadPos++);
1085 u8 renderMode = evt_get_variable(script, *ptrReadPos++);
1086 Npc* npc = resolve_npc(script, npcID);
1087
1088 npc->renderMode = renderMode;
1089 return ApiStatus_DONE2;
1090}
BSS s32 PopupMenu_SelectedIndex
s8 flags
Definition demo_api.c:15
#define sfx_play_sound_at_position
#define sin_deg
#define clamp_angle
#define atan2
@ PARTNER_ANIM_STILL
Definition enums.h:3448
@ PARTNER_ANIM_HURT
Definition enums.h:3456
@ ENEMY_ANIM_F
Definition enums.h:3488
@ ENEMY_ANIM_IDLE
Definition enums.h:3473
@ NPC_SELF
Definition enums.h:2512
@ NPC_PARTNER
Definition enums.h:2514
@ SURFACE_INTERACT_RUN
Definition enums.h:4270
@ SURFACE_INTERACT_WALK
Definition enums.h:4269
@ SURFACE_INTERACT_LAND
Definition enums.h:4271
@ NPC_FLAG_JUMPING
Definition enums.h:3043
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:3040
@ NPC_FLAG_DIRTY_SHADOW
Definition enums.h:3048
s32 ApiStatus
Definition evt.h:116
#define ApiStatus_DONE2
Definition evt.h:119
s32 Bytecode
Definition evt.h:7
#define ApiStatus_DONE1
Definition evt.h:118
#define ApiStatus_BLOCK
Definition evt.h:117
s32 evt_get_variable(Evt *script, Bytecode var)
Definition evt.c:1730
f32 update_lerp(s32 easing, f32 start, f32 end, s32 elapsed, s32 duration)
Definition 43F0.c:735
void disable_npc_blur(Npc *npc)
Definition npc.c:1085
void func_800EF3D4(s32)
Definition partners.c:2411
void partner_clear_player_tracking(Npc *partner)
Definition partners.c:2433
void enable_npc_blur(Npc *npc)
Definition npc.c:1064
s32 evt_set_variable(Evt *script, Bytecode var, s32 value)
Definition evt.c:1887
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
s32 partner_is_flying(void)
Definition partners.c:572
void func_800EF314(void)
Definition partners.c:2383
void enable_partner_ai(void)
Definition partners.c:2387
void func_800EF3E4(void)
Definition partners.c:2415
void func_800EF43C(void)
Definition partners.c:2427
f32 evt_get_float_variable(Evt *script, Bytecode var)
Definition evt.c:1970
void func_800EF300(void)
Definition partners.c:2379
void free_npc(Npc *npc)
Definition npc.c:236
s32 create_basic_npc(NpcBlueprint *blueprint)
Definition npc.c:189
void npc_surface_spawn_fx(Npc *npc, SurfaceInteractMode mode)
Definition surfaces.c:394
Enemy * get_enemy(s32 npcID)
Looks for an enemy matching the specified npcID.
Definition npc.c:2537
void npc_set_palswap_1(Npc *npc, s32 palIndexA, s32 palIndexB, s32 timeHoldA, s32 timeAB)
Definition npc.c:1284
void enable_npc_shadow(Npc *npc)
Definition npc.c:1024
s32 * animList
Definition npc.h:341
void disable_npc_shadow(Npc *npc)
Definition npc.c:1034
void free_npc_by_index(s32 listIndex)
Definition npc.c:201
void npc_set_imgfx_params(Npc *npc, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6)
Definition npc.c:2159
void npc_set_decoration(Npc *npc, s32 idx, s32 decorationType)
Definition npc.c:1731
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:992
void npc_set_palswap_2(Npc *npc, s32 timeHoldB, s32 timeBA, s32 palIndexC, s32 palIndexD)
Definition npc.c:1291
void npc_set_palswap_mode_A(Npc *npc, s32 arg1)
Definition npc.c:1255
Npc * get_npc_by_index(s32 listIndex)
Definition npc.c:270
void npc_move_heading(Npc *npc, f32 speed, f32 yaw)
Definition npc.c:983
void set_npc_yaw(Npc *npc, f32 yaw)
Definition npc.c:1243
void set_npc_sprite(Npc *npc, s32 anim, AnimID *extraAnimList)
Definition npc.c:1045
Npc * get_npc_safe(s32 npcID)
Definition npc.c:1007
void set_npc_animation(Npc *npc, u32 animID)
Definition npc_api.c:18
s32 wExtraPartnerID
Definition script_list.c:34
ApiStatus _npc_jump_to(Evt *script, s32 isInitialCall, s32 snapYaw)
Definition npc_api.c:290
Npc * resolve_npc(Evt *script, s32 npcIdOrPtr)
Definition npc_api.c:8
s32 wExtraPartnerNpcID
Definition script_list.c:35
s32 partner_can_use_ability(void)
Definition partners.c:993
ApiStatus SetNpcPaletteSwapping(Evt *script, b32 isInitialCall)
ApiStatus PlaySoundAtNpc(Evt *script, b32 isInitialCall)
ApiStatus SetNpcRotationPivot(Evt *script, b32 isInitialCall)
ApiStatus DeleteNpc(Evt *script, b32 isInitialCall)
ApiStatus PartnerIsFlying(Evt *script, b32 isInitialCall)
ApiStatus DisablePartnerAI(Evt *script, b32 isInitialCall)
ApiStatus ClearPartnerMoveHistory(Evt *script, b32 isInitialCall)
ApiStatus SetNpcPaletteSwapMode(Evt *script, b32 isInitialCall)
ApiStatus GetNpcAnimation(Evt *script, b32 isInitialCall)
ApiStatus SetNpcImgFXFlags(Evt *script, b32 isInitialCall)
ApiStatus PartnerCanUseAbility(Evt *script, b32 isInitialCall)
ApiStatus EnableNpcShadow(Evt *script, b32 isInitialCall)
ApiStatus GetNpcPos(Evt *script, b32 isInitialCall)
ApiStatus SetNpcDecoration(Evt *script, b32 isInitialCall)
ApiStatus SetNpcImgFXParams(Evt *script, b32 isInitialCall)
ApiStatus SetNpcSpeed(Evt *script, b32 isInitialCall)
ApiStatus NpcSetHomePosToCurrent(Evt *script, b32 isInitialCall)
ApiStatus GetCurrentPartnerID(Evt *script, b32 isInitialCall)
ApiStatus SetNpcAnimation(Evt *script, b32 isInitialCall)
ApiStatus SetNpcPaletteSwapLower(Evt *script, b32 isInitialCall)
ApiStatus SetNpcScale(Evt *script, b32 isInitialCall)
ApiStatus SetNpcRenderMode(Evt *script, b32 isInitialCall)
ApiStatus EnablePartnerAI(Evt *script, b32 isInitialCall)
ApiStatus NpcFaceNpc(Evt *script, b32 isInitialCall)
ApiStatus GetNpcYaw(Evt *script, b32 isInitialCall)
ApiStatus SetNpcRotation(Evt *script, b32 isInitialCall)
ApiStatus BringPartnerOut(Evt *script, b32 isInitialCall)
ApiStatus CreateNpc(Evt *script, b32 isInitialCall)
ApiStatus InterpNpcYaw(Evt *script, b32 isInitialCall)
ApiStatus NpcJump1(Evt *script, b32 isInitialCall)
ApiStatus SetNpcPos(Evt *script, b32 isInitialCall)
ApiStatus NpcJump0(Evt *script, b32 isInitialCall)
ApiStatus NpcFacePlayer(Evt *script, b32 isInitialCall)
ApiStatus SetNpcJumpscale(Evt *script, b32 isInitialCall)
ApiStatus PutPartnerAway(Evt *script, b32 isInitialCall)
ApiStatus SetNpcAnimationSpeed(Evt *script, b32 isInitialCall)
ApiStatus SetNpcCollisionChannel(Evt *script, b32 isInitialCall)
ApiStatus SetNpcSprite(Evt *script, b32 isInitialCall)
ApiStatus SetNpcYaw(Evt *script, b32 isInitialCall)
ApiStatus GetPartnerPos(Evt *script, b32 isInitialCall)
ApiStatus GetNpcPointer(Evt *script, b32 isInitialCall)
ApiStatus NpcMoveTo(Evt *script, b32 isInitialCall)
ApiStatus SetNpcFlagBits(Evt *script, b32 isInitialCall)
ApiStatus func_802CF56C(Evt *script, b32 isInitialCall)
ApiStatus EnableNpcBlur(Evt *script, b32 isInitialCall)
ApiStatus SetNpcCollisionSize(Evt *script, b32 isInitialCall)
ApiStatus NpcFlyTo(Evt *script, b32 isInitialCall)
ApiStatus func_802CF54C(Evt *script, b32 isInitialCall)
#define EVT_LIMIT
Definition macros.h:48
void(* onRender)(struct Npc *)
Definition npc.h:89
void(* onUpdate)(struct Npc *)
Definition npc.h:88
s32 initialAnim
Definition npc.h:87
s32 flags
Definition npc.h:86
s16 collisionDiameter
f32 jumpScale
Vec3f scale
f32 jumpVel
f32 animationSpeed
s8 renderMode
s32 flags
AnimID curAnim
Vec3f moveToPos
f32 planarFlyDist
s32 collisionChannel
Vec3f colliderPos
s16 collisionHeight
Vec3f rot
u16 imgfxFlags
Vec3f pos
f32 rotPivotOffsetY
f32 moveSpeed
Vec3s homePos
s16 duration
PlayerData gPlayerData
Definition 77480.c:39
PartnerAnimations gPartnerAnimations[12]
Definition partners.c:343
PlayerStatus gPlayerStatus
Definition 77480.c:38