Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
partners.c
Go to the documentation of this file.
1#include "common_structs.h"
2#include "partners.h"
3#include "macros.h"
4
5#include "ld_addrs.h"
6#include "npc.h"
7#include "hud_element.h"
8
9#include "partner/goombario.h"
10#include "sprite/npc/WorldGoombario.h"
11
12#include "partner/kooper.h"
13#include "sprite/npc/WorldKooper.h"
14
15#include "partner/bombette.h"
16#include "sprite/npc/WorldBombette.h"
17
18#include "partner/parakarry.h"
19#include "sprite/npc/WorldParakarry.h"
20
21#include "partner/goompa.h"
22#include "sprite/npc/Goompa.h"
23
24#include "partner/watt.h"
25#include "sprite/npc/WorldWatt.h"
26
27#include "partner/sushie.h"
28#include "sprite/npc/WorldSushie.h"
29
30#include "partner/lakilester.h"
31#include "sprite/npc/WorldLakilester.h"
32
33#include "partner/bow.h"
34#include "sprite/npc/WorldBow.h"
35
36#include "partner/goombaria.h"
37#include "sprite/npc/Goombaria.h"
38
39#include "partner/twink.h"
40#include "sprite/npc/Twink.h"
41
44
63
69extern HudScript HES_Watt;
72extern HudScript HES_Bow;
84
97
105
113
115
116s32 partner_is_idle(Npc* partner);
118void _use_partner_ability(void);
120void partner_move_to_goal(Npc*, s32);
121
122typedef struct UseItemStruct {
123 /* 0x00 */ u8* dmaStart;
124 /* 0x04 */ u8* dmaEnd;
125 /* 0x08 */ EvtScript* main;
126 /* 0x0C */ s32 unk_0C;
128
129// Partner icons
155
156s32 StatusBarSPIncrementOffsets[] = { -1, 1, 2, 4, 5, 7, 8, 0, 0, 0 };
157
163f32 D_800F8034 = 0.0f;
166
168 [PARTNER_NONE] {
169 // blank
170 },
172 .dmaStart = &world_partner_goombario_ROM_START,
173 .dmaEnd = &world_partner_goombario_ROM_END,
174 .dmaDest = &world_partner_goombario_VRAM,
175 .isFlying = FALSE,
176 .init = world_goombario_init,
177 .takeOut = &EVS_WorldGoombario_TakeOut,
178 .update = &EVS_WorldGoombario_Update,
179 .useAbility = &EVS_WorldGoombario_UseAbility,
180 .putAway = &EVS_WorldGoombario_PutAway,
181 .idle = ANIM_WorldGoombario_Idle,
182 .canUseAbility = world_goombario_can_open_menus,
183 .canPlayerOpenMenus = world_goombario_can_open_menus,
184 .preBattle = world_goombario_pre_battle,
185 },
187 .dmaStart = &world_partner_kooper_ROM_START,
188 .dmaEnd = &world_partner_kooper_ROM_END,
189 .dmaDest = &world_partner_kooper_VRAM,
190 .isFlying = FALSE,
191 .init = world_kooper_init,
192 .takeOut = &EVS_WorldKooper_TakeOut,
193 .update = &EVS_WorldKooper_Update,
194 .useAbility = &EVS_WorldKooper_UseAbility,
195 .putAway = &EVS_WorldKooper_PutAway,
196 .idle = ANIM_WorldKooper_Idle,
197 .testFirstStrike = world_kooper_test_first_strike,
198 .canUseAbility = partner_is_idle,
199 .canPlayerOpenMenus = partner_is_idle,
200 .preBattle = world_kooper_pre_battle,
201 .postBattle = world_kooper_post_battle,
202 },
204 .dmaStart = &world_partner_bombette_ROM_START,
205 .dmaEnd = &world_partner_bombette_ROM_END,
206 .dmaDest = &world_partner_bombette_VRAM,
207 .isFlying = FALSE,
208 .init = world_bombette_init,
209 .takeOut = &EVS_WorldBombette_TakeOut,
210 .update = &EVS_WorldBombette_Update,
211 .useAbility = &EVS_WorldBombette_UseAbility,
212 .putAway = &EVS_WorldBombette_PutAway,
213 .idle = ANIM_WorldBombette_Idle,
214 .testFirstStrike = world_bombette_test_first_strike,
215 .canUseAbility = world_bombette_can_use_ability,
216 .canPlayerOpenMenus = world_bombette_can_open_menus,
217 .preBattle = world_bombette_pre_battle,
218 },
220 .dmaStart = &world_partner_parakarry_ROM_START,
221 .dmaEnd = &world_partner_parakarry_ROM_END,
222 .dmaDest = &world_partner_parakarry_VRAM,
223 .isFlying = TRUE,
224 .init = world_parakarry_init,
225 .takeOut = &EVS_WorldParakarry_TakeOut,
226 .update = &EVS_WorldParakarry_Update,
227 .useAbility = &EVS_WorldParakarry_UseAbility,
228 .putAway = &EVS_WorldParakarry_PutAway,
229 .idle = ANIM_WorldParakarry_Idle,
230 .canPlayerOpenMenus = partner_is_idle,
231 .preBattle = world_parakarry_pre_battle,
232 .postBattle = world_parakarry_post_battle,
233 },
235 .dmaStart = &world_partner_goompa_ROM_START,
236 .dmaEnd = &world_partner_goompa_ROM_END,
237 .dmaDest = &world_partner_goompa_VRAM,
238 .isFlying = FALSE,
239 .init = world_goompa_init,
240 .takeOut = &EVS_WorldGoompa_TakeOut,
241 .update = &EVS_WorldGoompa_Update,
242 .useAbility = &EVS_WorldGoompa_UseAbility,
243 .putAway = &EVS_WorldGoompa_PutAway,
244 .idle = ANIM_Goompa_Idle,
245 },
246 [PARTNER_WATT] {
247 .dmaStart = &world_partner_watt_ROM_START,
248 .dmaEnd = &world_partner_watt_ROM_END,
249 .dmaDest = &world_partner_watt_VRAM,
250 .isFlying = TRUE,
251 .init = world_watt_init,
252 .takeOut = &EVS_WorldWatt_TakeOut,
253 .update = &EVS_WorldWatt_Update,
254 .useAbility = &EVS_WorldWatt_UseAbility,
255 .putAway = &EVS_WorldWatt_PutAway,
256 .idle = ANIM_WorldWatt_Idle,
257 .canPlayerOpenMenus = world_partner_can_open_menus_default,
258 .preBattle = world_watt_pre_battle,
259 .postBattle = world_watt_post_battle,
260 .onEnterMap = &EVS_WorldWatt_EnterMap,
261 },
263 .dmaStart = &world_partner_sushie_ROM_START,
264 .dmaEnd = &world_partner_sushie_ROM_END,
265 .dmaDest = &world_partner_sushie_VRAM,
266 .isFlying = FALSE,
267 .init = world_sushie_init,
268 .takeOut = &EVS_WorldSushie_TakeOut,
269 .update = &EVS_WorldSushie_Update,
270 .useAbility = &EVS_WorldSushie_UseAbility,
271 .putAway = &EVS_WorldSushie_PutAway,
272 .idle = ANIM_WorldSushie_Idle,
273 .canPlayerOpenMenus = world_partner_can_open_menus_default,
274 .preBattle = world_sushie_pre_battle,
275 .postBattle = world_sushie_post_battle,
276 .onEnterMap = &EVS_WorldSushie_EnterMap,
277 },
279 .dmaStart = &world_partner_lakilester_ROM_START,
280 .dmaEnd = &world_partner_lakilester_ROM_END,
281 .dmaDest = &world_partner_lakilester_VRAM,
282 .isFlying = TRUE,
283 .init = world_lakilester_init,
284 .takeOut = &EVS_WorldLakilester_TakeOut,
286 .useAbility = &EVS_WorldLakilester_UseAbility,
287 .putAway = &EVS_WorldLakilester_PutAway,
288 .idle = ANIM_WorldLakilester_Idle,
289 .canPlayerOpenMenus = world_partner_can_open_menus_default,
290 .preBattle = world_lakilester_pre_battle,
291 .postBattle = world_lakilester_post_battle,
292 .onEnterMap = &EVS_WorldLakilester_EnterMap,
293 },
294 [PARTNER_BOW] {
295 .dmaStart = &world_partner_bow_ROM_START,
296 .dmaEnd = &world_partner_bow_ROM_END,
297 .dmaDest = &world_partner_bow_VRAM,
298 .isFlying = TRUE,
299 .init = world_bow_init,
300 .takeOut = &EVS_WorldBow_TakeOut,
301 .update = &EVS_WorldBow_Update,
302 .useAbility = &EVS_WorldBow_UseAbility,
303 .putAway = &EVS_WorldBow_PutAway,
304 .idle = ANIM_WorldBow_Idle,
305 .canUseAbility = partner_is_idle,
306 .canPlayerOpenMenus = world_partner_can_open_menus_default,
307 .preBattle = world_bow_pre_battle,
308 },
310 .dmaStart = &world_partner_goombaria_ROM_START,
311 .dmaEnd = &world_partner_goombaria_ROM_END,
312 .dmaDest = &world_partner_goombaria_VRAM,
313 .isFlying = FALSE,
314 .init = world_goombaria_init,
315 .takeOut = &EVS_WorldGoombaria_TakeOut,
316 .update = &EVS_WorldGoombaria_Update,
317 .useAbility = &EVS_WorldGoombaria_UseAbility,
318 .putAway = &EVS_WorldGoombaria_PutAway,
319 .idle = ANIM_Goombaria_Idle,
320 .canUseAbility = partner_is_idle,
321 .canPlayerOpenMenus = partner_is_idle,
322 },
323 [PARTNER_TWINK] {
324 .dmaStart = &world_partner_twink_ROM_START,
325 .dmaEnd = &world_partner_twink_ROM_END,
326 .dmaDest = &world_partner_twink_VRAM,
327 .isFlying = TRUE,
328 .init = world_twink_init,
329 .takeOut = &EVS_WorldTwink_TakeOut,
330 .update = &EVS_WorldTwink_Update,
331 .useAbility = &EVS_WorldTwink_UseAbility,
332 .putAway = &EVS_WorldTwink_PutAway,
333 .idle = ANIM_Twink_Idle,
334 .canUseAbility = partner_is_idle,
335 .canPlayerOpenMenus = partner_is_idle,
336 },
337};
338
342
344 [PARTNER_NONE] {
345 // blank
346 },
348 ANIM_WorldGoombario_Still,
349 ANIM_WorldGoombario_Walk,
350 ANIM_WorldGoombario_Jump,
351 ANIM_WorldGoombario_Fall,
352 ANIM_WorldGoombario_Idle,
353 ANIM_WorldGoombario_Idle,
354 ANIM_WorldGoombario_Run,
355 ANIM_WorldGoombario_Talk,
356 ANIM_WorldGoombario_Hurt
357 }},
358 [PARTNER_KOOPER] {{
359 ANIM_WorldKooper_Still,
360 ANIM_WorldKooper_Walk,
361 ANIM_WorldKooper_Jump,
362 ANIM_WorldKooper_Fall,
363 ANIM_WorldKooper_Still,
364 ANIM_WorldKooper_Idle,
365 ANIM_WorldKooper_Run,
366 ANIM_WorldKooper_Talk,
367 ANIM_WorldKooper_Hurt
368 }},
370 ANIM_WorldBombette_Still,
371 ANIM_WorldBombette_Walk,
372 ANIM_WorldBombette_Jump,
373 ANIM_WorldBombette_Fall,
374 ANIM_WorldBombette_Still,
375 ANIM_WorldBombette_Idle,
376 ANIM_WorldBombette_Run,
377 ANIM_WorldBombette_Talk,
378 ANIM_WorldBombette_Hurt
379 }},
381 ANIM_WorldParakarry_Still,
382 ANIM_WorldParakarry_Walk,
383 ANIM_WorldParakarry_FlyFast,
384 ANIM_WorldParakarry_Walk,
385 ANIM_WorldParakarry_Walk,
386 ANIM_WorldParakarry_Idle,
387 ANIM_WorldParakarry_Run,
388 ANIM_WorldParakarry_Talk,
389 ANIM_WorldParakarry_Hurt
390 }},
391 [PARTNER_GOOMPA] {{
392 ANIM_Goompa_Still,
393 ANIM_Goompa_Walk,
394 ANIM_Goompa_Jump,
395 ANIM_Goompa_Fall,
396 ANIM_Goompa_Idle,
397 ANIM_Goompa_Idle,
398 ANIM_Goompa_Run,
399 ANIM_Goompa_Talk,
400 ANIM_Goompa_Idle
401 }},
402 [PARTNER_WATT] {{
403 ANIM_WorldWatt_Still,
404 ANIM_WorldWatt_Walk,
405 ANIM_WorldWatt_Walk,
406 ANIM_WorldWatt_Walk,
407 ANIM_WorldWatt_Still,
408 ANIM_WorldWatt_Idle,
409 ANIM_WorldWatt_Run,
410 ANIM_WorldWatt_Talk,
411 ANIM_WorldWatt_Hurt
412 }},
413 [PARTNER_SUSHIE] {{
414 ANIM_WorldSushie_Still,
415 ANIM_WorldSushie_Walk,
416 ANIM_WorldSushie_Walk,
417 ANIM_WorldSushie_Walk,
418 ANIM_WorldSushie_Still,
419 ANIM_WorldSushie_Idle,
420 ANIM_WorldSushie_Run,
421 ANIM_WorldSushie_Talk,
422 ANIM_WorldSushie_Hurt
423 }},
425 ANIM_WorldLakilester_Still,
426 ANIM_WorldLakilester_Walk,
427 ANIM_WorldLakilester_Walk,
428 ANIM_WorldLakilester_Walk,
429 ANIM_WorldLakilester_Still,
430 ANIM_WorldLakilester_Idle,
431 ANIM_WorldLakilester_Run,
432 ANIM_WorldLakilester_Talk,
433 ANIM_WorldLakilester_TiredTalk
434 }},
435 [PARTNER_BOW] {{
436 ANIM_WorldBow_Still,
437 ANIM_WorldBow_Walk,
438 ANIM_WorldBow_Walk,
439 ANIM_WorldBow_Walk,
440 ANIM_WorldBow_Still,
441 ANIM_WorldBow_Idle,
442 ANIM_WorldBow_Run,
443 ANIM_WorldBow_Talk,
444 ANIM_WorldBow_Flail
445 }},
447 ANIM_Goombaria_Still,
448 ANIM_Goombaria_Walk,
449 ANIM_Goombaria_Jump,
450 ANIM_Goombaria_Fall,
451 ANIM_Goombaria_Idle,
452 ANIM_Goombaria_Idle,
453 ANIM_Goombaria_Run,
454 ANIM_Goombaria_Talk,
455 ANIM_Goombaria_Idle
456 }},
457 [PARTNER_TWINK] {{
458 ANIM_Twink_Still,
459 ANIM_Twink_Idle,
460 ANIM_Twink_Idle,
461 ANIM_Twink_Idle,
462 ANIM_Twink_Idle,
463 ANIM_Twink_Idle,
464 ANIM_Twink_Idle,
465 ANIM_Twink_Talk,
466 ANIM_Twink_Hurt
467 }},
468};
469
471 world_use_item_ROM_START,
472 world_use_item_ROM_END,
474 0
475};
476
478
479s32 use_consumable(s32 invSlot) {
480 Evt* script;
481
482 D_8010CD20 = invSlot;
483 invSlot = gPlayerData.invItems[invSlot];
486 script->varTable[10] = invSlot;
487 return script->id;
488}
489
491 gPlayerData.invItems[D_8010CD20] = ITEM_NONE;
493}
494
495f32 D_800F84F8 = 0.0f;
496
497s32 func_800EA4B0(s32 collisionID) {
498 s32 ret = TRUE;
499
500 if (collisionID >= 0) {
501 if (collisionID & COLLISION_WITH_ENTITY_BIT) {
502 switch (get_entity_type(collisionID)) {
516 case ENTITY_TYPE_3B:
518 ret = FALSE;
519 break;
520 default:
521 ret = TRUE;
522 break;
523 }
524 }
525 }
526 return ret;
527}
528
532
534 return TRUE;
535}
536
537s32 func_800EA52C(s32 partnerID) {
538 PlayerStatus* playerStatus = &gPlayerStatus;
539 u32 playerActionState = playerStatus->actionState;
540 s32 ret = FALSE;
541
542 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
543 return FALSE;
544 }
545
546 // any partner
547 if (playerActionState == ACTION_STATE_IDLE
548 || playerActionState == ACTION_STATE_WALK
549 || playerActionState == ACTION_STATE_RUN
550 ) {
551 ret = TRUE;
552 }
553
554 // check specific partners
555 if (partnerID == PARTNER_BOW) {
556 if (playerActionState == ACTION_STATE_RIDE) {
557 ret = TRUE;
558 }
559 } else if (partnerID == PARTNER_PARAKARRY) {
560 if (playerActionState == ACTION_STATE_RIDE
561 || playerActionState == ACTION_STATE_IDLE
562 || playerActionState == ACTION_STATE_WALK
563 || playerActionState == ACTION_STATE_RUN
564 ) {
565 ret = TRUE;
566 }
567 }
568
569 return ret;
570}
571
573 return !wPartner->isFlying;
574}
575
580
582 WorldPartner* partnerEntry = &wPartners[wCurrentPartnerId];
583 Npc** partnerNpcPtr = &wPartnerNpc;
584 WorldPartner** partner = &wPartner;
585 s32 npcIndex;
586 NpcBlueprint blueprint;
587 NpcBlueprint* blueprintPtr;
588
589 *partner = partnerEntry;
590 blueprintPtr = &blueprint;
591 dma_copy(partnerEntry->dmaStart, partnerEntry->dmaEnd, partnerEntry->dmaDest);
592
594 blueprint.initialAnim = (*partner)->idle;
595 blueprint.onUpdate = NULL;
596 blueprint.onRender = NULL;
597 wPartnerNpcIndex = npcIndex = create_basic_npc(blueprintPtr);
598
599 *partnerNpcPtr = get_npc_by_index(npcIndex);
600
601 {
602 Npc* npc = *partnerNpcPtr;
603 npc->npcID = NPC_PARTNER;
604 npc->collisionDiameter = 10;
605 npc->collisionHeight = 10;
606 }
607
608 {
609 Npc* npc = *partnerNpcPtr;
610 npc->pos.x = NPC_DISPOSE_POS_X;
611 npc->pos.y = NPC_DISPOSE_POS_Y;
612 npc->pos.z = NPC_DISPOSE_POS_Z;
613 npc->scale.x = 0.0f;
614 npc->scale.y = 0.0f;
615 npc->scale.z = 0.0f;
616 }
617
619}
620
624
626 static u32 PartnerCommand; // goes into BSS, needs to be static for the function to match
627
628 PlayerData* playerData = &gPlayerData;
629 PartnerStatus* partnerStatus = &gPartnerStatus;
630 PlayerStatus* playerStatus = &gPlayerStatus;
631
632 if (partnerStatus->inputDisabledCount == 0) {
638 } else {
639 partnerStatus->stickX = 0;
640 partnerStatus->stickY = 0;
641 partnerStatus->curButtons = 0;
642 partnerStatus->pressedButtons = 0;
643 partnerStatus->heldButtons = 0;
644 }
645
646 if (playerStatus->animFlags & PA_FLAG_INTERRUPT_USE_PARTNER) {
647 playerStatus->animFlags &= ~PA_FLAG_INTERRUPT_USE_PARTNER;
648 partnerStatus->pressedButtons |= BUTTON_B | BUTTON_C_DOWN;
650 }
651
653 PartnerCommand = NextPartnerCommand;
656 }
657
658 if (PartnerCommand >= PARTNER_CMD_INSTA_SWITCH) {
659#if VERSION_JP
660 D_8010CFC4 = 0;
661#else
662 if (PartnerCommand != PARTNER_CMD_USE_ABILITY) {
663 D_8010CFC4 = 0;
664 }
665#endif
666 }
667
668 switch (PartnerCommand) {
669 case PARTNER_CMD_NONE:
670 break;
672 D_8010CFC4 = 3;
673 switch (PartnerCommandState) {
674 case 0: // put away current partner
684 break;
685 case 1: // free old partner and create new one
687 break;
688 }
696 // fallthrough
697 case 2: // take out new partner
704 break;
705 case 3: // resume normal partner behaviour
707 break;
708 }
713 PartnerCommand = PARTNER_CMD_INIT;
716 break;
717 }
718 break;
720 D_8010CFC4 = 3;
721 switch (PartnerCommandState) {
722 case 0:
725 case 1:
732 wPartnerNpc->jumpVel = 0.0f;
733 wPartnerNpc->scale.x = 1.0f;
734 wPartnerNpc->scale.y = 1.0f;
735 wPartnerNpc->scale.z = 1.0f;
738 // fallthrough
739 case 2:
741 break;
742 case 3:
747 PartnerCommand = PARTNER_CMD_INIT;
748 break;
749 }
750 break;
752 switch (PartnerCommandState) {
753 case 0: // put away current partner
762 break;
763 case 1: // free old partner and resume game
765 break;
766 }
768 PartnerCommand = PARTNER_CMD_INIT;
771 break;
772 }
773 break;
775 if (PartnerCommandState == 0) {
778 PartnerCommand = PARTNER_CMD_INIT;
780 break;
781 }
782 break;
784 switch (PartnerCommandState) {
785 case 0: // create the new partner
791 // fallthrough
792 case 1: // take out new partner
798 break;
799 case 2: // resume standard partner behaviour
801 break;
802 }
807 PartnerCommand = PARTNER_CMD_INIT;
809 break;
810 }
811 break;
813 D_8010CFC4 = 2;
814 switch (PartnerCommandState) {
815 case 0:
822 wPartnerNpc->jumpVel = 0.0f;
823 wPartnerNpc->scale.x = 1.0f;
824 wPartnerNpc->scale.y = 1.0f;
825 wPartnerNpc->scale.z = 1.0f;
828 break;
829 case 1:
834 PartnerCommand = PARTNER_CMD_INIT;
837 break;
838 }
839 break;
841 switch (PartnerCommandState) {
842 case 0:
849 break;
850 case 1:
852 break;
853 }
858 PartnerCommand = PARTNER_CMD_INIT;
859 break;
860 }
861 break;
863 D_8010CFC4 = 1;
864 switch (PartnerCommandState) {
865 case 0:
869 // fallthrough
870 case 1:
872 break;
873 case 2:
874 if (partnerStatus->partnerActionState != 1) {
875 wSavedPartnerPosX = playerStatus->pos.x;
876 wSavedPartnerPosY = playerStatus->pos.y;
877 wSavedPartnerPosZ = playerStatus->pos.z;
882 }
884 PartnerCommand = PARTNER_CMD_INIT;
885 break;
886 }
887 break;
889 if (PartnerCommandState == 0) {
892 }
894 }
895 break;
896 case PARTNER_CMD_INIT:
897 PartnerCommand = PARTNER_CMD_NONE;
898 D_8010CFE0 = 0;
899 if (D_8010CFC4 != 3) {
900 D_8010CFC4 = 0;
901 }
902 break;
903 }
904}
905
906void switch_to_partner(s32 partnerID) {
907 PlayerStatus* playerStatus = &gPlayerStatus;
908
909 if (wCurrentPartnerId != partnerID) {
910 D_8010CFE0 = 1;
911 NextPartnerID = partnerID;
912
913 if (wCurrentPartnerId != PARTNER_NONE && partnerID != PARTNER_NONE) {
915 } else if (partnerID == PARTNER_NONE) {
917 } else {
919 wSavedPartnerPosX = playerStatus->pos.x;
920 wSavedPartnerPosY = playerStatus->pos.y;
921 wSavedPartnerPosZ = playerStatus->pos.z;
922 }
923 }
924}
925
926void partner_init_after_battle(s32 partnerID) {
927 PlayerStatus* playerStatus = &gPlayerStatus;
928 PartnerStatus* partnerStatus = &gPartnerStatus;
929
930 if (wCurrentPartnerId != partnerID) {
931 D_8010CFE0 = 1;
932 NextPartnerID = partnerID;
933 partnerStatus->partnerActionState = 0;
934 partnerStatus->shouldResumeAbility = FALSE;
935
936 if (wCurrentPartnerId != PARTNER_NONE && partnerID != PARTNER_NONE) {
938 } else if (partnerID == PARTNER_NONE) {
940 } else {
942 wSavedPartnerPosX = playerStatus->pos.x;
943 wSavedPartnerPosY = playerStatus->pos.y;
944 wSavedPartnerPosZ = playerStatus->pos.z;
945 }
946 }
947}
948
949void func_800EB2A4(s32 partnerID) {
950 if (wCurrentPartnerId != partnerID) {
951 D_8010CFE0 = 1;
952 NextPartnerID = partnerID;
953
954 if (wCurrentPartnerId != PARTNER_NONE && partnerID != PARTNER_NONE) {
956 } else if (partnerID == PARTNER_NONE) {
958 } else {
960 }
961 }
962}
963
965 PartnerStatus* partnerStatus = &gPartnerStatus;
966
968 && wPartner != NULL
970 {
971 if (gGameStatusPtr->multiplayerEnabled && (partnerStatus->curButtons & BUTTON_B)) {
973 } else if (wCurrentPartnerId != PARTNER_NONE) {
974 D_8010CFE0 = 1;
977 return TRUE;
978 }
979 }
980 return FALSE;
981}
982
984 if (wPartner != NULL
985 && wPartner->canPlayerOpenMenus != NULL
987 ) {
988 return FALSE;
989 }
990 return TRUE;
991}
992
995 return TRUE;
996 }
997 return FALSE;
998}
999
1001 PlayerStatus* playerStatus = &gPlayerStatus;
1002 s32 currentPartner = gPlayerData.curPartner;
1003
1006
1007 D_8010CFE0 = 1;
1009 wCurrentPartnerId = currentPartner;
1010
1014 }
1015
1016 wPartner = NULL;
1017 wSavedPartnerPosX = playerStatus->pos.x;
1018 wSavedPartnerPosY = playerStatus->pos.y;
1019 wSavedPartnerPosZ = playerStatus->pos.z;
1020
1023 } else {
1025 wPartnerNpc->scale.x = 1.0f;
1026 wPartnerNpc->scale.y = 1.0f;
1027 wPartnerNpc->scale.z = 1.0f;
1029 }
1030}
1031
1033 PartnerStatus* partnerStatus = &gPartnerStatus;
1034
1036 D_8010CFE0 = 0;
1038 D_8010CFC4 = 0;
1039 partnerStatus->actingPartner = 0;
1040 partnerStatus->inputDisabledCount = 0;
1041 partnerStatus->shouldResumeAbility = FALSE;
1042 partnerStatus->partnerActionState = 0;
1043 partnerStatus->unk_358 = 0;
1044 partnerStatus->partnerAction_unk_2 = FALSE;
1045 wPartner = NULL;
1049}
1050
1053 return wPartner->testFirstStrike(wPartnerNpc, enemy);
1054 }
1055 return FALSE;
1056}
1057
1059 WorldPartner* partner = wPartner;
1060
1061 if (partner == NULL) {
1062 return NULL;
1063 }
1064 return partner->onEnterMap;
1065}
1066
1069 s32* scriptID = &wPartnerCurrentScriptID;
1070
1071 if (does_script_exist(*scriptID)) {
1072 kill_script_by_ID(*scriptID);
1073 }
1074
1075 if (wPartner->preBattle != NULL) {
1077 }
1078 }
1079}
1080
1082 PartnerStatus* partnerStatus = &gPartnerStatus;
1083 PlayerData* playerData = &gPlayerData;
1084
1088 }
1089
1094
1096
1097 if (playerData->curPartner != PARTNER_WATT && partnerStatus->actingPartner == PARTNER_WATT) {
1098 gPlayerStatusPtr->animFlags &= ~PA_FLAG_USING_WATT;
1099 gPlayerStatusPtr->animFlags &= ~PA_FLAG_WATT_IN_HANDS;
1100 partnerStatus->actingPartner = PARTNER_NONE;
1101 }
1102
1103 if (wPartner->postBattle != NULL) {
1105 }
1106 }
1107}
1108
1116
1124
1132
1133void partner_walking_enable(Npc* partner, s32 val) {
1134 PlayerStatus* playerStatus = &gPlayerStatus;
1136 s32 i;
1137
1138 partner->pos.x = wSavedPartnerPosX;
1139 partner->pos.y = wSavedPartnerPosY;
1140 partner->pos.z = wSavedPartnerPosZ;
1141
1142 for (i = 0; i < ARRAY_COUNT(gPlayerMoveHistory); i++, it++) {
1143 it->pos.x = playerStatus->pos.x;
1144 it->pos.y = playerStatus->pos.y;
1145 it->pos.z = playerStatus->pos.z;
1146 it->isJumping = FALSE;
1147 }
1148
1150 D_8010CFBC = 0;
1151 D_8010CFCA = val ? 2 : 0;
1153
1154 if (D_8010CFC4 == 1 || D_8010CFC4 == 3) {
1155 D_8010CFC4 = 0;
1156 D_8010CFCA = 0;
1158 } else if (D_8010CFC4 == 2) {
1159 D_8010CFCA = 0;
1161 }
1162
1163 D_8010CFCE = 0;
1164 D_8010CFCC = 0;
1165 wPartnerMoveTime = 16;
1166 wPartnerTetherDistance = 40.0f;
1168 func_800EA5B8(partner);
1170 partner->jumpVel = 0.0f;
1172 partner->jumpScale = 1.8f;
1173}
1174
1176 PlayerStatus* playerStatus = &gPlayerStatus;
1177 s32 isPlayerJumping;
1178 PlayerPathElement* currentSnapshot;
1179
1180 if (playerStatus->flags & (PS_FLAG_FALLING | PS_FLAG_JUMPING)) {
1181 isPlayerJumping = (playerStatus->actionState == ACTION_STATE_LAND || playerStatus->actionState == ACTION_STATE_STEP_DOWN) ^ 1;
1182 } else {
1183 isPlayerJumping = FALSE;
1184 }
1185 currentSnapshot = &gPlayerMoveHistory[gPlayerMoveHistoryIndex];
1186 if ((!currentSnapshot->isJumping || !isPlayerJumping) &&
1187 ((currentSnapshot->pos.x != playerStatus->pos.x) || (currentSnapshot->pos.y != playerStatus->pos.y)
1188 || (currentSnapshot->pos.z != playerStatus->pos.z))) {
1192 }
1193 currentSnapshot = &gPlayerMoveHistory[gPlayerMoveHistoryIndex];
1194 currentSnapshot->pos.x = playerStatus->pos.x;
1195 currentSnapshot->pos.y = playerStatus->pos.y;
1196 currentSnapshot->pos.z = playerStatus->pos.z;
1197 currentSnapshot->isJumping = isPlayerJumping;
1198 }
1199 }
1200}
1201
1203 PlayerStatus* playerStatus = &gPlayerStatus;
1204 PartnerStatus* partnerStatus = &gPartnerStatus;
1205
1207 || partnerStatus->inputDisabledCount != 0 || partnerStatus->partnerAction_unk_2) {
1208 if (!(playerStatus->animFlags & PA_FLAG_OPENED_HIDDEN_PANEL)) {
1210 }
1211 if (partnerStatus->pressedButtons & (BUTTON_Z | BUTTON_B | BUTTON_C_LEFT | BUTTON_C_DOWN)) {
1212 partnerStatus->partnerAction_unk_2 = FALSE;
1213 }
1214 }
1215
1216 if (wPartnerFollowState != 50 && fabsf(partner->pos.y - playerStatus->pos.y) > 1000.0f) {
1217 partner->pos.x = playerStatus->pos.x;
1218 partner->pos.y = playerStatus->pos.y;
1219 partner->pos.z = playerStatus->pos.z;
1220 partner->jumpVel = 0.0f;
1221 partner->jumpScale = 0.0f;
1222 partner->flags = partner->flags & ~PA_FLAG_OPENED_HIDDEN_PANEL;
1223 }
1224
1226 wSavedPartnerPosX = partner->pos.x;
1227 wSavedPartnerPosY = partner->pos.y;
1228 wSavedPartnerPosZ = partner->pos.z;
1229}
1230
1232 PlayerStatus* playerStatus = &gPlayerStatus;
1233 Camera* cameras = &gCameras[CAM_DEFAULT];
1234 s32 surfaceType;
1235 f32 moveHistoryX, moveHistoryY, moveHistoryZ;
1236 f32 x, y, z;
1237 f32 distance;
1238 f32 yaw;
1239 f32 temp_a3;
1240 f32 angle;
1241 s32 var_a1;
1242 PlayerPathElement* currentSnapshot;
1243
1244 switch (wPartnerFollowState) {
1245 case 0:
1246 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1247 moveHistoryX = currentSnapshot->pos.x;
1248 moveHistoryZ = currentSnapshot->pos.z;
1249 x = partner->pos.x;
1250 y = partner->pos.y;
1251 z = partner->pos.z;
1252 partner->moveSpeed = 3.0f;
1253
1254 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1255 if (distance >= 50.0) {
1256 partner->moveSpeed = !(playerStatus->animFlags & PA_FLAG_SPINNING) ? 5.0f : 7.0f;
1257 }
1258 if (wPartnerTetherDistance < 20.0) {
1259 partner->moveSpeed = 4.0f;
1260 }
1262 if (!(partner->flags & NPC_FLAG_GROUNDED)) {
1264 }
1265 while (TRUE) {
1266 distance = dist2D(x, z, moveHistoryX, moveHistoryZ);
1267 yaw = atan2(x, z, moveHistoryX, moveHistoryZ);
1268 if (partner->moveSpeed < distance) {
1269 distance = dist2D(x, z, playerStatus->pos.x, playerStatus->pos.z);
1270 if (distance >= 50.0) {
1271 break;
1272 }
1273 if (wPartnerTetherDistance < distance) {
1274 partner->moveSpeed = distance - wPartnerTetherDistance;
1275 if (partner->moveSpeed > 3.0) {
1276 partner->moveSpeed = 3.0f;
1277 if (wPartnerTetherDistance < 20.0f) {
1278 partner->moveSpeed = 4.0f;
1279 }
1280 } else {
1281 partner->moveSpeed += 1.0;
1282 }
1283 break;
1284 } else {
1285 partner->moveSpeed = 0.0f;
1286 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1287 }
1288 }
1290 yaw = partner->yaw;
1291 partner->moveSpeed = 0.0f;
1292 partner->jumpScale = 0.0f;
1295 break;
1296 } else {
1297 D_8010CFBC++;
1298 if (D_8010CFBC >= 40) {
1299 D_8010CFBC = 0;
1300 }
1301 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1302 moveHistoryX = currentSnapshot->pos.x;
1303 moveHistoryZ = currentSnapshot->pos.z;
1304
1305 if (fabsf(get_clamped_angle_diff(partner->yaw, atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ))) > 90.0f) {
1307 break;
1308 }
1309
1310 if ((partner->flags & NPC_FLAG_GROUNDED) && currentSnapshot->isJumping) {
1312 break;
1313 }
1314 }
1315 }
1316
1317 if (!(partner->flags & NPC_FLAG_GROUNDED)) {
1318 partner->moveSpeed *= 0.5f;
1319 }
1320 partner->yaw = yaw;
1321 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
1323 surfaceType = get_collider_flags(partner->curFloor);
1324 if (surfaceType == SURFACE_TYPE_SPIKES
1325 || surfaceType == SURFACE_TYPE_LAVA
1326 || ((partner->flags & NPC_FLAG_GROUNDED) && (partner->flags & NPC_FLAG_COLLDING_FORWARD_WITH_WORLD))
1327 ) {
1328 if (!func_800EA4B0(partner->curWall)) {
1329 D_8010CFBC++;
1330 if (D_8010CFBC >= 40) {
1331 D_8010CFBC = 0;
1332 }
1333 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1334 moveHistoryX = currentSnapshot->pos.x;
1335 moveHistoryZ = currentSnapshot->pos.z;
1336 if (fabsf(get_clamped_angle_diff(partner->yaw, atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ))) > 90.0f) {
1338 return;
1339 }
1340 } else {
1342 return;
1343 }
1344 }
1345 break;
1346 case 1:
1347 surfaceType = get_collider_flags(partner->curFloor);
1349 if (surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) {
1350 moveHistoryX = partner->pos.x;
1351 moveHistoryY = playerStatus->pos.y;
1352 moveHistoryZ = partner->pos.z;
1353 add_vec2D_polar(&moveHistoryX, &moveHistoryZ, 6.0f, atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z));
1354 } else {
1355 break;
1356 }
1357 } else {
1358 D_8010CFBC++;
1359 if (D_8010CFBC >= 40) {
1360 D_8010CFBC = 0;
1361 }
1362 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1363 moveHistoryX = currentSnapshot->pos.x;
1364 moveHistoryY = currentSnapshot->pos.y;
1365 moveHistoryZ = currentSnapshot->pos.z;
1366 }
1367 partner->moveToPos.x = moveHistoryX;
1368 partner->moveToPos.y = moveHistoryY;
1369 partner->moveToPos.z = moveHistoryZ;
1370 partner->duration = 0;
1371 partner->jumpScale = 3.0f;
1372 partner->moveSpeed = 6.0f;
1373 partner->planarFlyDist = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1374 partner->yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1375 if (partner->planarFlyDist > 50.0) {
1376 partner->planarFlyDist = 50.0f;
1377 }
1378 distance = partner->planarFlyDist;
1379 y = partner->moveToPos.y - partner->pos.y;
1380 if (distance < wPartnerTetherDistance && !(surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA)) {
1381 partner->jumpVel = 0.0f;
1382 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1384 return;
1385 }
1386 partner->duration = distance / partner->moveSpeed;
1387 if (partner->duration < 10) {
1388 partner->duration = 10;
1389 }
1390 partner->moveSpeed = partner->planarFlyDist / partner->duration;
1391 partner->jumpVel = (y + partner->jumpScale * partner->duration * partner->duration * 0.5f) / partner->duration;
1392 if (partner->jumpVel > 20.0) {
1393 partner->jumpVel = 20.0f;
1394 }
1395 if (partner->jumpVel < 0.0) {
1396 partner->jumpVel = 0.0f;
1397 }
1398 if (!(surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA)) {
1400 } else {
1402 }
1403
1404 partner->moveToPos.x = partner->pos.x;
1405 partner->moveToPos.y = partner->pos.y;
1406 partner->moveToPos.z = partner->pos.z;
1407 partner->flags |= NPC_FLAG_JUMPING;
1409 // fallthrough
1410 case 2:
1411 partner->jumpVel -= partner->jumpScale;
1412 partner->pos.y += partner->jumpVel;
1413 if (partner->jumpVel <= 0.0f) {
1415 }
1416 if (partner->pos.y < -2000.0f) {
1418 partner->flags &= ~NPC_FLAG_JUMPING;
1419 partner->jumpVel = 0.0f;
1420 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1421 partner->pos.x = playerStatus->pos.x;
1422 partner->pos.y = playerStatus->pos.y;
1423 partner->pos.z = playerStatus->pos.z;
1425 return;
1426 }
1427 if (partner->jumpVel <= 0.0f) {
1428 distance = fabsf(partner->jumpVel) + 11.0f;
1429 x = partner->pos.x;
1430 y = partner->pos.y + distance;
1431 z = partner->pos.z;
1432 if (npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) != 0) {
1433 if (distance <= fabsf(partner->jumpVel) + 22.0f) {
1435 partner->flags &= ~NPC_FLAG_JUMPING;
1436 partner->jumpVel = 0.0f;
1437 partner->pos.y = y;
1438 partner->yaw = atan2(x, z, playerStatus->pos.x, playerStatus->pos.z);
1441 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1442 if (distance < 5.0) {
1443 partner->pos.x = playerStatus->pos.x;
1444 partner->pos.y = playerStatus->pos.y;
1445 partner->pos.z = playerStatus->pos.z;
1446 add_vec2D_polar(&partner->pos.x, &partner->pos.z, 5.0f, clamp_angle((cameras[CAM_DEFAULT].curYaw + 90.0f) - playerStatus->spriteFacingAngle));
1448 }
1449 break;
1450 }
1451 }
1452 }
1453 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
1454 break;
1455 case 5:
1456 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1457 moveHistoryX = currentSnapshot->pos.x;
1458 moveHistoryZ = currentSnapshot->pos.z;
1459 x = partner->pos.x;
1460 y = partner->pos.y;
1461 z = partner->pos.z;
1462 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1463 if (distance <= wPartnerTetherDistance) {
1464 if (D_8010CFCA == 0) {
1465 partner->moveSpeed = 0.0f;
1466 partner->jumpScale = 0.0f;
1468 if (playerStatus->actionState == ACTION_STATE_TALK) {
1469 D_8010CFCA = 0;
1470 }
1471 surfaceType = get_collider_flags(partner->curFloor);
1472 if (surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) {
1474 return;
1475 }
1476 } else {
1477 temp_a3 = clamp_angle(cameras[CAM_DEFAULT].curYaw + (playerStatus->spriteFacingAngle < 180.0f ? 90.0f : -90.0f));
1478 partner->moveToPos.x = playerStatus->pos.x;
1479 partner->moveToPos.y = playerStatus->pos.y;
1480 partner->moveToPos.z = playerStatus->pos.z;
1481 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, wPartnerTetherDistance - 10.0f, temp_a3);
1482 yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1483 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1484 partner->moveSpeed = 2.0f;
1485 if (distance > 2.0f) {
1486 partner->yaw = yaw;
1488 if (!(partner->flags & NPC_FLAG_COLLDING_FORWARD_WITH_WORLD)) {
1489 D_800F803A = 0;
1490 } else {
1491 D_800F803A++;
1492 if (D_800F803A > 10) {
1493 yaw = playerStatus->targetYaw;
1494 partner->moveSpeed = 0.0f;
1495 partner->jumpScale = 0.0f;
1496 partner->renderYaw = yaw;
1498 if (D_8010CFCA == 2 || playerStatus->actionState == ACTION_STATE_TALK) {
1499 D_8010CFCA = 0;
1500 }
1501 }
1502 }
1503 } else {
1504 yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1505 partner->yaw = yaw;
1506 partner->moveSpeed = 0.0f;
1507 partner->jumpScale = 0.0f;
1509 if (D_8010CFCA == 2 || playerStatus->actionState == ACTION_STATE_TALK) {
1510 D_8010CFCA = 0;
1511 }
1512 }
1513 partner->yaw = yaw;
1514 npc_move_heading(partner, partner->moveSpeed, yaw);
1516 distance = 1000.0f;
1517 x = partner->pos.x;
1518 z = partner->pos.z;
1519 y = partner->pos.y + partner->collisionHeight;
1520 if (npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) != 0) {
1521 s32 surfaceType = get_collider_flags(NpcHitQueryColliderID);
1522 if (surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) {
1523 partner->yaw = clamp_angle(yaw + 180.0f);
1524 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
1525 partner->moveSpeed = 0.0f;
1526 partner->jumpScale = 0.0f;
1528 if (D_8010CFCA == 2) {
1529 D_8010CFCA = 0;
1530 } else if (playerStatus->actionState == ACTION_STATE_TALK) {
1531 D_8010CFCA = 0;
1532 }
1533 } else if (!func_800EA4B0(NpcHitQueryColliderID)) {
1534 D_8010CFCA = 2;
1535 }
1536 }
1537 break;
1538 }
1539 }
1540 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1541 if (distance <= wPartnerTetherDistance) {
1543 D_8010CFCA = 2;
1544 }
1545 } else {
1546 while (TRUE) {
1547 if (currentSnapshot->isJumping) {
1548 break;
1549 }
1550 yaw = atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ);
1551 if (fabsf(get_clamped_angle_diff(yaw, atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z))) < 90.0f) {
1552 break;
1553 }
1555 break;
1556 }
1557 D_8010CFBC++;
1558 if (D_8010CFBC >= 40) {
1559 D_8010CFBC = 0;
1560 }
1561 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1562 moveHistoryX = currentSnapshot->pos.x;
1563 moveHistoryZ = currentSnapshot->pos.z;
1564 }
1565 if (!currentSnapshot->isJumping) {
1567 return;
1568 }
1569 while (TRUE) {
1570 if (!currentSnapshot->isJumping) {
1571 break;
1572 }
1573 yaw = atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ);
1574 if (fabsf(get_clamped_angle_diff(yaw, atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z))) < 90.0f) {
1575 break;
1576 }
1578 break;
1579 }
1580 D_8010CFBC++;
1581 if (D_8010CFBC >= 40) {
1582 D_8010CFBC = 0;
1583 }
1584 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1585 moveHistoryX = currentSnapshot->pos.x;
1586 moveHistoryZ = currentSnapshot->pos.z;
1587 }
1589 return;
1590 }
1591 break;
1592 case 15:
1593 switch (D_8010CFCE) {
1594 case 0:
1595 angle = clamp_angle(player_get_side_angle() + 180.0f);
1596 partner->moveToPos.x = playerStatus->pos.x;
1597 partner->moveToPos.y = playerStatus->pos.y;
1598 partner->moveToPos.z = playerStatus->pos.z;
1599 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, playerStatus->colliderDiameter, angle);
1600 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1602 partner->moveSpeed = wPartnerMoveSpeed;
1604 yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1605 partner->yaw = D_800F8034 = yaw;
1606 D_8010CFCE++;
1607 // fallthrough
1608 case 1:
1609 if (wPartnerMoveTime != 0) {
1611 if (partner->jumpScale != 0.0f) {
1612 partner->jumpVel -= partner->jumpScale;
1613 partner->pos.y += partner->jumpVel;
1614 if (partner->jumpVel <= 0.0f) {
1616 }
1617 if (partner->jumpVel <= 0.0f) {
1618 distance = fabsf(partner->jumpVel) + 11.0f;
1619 x = partner->pos.x;
1620 y = partner->pos.y + distance;
1621 z = partner->pos.z;
1622 if ((npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) != 0) && (distance <= (fabsf(partner->jumpVel) + 22.0f))) {
1624 partner->jumpScale = 0.0f;
1625 partner->jumpVel = 0.0f;
1626 partner->pos.y = y;
1627 partner->flags &= ~NPC_FLAG_JUMPING;
1628 }
1629 }
1630 }
1631 partner->moveSpeed = wPartnerMoveSpeed;
1632 partner->yaw = D_800F8034;
1633 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
1635 } else {
1637 partner->moveSpeed = 0.0f;
1638 partner->jumpScale = 0.0f;
1640 partner->yaw = clamp_angle((cameras[CAM_DEFAULT].curYaw + 270.0f) - playerStatus->spriteFacingAngle);
1641 wPartnerMoveTime = 30;
1642 D_8010CFCE++;
1643 }
1644 return;
1645 case 2:
1646 if (wPartnerMoveTime != 0) {
1648 return;
1649 }
1651 D_8010CFCA = 0;
1652 D_8010CFCE = 0;
1653 }
1654 break;
1655 case 20:
1656 partner_move_to_goal(partner, FALSE);
1657 break;
1658 case 40:
1659 if (partner->flags & NPC_FLAG_GROUNDED) {
1660 if (func_800EA4B0(partner->curFloor)) {
1663 } else {
1665 }
1666 break;
1667 }
1668 partner->jumpScale = 3.0f;
1669 partner->jumpVel -= partner->jumpScale;
1670 partner->pos.y += partner->jumpVel;
1671 if (partner->jumpVel <= 0.0f) {
1673 }
1674 if (partner->pos.y < -2000.0f) {
1676 partner->flags &= ~NPC_FLAG_JUMPING;
1677 partner->jumpVel = 0.0f;
1678 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1679 partner->pos.x = playerStatus->pos.x;
1680 partner->pos.y = playerStatus->pos.y;
1681 partner->pos.z = playerStatus->pos.z;
1683 return;
1684 }
1685 distance = fabsf(partner->jumpVel) + 11.0f;
1686 x = partner->pos.x;
1687 y = partner->pos.y + distance;
1688 z = partner->pos.z;
1689 if (npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) != 0) {
1691 partner->flags &= ~NPC_FLAG_JUMPING;
1692 partner->jumpVel = 0.0f;
1693 partner->pos.y = y;
1694 partner->yaw = atan2(x, z, playerStatus->pos.x, playerStatus->pos.z);
1697 }
1698 break;
1699 case 50:
1700 break;
1701 }
1702}
1703
1704static const f32 padding = 0.0f;
1705
1706void partner_flying_enable(Npc* partner, s32 val) {
1707 PlayerStatus* playerStatus = &gPlayerStatus;
1709 s32 i;
1710
1711 partner->pos.x = wSavedPartnerPosX;
1712 partner->pos.y = wSavedPartnerPosY;
1713 partner->pos.z = wSavedPartnerPosZ;
1714
1715 for (i = 0; i < ARRAY_COUNT(gPlayerMoveHistory); i++, it++) {
1716 it->pos.x = wSavedPartnerPosX;
1717 it->pos.y = wSavedPartnerPosY;
1718 it->pos.z = wSavedPartnerPosZ;
1719 it->isJumping = FALSE;
1720 }
1721
1723 D_8010CFBC = 0;
1724
1725 if (!val) {
1727 D_8010CFCA = 0;
1728 } else if (D_8010CFC4 == 0) {
1730 D_8010CFCA = 2;
1731 } else if (D_8010CFC4 == 1 || D_8010CFC4 == 3) {
1732 D_8010CFC4 = 0;
1734 D_8010CFCA = 0;
1735 } else if (D_8010CFC4 == 2) {
1737 D_8010CFCA = 0;
1738 }
1739
1740 D_8010CFCE = 0;
1741 D_8010CFCC = 0;
1742 wPartnerMoveTime = 16;
1743 wPartnerTetherDistance = 40.0f;
1745 func_800EA5B8(partner);
1748 partner->flags &= ~NPC_FLAG_GRAVITY;
1749}
1750
1752 PlayerStatus* playerStatus = &gPlayerStatus;
1753 PlayerPathElement* currentSnapshot;
1754 f32 effectiveY;
1755 s32 isPlayerJumping = FALSE;
1756
1757 effectiveY = playerStatus->pos.y;
1758 if ((playerStatus->actionState == ACTION_STATE_HIT_LAVA) || (playerStatus->actionState == ACTION_STATE_HIT_FIRE)) {
1759 effectiveY = playerStatus->lastGoodPos.y + partner->collisionHeight + 5;
1760 }
1761 currentSnapshot = &gPlayerMoveHistory[gPlayerMoveHistoryIndex];
1762 if ((!currentSnapshot->isJumping || !isPlayerJumping) && (currentSnapshot->pos.x != playerStatus->pos.x || currentSnapshot->pos.y != effectiveY
1763 || currentSnapshot->pos.z != playerStatus->pos.z)) {
1767 }
1768 currentSnapshot = &gPlayerMoveHistory[gPlayerMoveHistoryIndex];
1769 currentSnapshot->pos.x = playerStatus->pos.x;
1770 currentSnapshot->pos.y = effectiveY;
1771 currentSnapshot->pos.z = playerStatus->pos.z;
1772 currentSnapshot->isJumping = isPlayerJumping;
1773 }
1774 }
1775}
1776
1778 PlayerStatus* playerStatus = &gPlayerStatus;
1779 PartnerStatus* partnerStatus = &gPartnerStatus;
1780 f32 x, y, z, hitDepth;
1781 f32 var_f0;
1782 f32 var_f2;
1783
1786 partnerStatus->inputDisabledCount ||
1787 partnerStatus->partnerAction_unk_2)
1788 {
1789 if (!(playerStatus->animFlags & PA_FLAG_OPENED_HIDDEN_PANEL) || D_800F8020 == 0) {
1791 }
1792 if (partnerStatus->pressedButtons & (BUTTON_B | BUTTON_Z | BUTTON_C_DOWN | BUTTON_C_LEFT)) {
1793 partnerStatus->partnerAction_unk_2 = FALSE;
1794 }
1795 }
1796 if (wPartnerFollowState != 50 && fabsf(partner->pos.y - playerStatus->pos.y) > 1000.0f) {
1797 partner->pos.x = playerStatus->pos.x;
1798 partner->pos.y = playerStatus->pos.y;
1799 partner->pos.z = playerStatus->pos.z;
1800 partner->jumpVel = 0.0f;
1801 partner->jumpScale = 0.0f;
1802 partner->flags &= ~NPC_FLAG_JUMPING;
1803 }
1804
1805 D_800F8020 = 0;
1806 x = partner->pos.x;
1807 y = partner->pos.y + (partner->collisionHeight * 0.5f);
1808 z = partner->pos.z;
1809
1810 hitDepth = partner->collisionHeight * 0.5f;
1811 if (npc_raycast_up(0, &x, &y, &z, &hitDepth)) {
1812 D_800F8020 = 1;
1813 wSavedPartnerPosX = partner->pos.x;
1814 wSavedPartnerPosY = partner->pos.y;
1815 wSavedPartnerPosZ = partner->pos.z;
1816 } else {
1818 if (wPartnerFollowState != 50) {
1819 x = partner->pos.x;
1820 y = partner->pos.y;
1821 z = partner->pos.z;
1822 hitDepth = 1000.0f;
1823 if (npc_raycast_down_around(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &hitDepth, partner->yaw, partner->collisionDiameter) == 0) {
1824 y = playerStatus->pos.y;
1825 }
1826
1827 if (partner->pos.y <= y + partner->collisionHeight + 2.0f) {
1828 if (playerStatus->curSpeed != 0.0f) {
1829 D_800F84F8 = ((y + (partner->collisionHeight / 2) + 2.0f) - partner->pos.y) * 0.125f;
1830 } else {
1831 if (y < playerStatus->pos.y) {
1832 var_f0 = playerStatus->pos.y + 10.0f - partner->pos.y;
1833 } else {
1834 var_f0 = y + 10.0f - partner->pos.y;
1835 }
1836 var_f2 = 0.25f;
1837 D_800F84F8 = var_f0 * var_f2;
1838 }
1839 } else {
1840 if (playerStatus->pos.y + playerStatus->colliderHeight < y) {
1841 D_800F84F8 = (y + partner->collisionHeight - partner->pos.y) * 0.125f;
1842 if (partner->pos.y + D_800F84F8 <= y + partner->collisionHeight) {
1843 D_800F84F8 = (y + partner->collisionHeight - partner->pos.y) * 0.25f;
1844 }
1845 } else {
1846 var_f0 = (playerStatus->pos.y + playerStatus->colliderHeight + 5.0f) - partner->pos.y;
1847 var_f2 = 0.0625f;
1848 D_800F84F8 = var_f0 * var_f2;
1849 }
1850 }
1851 partner->pos.y += D_800F84F8;
1852 }
1853 wSavedPartnerPosX = partner->pos.x;
1854 wSavedPartnerPosY = partner->pos.y;
1855 wSavedPartnerPosZ = partner->pos.z;
1856 }
1857}
1858
1860 PlayerStatus* playerStatus = &gPlayerStatus;
1861 Camera* camera = &gCameras[CAM_DEFAULT];
1862 f32 x, y, z;
1863 f32 distance;
1864 f32 yaw;
1865 f32 temp_a3;
1866 f32 temp_f0_15;
1867 f32 var_f12;
1868 f32 moveHistoryX, moveHistoryY, moveHistoryZ;
1869 PlayerPathElement* currentSnapshot;
1870
1871 switch (wPartnerFollowState) {
1872 case 0:
1873 var_f12 = 0.0f;
1874 x = partner->pos.x;
1875 y = partner->pos.y;
1876 z = partner->pos.z;
1880 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1881 moveHistoryX = currentSnapshot->pos.x;
1882 moveHistoryY = currentSnapshot->pos.y;
1883 moveHistoryZ = currentSnapshot->pos.z;
1884 if (wPartnerTetherDistance < 20.0f) {
1885 var_f12 = (20.0f - wPartnerTetherDistance) * 0.5f;
1886 }
1887 partner->pos.y = y + (moveHistoryY + 20.0f + var_f12 - y) * 0.125f;
1888 partner->moveSpeed = 3.0f;
1889 y = partner->pos.y;
1890 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1891 if (distance >= 50.0) {
1892 if (partner->pos.y >= playerStatus->pos.y) {
1893 partner->moveSpeed = distance * 0.25f;
1894 } else {
1895 partner->moveSpeed = 8.0f;
1896 }
1897 }
1898 if (wPartnerTetherDistance < 20.0f) {
1899 partner->moveSpeed = 4.0f;
1900 }
1901
1902 while (TRUE) {
1903 yaw = atan2(x, z, moveHistoryX, moveHistoryZ);
1904 distance = dist2D(x, z, moveHistoryX, moveHistoryZ);
1905 if (partner->moveSpeed < distance) {
1906 if (partner->pos.y >= playerStatus->pos.y) {
1907 if (partner->moveSpeed >= distance * 0.25f) {
1908 partner->moveSpeed = distance * 0.25f;
1909 } else {
1910 partner->moveSpeed += distance * 0.0625f;
1911 }
1912 } else {
1913 if (partner->moveSpeed > 6.0) {
1914 partner->moveSpeed = 6.0f;
1915 } else {
1916 partner->moveSpeed += 1.0;
1917 }
1918 }
1919 break;
1920 }
1922 yaw = partner->yaw;
1923 partner->moveSpeed = 0.0f;
1924 partner->jumpScale = 0.0f;
1926 break;
1927 }
1928 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1929 if (distance <= wPartnerTetherDistance) {
1931 yaw = partner->yaw;
1932 partner->moveSpeed = 0.0f;
1933 partner->jumpScale = 0.0f;
1935 break;
1936 }
1937 D_8010CFBC++;
1938 if (D_8010CFBC >= 40) {
1939 D_8010CFBC = 0;
1940 }
1941 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1942 moveHistoryX = currentSnapshot->pos.x;
1943 moveHistoryZ = currentSnapshot->pos.z;
1944 }
1945 partner->yaw = yaw;
1946 npc_move_heading(partner, partner->moveSpeed, yaw);
1947 if (partner->flags & 0x4000) {
1949 return;
1950 }
1951 break;
1952 case 1:
1953 case 3:
1955 D_8010CFBC++;
1956 if (D_8010CFBC >= 40) {
1957 D_8010CFBC = 0;
1958 }
1959 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1960 moveHistoryX = currentSnapshot->pos.x;
1961 moveHistoryY = currentSnapshot->pos.y;
1962 moveHistoryZ = currentSnapshot->pos.z;
1963 partner->moveToPos.x = moveHistoryX;
1964 partner->moveToPos.y = moveHistoryY;
1965 partner->moveToPos.z = moveHistoryZ;
1966 partner->duration = 0;
1967 partner->jumpScale = 1.3f;
1968 if (wPartnerFollowState == 1) {
1969 partner->moveSpeed = 6.0f;
1970 }
1971 partner->planarFlyDist = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1972 partner->yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1973 if (partner->planarFlyDist > 50.0) {
1974 partner->planarFlyDist = 50.0f;
1975 }
1976 distance = partner->planarFlyDist;
1977 y = partner->moveToPos.y - partner->pos.y;
1978 if (partner->planarFlyDist < y) {
1979 distance = y;
1980 }
1981 if (wPartnerFollowState == 1) {
1982 if (distance < wPartnerTetherDistance) {
1983 partner->jumpVel = 0.0f;
1984 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1986 return;
1987 }
1988 partner->duration = distance / partner->moveSpeed;
1989 if (partner->duration < 10) {
1990 partner->duration = 10;
1991 }
1992 partner->moveSpeed = partner->planarFlyDist / partner->duration;
1993 } else {
1994 partner->duration = 10;
1995 }
1996
1997 partner->jumpVel = (y + (partner->jumpScale * partner->duration * partner->duration * 0.5f)) / partner->duration;
1998 if (partner->jumpVel > 20.0) {
1999 partner->jumpVel = 20.0f;
2000 }
2003 partner->moveToPos.x = partner->pos.x;
2004 partner->moveToPos.y = partner->pos.y;
2005 partner->moveToPos.z = partner->pos.z;
2006 }
2007 break;
2008 case 2:
2009 partner->jumpVel -= partner->jumpScale;
2010 partner->pos.y += partner->jumpVel;
2011 if (partner->jumpVel <= 0.0f) {
2013 }
2014 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
2015 if (partner->jumpVel <= 0.0f) {
2016 if (partner->pos.y < partner->moveToPos.y) {
2018 partner->jumpVel = 0.0f;
2019 partner->pos.y = partner->moveToPos.y;
2020 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
2022 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
2023 if (distance < wPartnerTetherDistance) {
2025 }
2026 }
2027 }
2028 break;
2029 case 5:
2030 x = partner->pos.x;
2031 y = partner->pos.y;
2032 z = partner->pos.z;
2033 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
2034 moveHistoryX = currentSnapshot->pos.x;
2035 moveHistoryZ = currentSnapshot->pos.z;
2036 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
2037 if (distance <= wPartnerTetherDistance) {
2038 if (D_8010CFCA == 0) {
2039 partner->pos.y = y + (((playerStatus->pos.y + (playerStatus->colliderHeight - partner->collisionHeight / 2)) - partner->pos.y) * 0.03125);
2040 y = partner->pos.y;
2041 partner->moveSpeed = 0.0f;
2042 partner->jumpScale = 0.0f;
2044 if (playerStatus->actionState == ACTION_STATE_TALK) {
2045 D_8010CFCA = 0;
2046 }
2047 } else {
2048 temp_a3 = clamp_angle(camera->curYaw + (playerStatus->spriteFacingAngle < 180.0f ? 90.0f : -90.0f));
2049 partner->moveToPos.x = playerStatus->pos.x;
2050 partner->moveToPos.y = playerStatus->pos.y;
2051 partner->moveToPos.z = playerStatus->pos.z;
2052 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, wPartnerTetherDistance - 10.0f, temp_a3);
2053 yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
2054 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
2055 partner->moveSpeed = 2.0f;
2056 if (distance > 2.0f) {
2057 partner->yaw = yaw;
2059 if (!(partner->flags & NPC_FLAG_COLLDING_FORWARD_WITH_WORLD)) {
2060 D_800F803A = 0;
2061 } else {
2062 D_800F803A++;
2063 if (D_800F803A > 10) {
2064 yaw = playerStatus->targetYaw;
2065 partner->moveSpeed = 0.0f;
2066 partner->jumpScale = 0.0f;
2067 partner->renderYaw = yaw;
2069 if (D_8010CFCA == 2 || playerStatus->actionState == ACTION_STATE_TALK) {
2070 D_8010CFCA = 0;
2071 }
2072 }
2073 }
2074 } else {
2075 yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
2076 partner->yaw = yaw;
2077 partner->moveSpeed = 0.0f;
2078 partner->jumpScale = 0.0f;
2080 if (D_8010CFCA == 2 || playerStatus->actionState == ACTION_STATE_TALK) {
2081 D_8010CFCA = 0;
2082 }
2083 }
2084 partner->yaw = yaw;
2085 npc_move_heading(partner, partner->moveSpeed, yaw);
2086 return;
2087 }
2088 }
2089
2090 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
2091 if (!(distance <= wPartnerTetherDistance)) {
2092 while (TRUE) {
2093 if (!currentSnapshot->isJumping) {
2094 yaw = atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ);
2095 if (!(fabsf(get_clamped_angle_diff(yaw, atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z))) < 90.0f)) {
2097 D_8010CFBC++;
2098 if (D_8010CFBC >= 40) {
2099 D_8010CFBC = 0;
2100 }
2101 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
2102 moveHistoryX = currentSnapshot->pos.x;
2103 moveHistoryZ = currentSnapshot->pos.z;
2104 continue;
2105 }
2106 }
2107 }
2108 break;
2109 }
2111 }
2112 break;
2113 case 15:
2114 if (!(playerStatus->animFlags & PA_FLAG_CHANGING_MAP)) {
2115 switch (D_8010CFCE) {
2116 case 0:
2117 temp_f0_15 = clamp_angle(player_get_side_angle() + 180.0f);
2118 partner->moveToPos.x = playerStatus->pos.x;
2119 partner->moveToPos.y = playerStatus->pos.y;
2120 partner->moveToPos.z = playerStatus->pos.z;
2121 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, playerStatus->colliderDiameter, temp_f0_15);
2122 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
2123 partner->moveSpeed = wPartnerMoveSpeed = distance / wPartnerMoveTime;
2125 yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
2126 partner->yaw = D_800F8034 = yaw;
2127 D_8010CFCE++;
2128 // fallthrough
2129 case 1:
2130 if (wPartnerMoveTime != 0) {
2131 x = partner->pos.x;
2132 y = partner->pos.y + partner->collisionHeight;
2133 z = partner->pos.z;
2134 distance = partner->collisionHeight + 1;
2136 if (npc_raycast_down_around(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) == 0) {
2137 if (partner->collisionHeight + 5 < fabs((partner->pos.y - playerStatus->pos.y))) {
2138 partner->pos.y += (playerStatus->pos.y - partner->pos.y) / 10.0f;
2139 }
2140 } else {
2141 partner->pos.y += (((playerStatus->pos.y + playerStatus->colliderHeight) - partner->pos.y) * 0.125f);
2142 }
2143 partner->moveSpeed = wPartnerMoveSpeed;
2144 partner->yaw = D_800F8034;
2145 x = partner->pos.x;
2146 y = partner->pos.y;
2147 z = partner->pos.z;
2148 if (npc_test_move_taller_with_slipping(0, &x, &y, &z, partner->moveSpeed, partner->yaw, partner->collisionHeight, partner->collisionDiameter)) {
2149 partner->pos.x += (x - partner->pos.x) / 5.0f;
2150 partner->pos.z += (z - partner->pos.z) / 5.0f;
2151 } else {
2152 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
2153 }
2154 return;
2155 }
2157 partner->moveSpeed = 0.0f;
2158 partner->jumpScale = 0.0f;
2161 D_8010CFCA = 0;
2162 D_8010CFCE = 0;
2163 partner->yaw = clamp_angle((camera->curYaw + 270.0f) - playerStatus->spriteFacingAngle);
2164 }
2165 }
2166 break;
2167 case 20:
2168 partner_move_to_goal(partner, TRUE);
2169 break;
2170 case 40:
2172 break;
2173 case 50:
2174 break;
2175 }
2176}
2177
2184
2185s32 partner_put_away(Npc* partner) {
2186 PlayerStatus* playerStatus = &gPlayerStatus;
2187 f32 tempMoveToX;
2188 f32 tempMoveToY;
2189 f32 tempMoveToZ;
2190 f32 tempPosX;
2191 f32 tempPosZ;
2192 f32 tempPosY;
2193 f32 tempDuration;
2194
2195 switch (wPartnerFollowState){
2196 case 0:
2197 tempMoveToX = partner->pos.x;
2198 tempMoveToY = partner->pos.y;
2199 tempMoveToZ = partner->pos.z;
2200 partner->flags &= ~NPC_FLAG_GRAVITY;
2201 partner->flags &= ~NPC_FLAG_FLYING;
2202 tempPosX = playerStatus->pos.x;
2203 partner->moveToPos.x = tempPosX;
2204 tempPosY = playerStatus->pos.y + (playerStatus->colliderHeight / 2);
2205 partner->moveToPos.y = playerStatus->pos.y + (playerStatus->colliderHeight / 2);
2206 tempPosZ = playerStatus->pos.z;
2207 wSavedPartnerPosX = tempMoveToX;
2208 wSavedPartnerPosY = tempMoveToY;
2209 wSavedPartnerPosZ = tempMoveToZ;
2210 partner->moveSpeed = 4.0f;
2211 partner->jumpScale = 1.6f;
2212 partner->moveToPos.z = tempPosZ;
2213 partner->planarFlyDist = dist2D(tempMoveToX, tempMoveToZ, tempPosX, tempPosZ);
2214 partner->yaw = atan2(tempMoveToX, tempMoveToZ, tempPosX, tempPosZ);
2215 partner->duration = 15;
2216 partner->moveSpeed = partner->planarFlyDist / partner->duration;
2217 tempMoveToY = tempPosY - tempMoveToY;
2218 partner->jumpVel = (tempMoveToY + partner->jumpScale * partner->duration * partner->duration * 0.5f) / partner->duration;
2220 enable_npc_blur(partner);
2222 break;
2223 case 1:
2224 partner->jumpVel -= partner->jumpScale;
2225 partner->pos.y += partner->jumpVel;
2226 if (partner->jumpVel <= 0.0f) {
2228 }
2229 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
2230 tempDuration = partner->duration;
2231 if (partner->duration > 10.0f) {
2232 tempDuration = 10.0f;
2233 }
2234 partner->scale.x = tempDuration / 10.0f;
2235 partner->scale.y = partner->scale.x;
2236 partner->scale.z = partner->scale.x;
2237 partner->duration--;
2238 if (partner->duration < 0) {
2240 }
2241 break;
2242 case 2:
2244 partner->jumpVel = 0.0f;
2245 partner->pos.y = partner->moveToPos.y;
2246 disable_npc_blur(partner);
2247 return TRUE;
2248 }
2249 return FALSE;
2250}
2251
2258
2259s32 partner_get_out(Npc* partner) {
2260 PlayerStatus* playerStatus = &gPlayerStatus;
2261 Camera* camera = &gCameras[gCurrentCameraID];
2262 f32 x, y, z, hitDepth;
2263 f32 var_f0;
2264
2265 f32 moveToX, moveToY, moveToZ;
2266
2267 switch (wPartnerFollowState) {
2268 case 0:
2269 if (clamp_angle(playerStatus->spriteFacingAngle) < 180.0f) {
2270 partner->yaw = clamp_angle(camera->curYaw + 90.0f);
2271 } else {
2272 partner->yaw = clamp_angle(camera->curYaw - 90.0f);
2273 }
2274 partner->moveToPos.x = playerStatus->pos.x;
2275 partner->moveToPos.y = playerStatus->pos.y;
2276 if (wPartner->isFlying) {
2277 partner->moveToPos.y = playerStatus->pos.y;
2278 }
2279 partner->moveToPos.z = playerStatus->pos.z;
2280 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, playerStatus->colliderDiameter, partner->yaw);
2281 moveToX = partner->moveToPos.x;
2282 moveToY = partner->moveToPos.y;
2283 moveToZ = partner->moveToPos.z;
2284 if (!wPartner->isFlying) {
2285 x = moveToX;
2286 y = moveToY + partner->collisionHeight;
2287 z = moveToZ;
2288 add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw);
2289 hitDepth = 1000.0f;
2290 if (npc_raycast_down_around(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &hitDepth, partner->yaw, partner->collisionDiameter)) {
2292 s32 surfaceType = get_collider_flags(NpcHitQueryColliderID);
2293
2294 if ((surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) || (hitDepth > 100.0f)) {
2295 moveToX = playerStatus->pos.x;
2296 moveToY = playerStatus->pos.y;
2297 moveToZ = playerStatus->pos.z;
2298 add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw);
2299 }
2300 } else {
2301 moveToX = playerStatus->pos.x;
2302 moveToY = playerStatus->pos.y;
2303 moveToZ = playerStatus->pos.z;
2304 add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw);
2305 }
2306 }
2307
2308 x = partner->pos.x = playerStatus->pos.x;
2309 y = partner->pos.y = playerStatus->pos.y + (playerStatus->colliderHeight / 2);
2310 z = partner->pos.z = playerStatus->pos.z;
2311
2312 partner->moveSpeed = 4.0f;
2313 partner->jumpScale = 1.2f;
2314 partner->planarFlyDist = dist2D(x, z, moveToX, moveToZ);
2315 partner->yaw = atan2(x, z, moveToX, moveToZ);
2316 partner->duration = partner->planarFlyDist / partner->moveSpeed;
2317 if (partner->duration < 10) {
2318 partner->duration = 10;
2319 partner->moveSpeed = partner->planarFlyDist / partner->duration;
2320 }
2321 partner->jumpVel = (moveToY - y + (partner->jumpScale * partner->duration * partner->duration * 0.5f)) /
2322 partner->duration;
2324 y = moveToY - y;
2326 break;
2327 case 1:
2328 if (partner->jumpVel < 0.0f && npc_try_snap_to_ground(partner, fabsf(partner->jumpVel))) {
2330 break;
2331 }
2332 partner->jumpVel -= partner->jumpScale;
2333 partner->pos.y += partner->jumpVel;
2334 if (partner->jumpVel <= 0.0f) {
2336 }
2337 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
2338 npc_do_world_collision(partner);
2339 var_f0 = partner->duration;
2340 if (var_f0 > 10.0f) {
2341 var_f0 = 10.0f;
2342 }
2343
2344 partner->scale.x = (10.0f - var_f0) / 10.0f;
2345 partner->scale.y = partner->scale.x;
2346 partner->scale.z = partner->scale.x;
2347
2348 partner->duration--;
2349 if (partner->duration < 0) {
2351 }
2352 break;
2353 case 2:
2354 partner->pos.y = partner->moveToPos.y;
2355 partner->jumpVel = 0.0f;
2356 partner->scale.x = 1.0f;
2357 partner->scale.y = 1.0f;
2358 partner->scale.z = 1.0f;
2359 partner->moveToPos.x = partner->pos.x;
2360 partner->moveToPos.y = partner->pos.y;
2361 partner->moveToPos.z = partner->pos.z;
2362 partner->pos.x = partner->pos.x;
2363 partner->pos.y = playerStatus->pos.y;
2364 if (wPartner->isFlying) {
2365 partner->pos.y = playerStatus->pos.y;
2366 }
2367 partner->pos.z = partner->pos.z;
2369 partner->pos.x = partner->moveToPos.x;
2370 partner->pos.y = partner->moveToPos.y;
2371 partner->pos.z = partner->moveToPos.z;
2372 if (partner->flags & NPC_FLAG_GROUNDED) {
2373 if (!wPartner->isFlying) {
2375 }
2376 }
2377 return TRUE;
2378 }
2379 return FALSE;
2380}
2381
2382void func_800EF300(void) {
2384}
2385
2386void func_800EF314(void) {
2388}
2389
2393
2394 if (!wPartner->isFlying) {
2396 } else {
2398 }
2399}
2400
2403}
2404
2408
2409void partner_set_goal_pos(s32 x, s32 z) {
2412}
2413
2414void func_800EF3D4(s32 arg0) {
2415 D_8010CFCA = arg0;
2416}
2417
2418void func_800EF3E4(void) {
2420 D_8010CFCA = 0;
2421 wPartnerMoveTime = 10;
2422 D_8010CFCE = 0;
2423}
2424
2425void func_800EF414(s32 posX, s32 posZ) {
2426 partner_set_goal_pos(posX, posZ);
2428}
2429
2430void func_800EF43C(void) {
2432 D_8010CFCA = 0;
2433 D_8010CFCE = 0;
2434}
2435
2438 s32 i;
2439
2440 wSavedPartnerPosX = partner->pos.x;
2441 wSavedPartnerPosY = partner->pos.y;
2442 wSavedPartnerPosZ = partner->pos.z;
2443
2444 for (i = 0; i < ARRAY_COUNT(gPlayerMoveHistory); i++, it++) {
2445 it->pos.x = wSavedPartnerPosX;
2446 it->pos.y = wSavedPartnerPosY;
2447 it->pos.z = wSavedPartnerPosZ;
2448 it->isJumping = FALSE;
2449 }
2450}
2451
2452// forces the player to complete a direction flip if they are currently performing one
2453// the resulting camera-relative direction is returned as a boolean 'isFacingLeft'
2455 PlayerStatus* playerStatus = &gPlayerStatus;
2456 Camera* cameras = gCameras;
2457 s32 isFacingLeft;
2458
2459 if (playerStatus->flipYaw[CAM_DEFAULT] == 0.0f) {
2460 if (!(playerStatus->spriteFacingAngle >= 90.0f) || !(playerStatus->spriteFacingAngle < 270.0f)) {
2461 isFacingLeft = TRUE;
2462 playerStatus->targetYaw = clamp_angle(cameras[CAM_DEFAULT].curYaw - 90.0f);
2463 } else {
2464 isFacingLeft = FALSE;
2465 playerStatus->targetYaw = clamp_angle(cameras[CAM_DEFAULT].curYaw + 90.0f);
2466 }
2467 } else if (get_clamped_angle_diff(cameras[CAM_DEFAULT].curYaw, playerStatus->targetYaw) < 0.0f) {
2468 isFacingLeft = TRUE;
2469 playerStatus->targetYaw = clamp_angle(cameras[CAM_DEFAULT].curYaw - 90.0f);
2470
2471 } else {
2472 isFacingLeft = FALSE;
2473 playerStatus->targetYaw = clamp_angle(cameras[CAM_DEFAULT].curYaw + 90.0f);
2474 }
2475
2476 playerStatus->curYaw = playerStatus->targetYaw;
2477 return isFacingLeft;
2478}
2479
2481 PartnerStatus* partnerStatus = &gPartnerStatus;
2482
2483 partnerStatus->inputDisabledCount--;
2484 if (partnerStatus->inputDisabledCount < 0) {
2485 partnerStatus->inputDisabledCount = 0;
2486 }
2487}
2488
2490 PartnerStatus* partnerStatus = &gPartnerStatus;
2491
2492 partnerStatus->inputDisabledCount++;
2493}
2494
2496 PlayerStatus* playerStatus = &gPlayerStatus;
2497 f32 playerScreenX;
2498 f32 playerScreenY;
2499 f32 playerScreenZ;
2500 f32 partnerScreenX;
2501 f32 partnerScreenY;
2502 f32 partnerScreenZ;
2503 f32 W;
2504
2505 transform_point(gCameras[CAM_DEFAULT].mtxPerspective,
2506 playerStatus->pos.x, playerStatus->pos.y, playerStatus->pos.z, 1.0f,
2507 &playerScreenX, &playerScreenY, &playerScreenZ, &W);
2508 transform_point(gCameras[CAM_DEFAULT].mtxPerspective, partner->pos.x, partner->pos.y, partner->pos.z, 1.0f,
2509 &partnerScreenX, &partnerScreenY, &partnerScreenZ, &W);
2510 playerScreenX = fabsf(playerScreenX - partnerScreenX);
2511 playerScreenY = fabsf(playerScreenY - partnerScreenY);
2512 playerScreenZ = fabsf(playerScreenZ - partnerScreenZ);
2513 if (playerScreenX <= (partner->collisionDiameter + playerStatus->colliderDiameter) * 0.9f &&
2514 playerScreenY <= partner->collisionHeight + playerStatus->colliderHeight && playerScreenZ <= 4.0)
2515 {
2516 npc_move_heading(partner, 1.0f,
2517 atan2(playerStatus->pos.x, playerStatus->pos.z, partner->pos.x, partner->pos.z));
2518 add_vec2D_polar(&partner->pos.x, &partner->pos.z, 2.0f, gCameras[gCurrentCameraID].curYaw);
2519 }
2520}
2521
2522void partner_move_to_goal(Npc* partner, s32 isFlying) {
2523 PlayerStatus* playerStatus = &gPlayerStatus;
2524 f32 x, y, z, temp;
2525 s32 var_a1;
2526
2527 switch (D_8010CFCE) {
2528 case 0:
2529 D_8010CFCE++;
2530 partner->moveToPos.y = playerStatus->pos.y;
2531 partner->moveToPos.x = wPartnerMoveGoalX;
2532 partner->moveToPos.z = wPartnerMoveGoalZ;
2533 D_800F8034 = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
2534 partner->yaw = D_800F8034;
2535 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, 5.0f, D_800F8034);
2536 wPartnerMoveTime = 18;
2537 temp = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
2538 partner->moveSpeed = wPartnerMoveSpeed = temp / wPartnerMoveTime;
2541 case 1:
2542 if (wPartnerMoveTime != 0) {
2544 if (!isFlying) {
2545 if (!(partner->flags & NPC_FLAG_GROUNDED)) {
2546 partner->pos.y = playerStatus->pos.y;
2547 }
2548 if (partner->jumpVel != 0.0f) {
2549 partner->jumpVel -= partner->jumpScale;
2550 partner->pos.y += partner->jumpVel;
2551 if (partner->jumpVel <= 0.0f) {
2553 }
2554
2555 if (partner->jumpVel <= 0.0f) {
2556 temp = fabsf(partner->jumpVel) + partner->collisionHeight;
2557 y = partner->pos.y + partner->collisionHeight;
2558 x = partner->pos.x;
2559 z = partner->pos.z;
2560
2561 if (npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &temp,
2562 partner->yaw, partner->collisionDiameter) &&
2563 (temp <= fabsf(partner->jumpVel) + 22.0f))
2564 {
2567 partner->jumpScale = 0.0f;
2568 partner->jumpVel = 0.0f;
2569 partner->pos.y = y;
2570 partner->flags &= ~NPC_FLAG_JUMPING;
2571 }
2572 }
2573 }
2574 partner->moveSpeed = wPartnerMoveSpeed;
2575 partner->yaw = D_800F8034;
2576 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
2579 npc_do_world_collision(partner);
2580 } else {
2581 if (fabs(partner->pos.y - playerStatus->pos.y) > 5.0) {
2582 partner->pos.y += (playerStatus->pos.y - partner->pos.y) * 0.5f;
2583 }
2584 partner->moveSpeed = wPartnerMoveSpeed;
2585 partner->yaw = D_800F8034;
2586 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
2587 }
2588
2590 } else {
2591 partner->flags &= ~NPC_FLAG_IGNORE_WORLD_COLLISION;
2593 D_8010CFCE++;
2594 }
2595 break;
2596 case 2:
2597 break;
2598 }
2599}
s32 world_bombette_can_use_ability(Npc *npc)
void world_bombette_init(Npc *)
s32 world_bombette_test_first_strike(Npc *, Npc *)
s32 world_bombette_can_open_menus(Npc *)
void world_bombette_pre_battle(Npc *)
void world_bow_init(Npc *)
void world_bow_pre_battle(Npc *)
b8 keepUsingPartnerOnMapChange
u32 pressedButtons[4]
u8 groupFlags
union Evt::@9 owner2
Initially -1.
Bytecode EvtScript[]
s16 invItems[10]
Vec3s pos
Definition demo_api.c:17
#define transform_point
#define clamp_angle
#define atan2
#define mem_clear
@ BUTTON_C_DOWN
Definition enums.h:2779
@ BUTTON_B
Definition enums.h:2789
@ BUTTON_C_LEFT
Definition enums.h:2778
@ BUTTON_Z
Definition enums.h:2788
@ SURFACE_TYPE_LAVA
Definition enums.h:4673
@ SURFACE_TYPE_SPIKES
Definition enums.h:4672
@ PARTNER_ANIM_INDEX_RUN
Definition enums.h:3408
@ PARTNER_ANIM_INDEX_WALK
Definition enums.h:3403
@ PS_FLAG_FALLING
Definition enums.h:3036
@ PS_FLAG_JUMPING
Definition enums.h:3035
@ PS_FLAG_NO_STATIC_COLLISION
Definition enums.h:3051
@ PS_FLAG_HIT_FIRE
Definition enums.h:3050
@ PS_FLAG_INPUT_DISABLED
Definition enums.h:3052
@ PARTNER_ACTION_NONE
Definition enums.h:2932
@ PARTNER_ACTION_USE
Definition enums.h:2933
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4696
@ NPC_PARTNER
Definition enums.h:2528
@ ENTITY_TYPE_TRUMPET_PLANT
Definition enums.h:2591
@ ENTITY_TYPE_BELLBELL_PLANT
Definition enums.h:2590
@ ENTITY_TYPE_SCRIPT_SPRING
Definition enums.h:2584
@ ENTITY_TYPE_3B
Definition enums.h:2596
@ ENTITY_TYPE_PINK_FLOWER
Definition enums.h:2594
@ ENTITY_TYPE_HUGE_BLUE_SWITCH
Definition enums.h:2552
@ ENTITY_TYPE_BLUE_SWITCH
Definition enums.h:2550
@ ENTITY_TYPE_GREEN_STOMP_SWITCH
Definition enums.h:2553
@ ENTITY_TYPE_CYMBAL_PLANT
Definition enums.h:2593
@ ENTITY_TYPE_RED_SWITCH
Definition enums.h:2551
@ ENTITY_TYPE_SIMPLE_SPRING
Definition enums.h:2583
@ ENTITY_TYPE_CHEST
Definition enums.h:2587
@ ENTITY_TYPE_SPINNING_FLOWER
Definition enums.h:2595
@ ENTITY_TYPE_TWEESTER
Definition enums.h:2597
@ ENTITY_TYPE_MUNCHLESIA
Definition enums.h:2592
@ PA_FLAG_INTERRUPT_USE_PARTNER
forces actions with bow, parakarry, watt, and lakilester to end (sushie not tested)
Definition enums.h:3093
@ PA_FLAG_SPINNING
Definition enums.h:3107
@ PA_FLAG_OPENED_HIDDEN_PANEL
Definition enums.h:3102
@ PA_FLAG_CHANGING_MAP
Definition enums.h:3112
@ PA_FLAG_FORCED_PARTNER_ABILITY_END
Definition enums.h:3125
@ TIME_FREEZE_PARTIAL
Definition enums.h:3465
@ TIME_FREEZE_NONE
Definition enums.h:3464
@ SOUND_PARTNER_GET_OUT
Definition enums.h:559
@ SOUND_PARTNER_PUT_AWAY
Definition enums.h:558
@ SOUND_MENU_ERROR
Definition enums.h:933
@ PARTNER_NONE
Definition enums.h:2885
@ PARTNER_BOMBETTE
Definition enums.h:2888
@ PARTNER_LAKILESTER
Definition enums.h:2893
@ PARTNER_WATT
Definition enums.h:2891
@ PARTNER_BOW
Definition enums.h:2894
@ PARTNER_SUSHIE
Definition enums.h:2892
@ PARTNER_TWINK
Definition enums.h:2896
@ PARTNER_PARAKARRY
Definition enums.h:2889
@ PARTNER_GOOMBARIA
Definition enums.h:2895
@ PARTNER_GOOMPA
Definition enums.h:2890
@ PARTNER_KOOPER
Definition enums.h:2887
@ PARTNER_GOOMBARIO
Definition enums.h:2886
@ ACTION_STATE_RIDE
Definition enums.h:2461
@ ACTION_STATE_HIT_LAVA
Definition enums.h:2451
@ ACTION_STATE_IDLE
Definition enums.h:2426
@ ACTION_STATE_TALK
Reading signs doesn't count.
Definition enums.h:2440
@ ACTION_STATE_LAND
Definition enums.h:2437
@ ACTION_STATE_WALK
Definition enums.h:2427
@ ACTION_STATE_STEP_DOWN
Definition enums.h:2436
@ ACTION_STATE_HIT_FIRE
Causes Mario to fly up and take damage. Used for fire bars.
Definition enums.h:2449
@ ACTION_STATE_RUN
Definition enums.h:2428
@ SURFACE_INTERACT_RUN
Definition enums.h:4685
@ SURFACE_INTERACT_WALK
Definition enums.h:4684
@ SURFACE_INTERACT_LAND
Definition enums.h:4686
@ PARTNER_CMD_INIT
Definition enums.h:2946
@ PARTNER_CMD_PUT_AWAY
Definition enums.h:2949
@ PARTNER_CMD_NONE
Definition enums.h:2945
@ PARTNER_CMD_RESET
Definition enums.h:2954
@ PARTNER_CMD_INSTA_SWITCH
Definition enums.h:2947
@ PARTNER_CMD_ABORT
Definition enums.h:2955
@ PARTNER_CMD_TAKE_OUT
Definition enums.h:2951
@ PARTNER_CMD_INSTA_TAKE_OUT
Definition enums.h:2952
@ PARTNER_CMD_INSTA_PUT_AWAY
Definition enums.h:2950
@ PARTNER_CMD_USE_ABILITY
Definition enums.h:2953
@ PARTNER_CMD_SWITCH
Definition enums.h:2948
@ CAM_DEFAULT
Definition enums.h:1800
@ NPC_FLAG_JUMPING
Definition enums.h:3009
@ NPC_FLAG_TOUCHES_GROUND
Definition enums.h:3020
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:3006
@ NPC_FLAG_COLLDING_FORWARD_WITH_WORLD
Definition enums.h:3012
@ NPC_FLAG_COLLIDING_WITH_NPC
Definition enums.h:3023
@ NPC_FLAG_GRAVITY
Definition enums.h:3007
@ NPC_FLAG_PARTNER
Definition enums.h:3024
@ NPC_FLAG_GROUNDED
Definition enums.h:3010
@ NPC_FLAG_COLLDING_WITH_WORLD
Definition enums.h:3011
@ EVT_PRIORITY_14
Definition evt.h:154
@ EVT_PRIORITY_1
Definition evt.h:152
@ EVT_GROUP_PASSIVE_NPC
Definition evt.h:143
@ EVT_FLAG_RUN_IMMEDIATELY
don't wait for next update_scripts call
Definition evt.h:161
Worker * get_worker(s32 idx)
Definition worker.c:186
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
f64 fabs(f64 f)
void sort_consumables(void)
Bubbles up player inventory items such that all ITEM_NONE values are at the bottom.
Definition inventory.c:404
s32 disable_player_input(void)
Definition 77480.c:990
s32 get_collider_flags(s32 colliderID)
Definition collision.c:481
s32 suspend_all_script(s32 id)
u32 dma_copy(Addr romStart, Addr romEnd, void *vramDest)
Definition 43F0.c:444
void enable_npc_blur(Npc *npc)
Definition npc.c:1067
s32 enable_player_input(void)
Definition 77480.c:998
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
f32 player_get_side_angle(void)
Definition 7BB60.c:1178
u32 get_entity_type(s32 arg0)
Definition entity.c:568
s32 is_starting_conversation(void)
Definition encounter.c:2818
Evt * start_script(EvtScript *source, s32 priority, s32 initialState)
b32 npc_test_move_taller_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
b32 npc_raycast_up(s32, f32 *, f32 *, f32 *, f32 *)
void kill_script_by_ID(s32 id)
s32 resume_all_script(s32 id)
s32 does_script_exist(s32 id)
void set_time_freeze_mode(s32)
Time freeze modes: 0: none 1: NPCs move, can't be interacted with 2: NPCs don't move,...
Definition main_loop.c:358
s32 create_worker_frontUI(void(*updateFunc)(void), void(*drawFunc)(void))
Definition worker.c:63
void add_vec2D_polar(f32 *x, f32 *y, f32 r, f32 theta)
Definition 43F0.c:685
f32 get_clamped_angle_diff(f32, f32)
Definition 43F0.c:606
EvtScript EVS_WorldGoombaria_UseAbility
Definition goombaria.c:63
EvtScript EVS_WorldGoombaria_Update
Definition goombaria.c:57
EvtScript EVS_WorldGoombaria_TakeOut
Definition goombaria.c:51
EvtScript EVS_WorldGoombaria_PutAway
Definition goombaria.c:69
void world_goombaria_init(Npc *partner)
s32 world_goombario_can_open_menus(Npc *partner)
void world_goombario_init(Npc *partner)
void world_goombario_pre_battle(Npc *partner)
void world_goompa_init(Npc *partner)
s32 HudScript[]
Definition hud_element.h:9
s32 world_kooper_test_first_strike(Npc *, Npc *)
void world_kooper_init(Npc *)
void world_kooper_post_battle(Npc *)
void world_kooper_pre_battle(Npc *)
void world_lakilester_init(Npc *)
void world_lakilester_pre_battle(Npc *)
void world_lakilester_post_battle(Npc *)
s32 npc_try_snap_to_ground(Npc *npc, f32 velocity)
Definition npc.c:581
s32 create_basic_npc(NpcBlueprint *blueprint)
Definition npc.c:190
void npc_surface_spawn_fx(Npc *npc, SurfaceInteractMode mode)
Definition surfaces.c:394
void free_npc_by_index(s32 listIndex)
Definition npc.c:202
void npc_do_world_collision(Npc *npc)
Definition npc.c:278
Npc * get_npc_by_index(s32 listIndex)
Definition npc.c:271
void npc_move_heading(Npc *npc, f32 speed, f32 yaw)
Definition npc.c:986
void world_parakarry_init(Npc *)
void world_parakarry_post_battle(Npc *)
void world_parakarry_pre_battle(Npc *)
BSS PlayerPathElement gPlayerMoveHistory[40]
Definition partners.c:46
HudScript HES_BombetteDisabled
void partner_init_after_battle(s32 partnerID)
Definition partners.c:926
s32 partner_can_use_ability(void)
Definition partners.c:993
BSS s32 gPlayerMoveHistoryIndex
Definition partners.c:47
s32 func_800EA52C(s32 partnerID)
Definition partners.c:537
HudScript HES_StatusDigit6
BSS s16 D_8010CFCC
Definition partners.c:53
HudScript HES_Parakarry
s32 partner_init_get_out(Npc *npc)
Definition partners.c:2252
HudScript HES_StatusSPIncrement6
s16 D_800F803A
Definition partners.c:165
HudScript * TimesHudScript
Definition partners.c:146
BSS s32 wPartnerNpcIndex
Definition partners.c:55
HudScript HES_StatusDigit1
void partner_walking_follow_player(Npc *partner)
Definition partners.c:1231
HudScript * wDisabledPartnerHudScripts[]
Definition partners.c:136
void switch_to_partner(s32 partnerID)
Definition partners.c:906
HudScript * SlashHudScript
Definition partners.c:147
void partner_reset_data(void)
Definition partners.c:1000
UseItemStruct UseItemDmaArgs
Definition partners.c:470
s32 func_800EA4B0(s32 collisionID)
Definition partners.c:497
PartnerAnimations gPartnerAnimations[]
Definition partners.c:343
HudScript HES_StatusSPIncrement4
void partner_disable_input(void)
Definition partners.c:2489
HudScript HES_StatusStar1
HudScript HES_StatusSPIncrement3
HudScript HES_PartnerADisabled
HudScript HES_StatusDigit8
void partner_resume_ability_script(void)
Definition partners.c:1125
PartnerStatus gPartnerStatus
Definition partners.c:42
void partner_walking_update_motion(Npc *partner)
Definition partners.c:1202
HudScript HES_BowDisabled
void partner_clear_player_tracking(Npc *partner)
Definition partners.c:2436
f32 wSavedPartnerPosZ
Definition partners.c:341
void partner_flying_update_player_tracking(Npc *partner)
Definition partners.c:1751
s32 wPartnerMoveGoalZ
Definition partners.c:160
HudScript HES_LakilesterDisabled
HudScript * DigitHudScripts[]
Definition partners.c:142
HudScript * wPartnerHudScripts[]
Definition partners.c:130
HudScript HES_StatusDigit3
s32 D_800F8020
Definition partners.c:158
HudScript * SPStarHudScripts[]
Definition partners.c:152
HudScript HES_StatusDigit5
HudScript HES_StatusDigit2
HudScript HES_StatusDigit7
EvtScript * main
Definition partners.c:125
HudScript HES_SushieDisabled
void partner_walking_update_player_tracking(Npc *partner)
Definition partners.c:1175
HudScript * SPIncrementHudScripts[]
Definition partners.c:148
BSS s32 D_8010CFBC
Definition partners.c:48
BSS s32 PartnerCommandState
Definition partners.c:45
void func_800EA5B8(Npc *partner)
Definition partners.c:576
HudScript HES_KooperDisabled
HudScript HES_GoombarioDisabled
BSS s32 D_8010CFC4
Definition partners.c:50
void partner_kill_ability_script(void)
Definition partners.c:1109
void create_partner_npc(void)
Definition partners.c:581
void partner_free_npc(void)
Definition partners.c:621
s32 wPartnerMoveGoalX
Definition partners.c:159
BSS s16 D_8010CFCA
Definition partners.c:52
s32 partner_is_flying(void)
Definition partners.c:572
HudScript HES_StatusStar2
HudScript HES_ParakarryDisabled
HudScript HES_StatusDigit9
HudScript HES_StatusStar3
f32 D_800F84F8
Definition partners.c:495
void func_800EF314(void)
Definition partners.c:2386
void partner_enable_input(void)
Definition partners.c:2480
s32 StatusBarSPIncrementOffsets[]
Definition partners.c:156
s32 partner_init_put_away(Npc *partner)
Definition partners.c:2178
s32 partner_use_ability(void)
Definition partners.c:964
HudScript HES_StatusSlash
BSS s32 wPartnerCurrentScriptID
Definition partners.c:58
HudScript HES_StatusSPIncrement7
WorldPartner wPartners[]
Definition partners.c:167
s32 partner_test_enemy_collision(Npc *enemy)
Definition partners.c:1051
BSS s32 NextPartnerCommand
Definition partners.c:61
void enable_partner_ai(void)
Definition partners.c:2390
s32 use_consumable(s32 invSlot)
Definition partners.c:479
BSS Evt * wPartnerCurrentScript
Definition partners.c:56
s16 D_800F8038
Definition partners.c:164
BSS s32 NextPartnerID
Definition partners.c:60
void func_800EF414(s32 posX, s32 posZ)
Definition partners.c:2425
f32 wSavedPartnerPosX
Definition partners.c:339
s32 partner_put_away(Npc *partner)
Definition partners.c:2185
HudScript HES_Partner0Disabled
void func_800EF3E4(void)
Definition partners.c:2418
f32 wSavedPartnerPosY
Definition partners.c:340
void partner_flying_follow_player(Npc *)
Definition partners.c:1859
HudScript HES_WattDisabled
HudScript HES_StatusTimes
BSS s32 D_8010CD20
Definition partners.c:477
BSS s16 wPartnerFollowState
Definition partners.c:51
void func_800EF43C(void)
Definition partners.c:2430
HudScript HES_Sushie
s32 partner_force_player_flip_done(void)
Definition partners.c:2454
s32 partner_can_open_world_menus(void)
Definition partners.c:983
void partner_flying_update_motion(Npc *partner)
Definition partners.c:1777
BSS s32 wCurrentPartnerId
Definition partners.c:57
HudScript HES_Partner0
s32 world_partner_can_open_menus_default(Npc *partner)
Definition partners.c:533
EvtScript * partner_get_enter_map_script(void)
Definition partners.c:1058
HudScript HES_StatusStar7
void remove_consumable(void)
Definition partners.c:490
BSS WorldPartner * wPartner
Definition partners.c:62
HudScript HES_StatusStar5
HudScript HES_StatusSPIncrement5
s32 wPartnerMoveTime
Definition partners.c:161
HudScript HES_PartnerA
BSS s32 D_8010CFE0
Definition partners.c:59
void partner_handle_before_battle(void)
Definition partners.c:1067
s32 partner_get_out(Npc *partner)
Definition partners.c:2259
HudScript HES_StatusSPIncrement2
HudScript HES_Kooper
void partner_walking_enable(Npc *partner, s32 val)
Definition partners.c:1133
f32 D_800F8034
Definition partners.c:163
void partner_flying_enable(Npc *partner, s32 val)
Definition partners.c:1706
BSS f32 wPartnerTetherDistance
Definition partners.c:49
void _use_partner_ability(void)
Definition partners.c:625
void func_800EB2A4(s32 partnerID)
Definition partners.c:949
void partner_handle_after_battle(void)
Definition partners.c:1081
void partner_set_tether_distance(f32 dist)
Definition partners.c:2401
HudScript HES_StatusStar6
void func_800EF3D4(s32 arg0)
Definition partners.c:2414
s32 partner_is_idle(Npc *partner)
Definition partners.c:529
void partner_reset_tether_distance(void)
Definition partners.c:2405
f32 wPartnerMoveSpeed
Definition partners.c:162
void partner_do_player_collision(Npc *partner)
Definition partners.c:2495
HudScript HES_Watt
void func_800EF300(void)
Definition partners.c:2382
void partner_suspend_ability_script(void)
Definition partners.c:1117
HudScript HES_StatusStar4
HudScript HES_StatusDigit0
Npc * wPartnerNpc
Definition partners.c:43
HudScript HES_StatusDigit4
void partner_move_to_goal(Npc *, s32)
Definition partners.c:2522
EvtScript EVS_World_UseItem
HudScript HES_Lakilester
HudScript HES_StatusSPIncrement1
void partner_set_goal_pos(s32 x, s32 z)
Definition partners.c:2409
HudScript HES_Bow
HudScript HES_Bombette
HudScript HES_Goombario
BSS s16 D_8010CFCE
Definition partners.c:54
void partner_initialize_data(void)
Definition partners.c:1032
void * dmaStart
Definition partners.h:9
void * dmaEnd
Definition partners.h:10
void * dmaDest
Always 0x802BD100
Definition partners.h:11
PartnerFunc preBattle
Definition partners.h:22
EvtScript * takeOut
Definition partners.h:14
PartnerBoolFunc canUseAbility
Definition partners.h:20
PartnerTesHitFunc testFirstStrike
Definition partners.h:19
EvtScript * update
Definition partners.h:15
PartnerBoolFunc canPlayerOpenMenus
Definition partners.h:21
PartnerFunc postBattle
Definition partners.h:23
EvtScript * onEnterMap
Definition partners.h:24
EvtScript * useAbility
Definition partners.h:16
EvtScript * putAway
Definition partners.h:17
PartnerFunc init
Definition partners.h:13
void sfx_play_sound(s32 soundID)
Definition sfx.c:517
#define NPC_DISPOSE_POS_Z
Definition macros.h:161
#define NPC_DISPOSE_POS_X
Definition macros.h:159
#define COLLISION_WITH_ENTITY_BIT
Definition macros.h:152
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define NPC_DISPOSE_POS_Y
Definition macros.h:160
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
s32 flags
f32 renderYaw
AnimID curAnim
Vec3f moveToPos
f32 planarFlyDist
s32 collisionChannel
s16 collisionHeight
Vec3f pos
s16 curFloor
f32 moveSpeed
s16 curWall
s16 duration
void world_sushie_pre_battle(Npc *)
void world_sushie_init(Npc *)
void world_sushie_post_battle(Npc *)
void world_twink_init(Npc *partner)
Entity * TweesterTouchingPartner
Definition 7B440.c:5
PlayerStatus * gPlayerStatusPtr
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
void world_watt_init(Npc *)
void world_watt_pre_battle(Npc *)
void world_watt_post_battle(Npc *)
EvtScript EVS_WorldBombette_TakeOut
Definition bombette.c:87
EvtScript EVS_WorldBombette_Update
Definition bombette.c:180
EvtScript EVS_WorldBombette_PutAway
Definition bombette.c:591
EvtScript EVS_WorldBombette_UseAbility
Definition bombette.c:571
EvtScript EVS_WorldBow_Update
Definition bow.c:128
EvtScript EVS_WorldBow_PutAway
Definition bow.c:415
EvtScript EVS_WorldBow_TakeOut
Definition bow.c:41
EvtScript EVS_WorldBow_UseAbility
Definition bow.c:360
EvtScript EVS_WorldGoombario_UseAbility
Definition goombario.c:457
EvtScript EVS_WorldGoombario_TakeOut
Definition goombario.c:98
EvtScript EVS_WorldGoombario_Update
Definition goombario.c:198
EvtScript EVS_WorldGoombario_PutAway
Definition goombario.c:493
EvtScript EVS_WorldGoompa_TakeOut
Definition goompa.c:26
EvtScript EVS_WorldGoompa_PutAway
Definition goompa.c:156
EvtScript EVS_WorldGoompa_UseAbility
Definition goompa.c:136
EvtScript EVS_WorldGoompa_Update
Definition goompa.c:117
EvtScript EVS_WorldKooper_TakeOut
Definition kooper.c:93
EvtScript EVS_WorldKooper_UseAbility
Definition kooper.c:647
EvtScript EVS_WorldKooper_Update
Definition kooper.c:194
EvtScript EVS_WorldKooper_PutAway
Definition kooper.c:663
EvtScript EVS_WorldLakilester_PutAway
EvtScript EVS_WorldLakilester_TakeOut
Definition lakilester.c:109
EvtScript EVS_WorldLakilester_UseAbility
Definition lakilester.c:992
EvtScript EVS_WorldLakilester_Update
Definition lakilester.c:200
EvtScript EVS_WorldLakilester_EnterMap
EvtScript EVS_WorldParakarry_UseAbility
Definition parakarry.c:613
EvtScript EVS_WorldParakarry_PutAway
Definition parakarry.c:633
EvtScript EVS_WorldParakarry_Update
Definition parakarry.c:147
EvtScript EVS_WorldParakarry_TakeOut
Definition parakarry.c:56
EvtScript EVS_WorldSushie_PutAway
Definition sushie.c:886
EvtScript EVS_WorldSushie_EnterMap
Definition sushie.c:985
EvtScript EVS_WorldSushie_TakeOut
Definition sushie.c:771
EvtScript EVS_WorldSushie_UseAbility
Definition sushie.c:740
EvtScript EVS_WorldSushie_Update
Definition sushie.c:860
EvtScript EVS_WorldTwink_TakeOut
Definition twink.c:59
EvtScript EVS_WorldTwink_UseAbility
Definition twink.c:71
EvtScript EVS_WorldTwink_PutAway
Definition twink.c:77
EvtScript EVS_WorldTwink_Update
Definition twink.c:65
EvtScript EVS_WorldWatt_PutAway
Definition watt.c:461
EvtScript EVS_WorldWatt_EnterMap
Definition watt.c:597
EvtScript EVS_WorldWatt_Update
Definition watt.c:208
EvtScript EVS_WorldWatt_UseAbility
Definition watt.c:433
EvtScript EVS_WorldWatt_TakeOut
Definition watt.c:90