Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
encounter.c File Reference

Go to the source code of this file.

Enumerations

enum  { MERLEE_EFFECTS_HOLD = 0 , MERLEE_EFFECTS_RELEASE = 1 , MERLEE_EFFECTS_DISMISS = 2 }
 

Functions

void set_battle_formation (Battle *)
 
void setup_status_bar_for_world (void)
 
void partner_handle_after_battle (void)
 
s32 get_coin_drop_amount (Enemy *enemy)
 
s32 get_defeated (s32 mapID, s32 encounterID)
 
void set_defeated (s32 mapID, s32 encounterID)
 
void update_encounters_neutral (void)
 
void draw_encounters_neutral (void)
 
void update_encounters_pre_battle (void)
 
void draw_encounters_pre_battle (void)
 
void show_first_strike_message (void)
 
void update_encounters_post_battle (void)
 
void draw_encounters_post_battle (void)
 
void update_encounters_conversation (void)
 
void draw_encounters_conversation (void)
 
b32 check_conversation_trigger (void)
 
void create_encounters (void)
 
void init_encounters_ui (void)
 
s32 is_starting_conversation (void)
 

Variables

b32 D_80077C40 = FALSE
 
b32 EncounterStateChanged
 
EvtScript EVS_MerleeDropCoins
 
EvtScript EVS_NpcDefeat
 
EvtScript EVS_FleeBattleDrops
 
EnemyDrops DefaultEnemyDrops
 
EvtScript EnemyNpcHit
 
EvtScript EnemyNpcDefeat
 
s32 gEncounterState
 
s32 gEncounterSubState
 
EncounterStatus gCurrentEncounter
 
s8 HasPreBattleSongPushed
 
b8 PendingPartnerAbilityResume
 
b8 LastBattleStartedBySpin
 
s16 gFirstStrikeMessagePos
 
BSS s32 WorldMerleeEffectsTime
 
BSS f32 WorldMerleeBasePosY
 
BSS EffectInstanceWorldMerleeOrbEffect
 
BSS EffectInstanceWorldMerleeWaveEffect
 
BSS EvtMerleeDropCoinsEvt
 
BSS s32 MerleeDropCoinsEvtID
 
BSS s16 WorldMerleeEffectsState
 

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
MERLEE_EFFECTS_HOLD 
MERLEE_EFFECTS_RELEASE 
MERLEE_EFFECTS_DISMISS 

Definition at line 191 of file encounter.c.

191 {
192 MERLEE_EFFECTS_HOLD = 0, // effects appear and track Merlee's position
193 MERLEE_EFFECTS_RELEASE = 1, // effects grow larger before vanishing
194 MERLEE_EFFECTS_DISMISS = 2, // effects vanish and are dismissed
195};
@ MERLEE_EFFECTS_DISMISS
Definition encounter.c:194
@ MERLEE_EFFECTS_RELEASE
Definition encounter.c:193
@ MERLEE_EFFECTS_HOLD
Definition encounter.c:192

Function Documentation

◆ set_battle_formation()

void set_battle_formation ( Battle * battle)

Definition at line 141 of file battle.c.

141 {
142 gOverrideBattlePtr = battle;
143}
BSS Battle * gOverrideBattlePtr
Definition battle.c:18

Referenced by update_encounters_pre_battle().

◆ setup_status_bar_for_world()

void setup_status_bar_for_world ( void )

Definition at line 1450 of file inventory.c.

1450 {
1451 StatusBar* statusBar = &gStatusBar;
1452
1453 statusBar->drawPosY = FULLY_RETRACTED_Y;
1454 statusBar->ignoreChanges = FALSE;
1455 statusBar->showTimer = 0;
1456 statusBar->hidden = TRUE;
1457 statusBar->unk_3B = FALSE;
1458 statusBar->unk_3C = FALSE;
1459}
#define FULLY_RETRACTED_Y
Definition inventory.c:7
StatusBar gStatusBar
Definition inventory.c:17

Referenced by update_encounters_post_battle().

◆ partner_handle_after_battle()

void partner_handle_after_battle ( void )

Definition at line 1081 of file partners.c.

1081 {
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}
u8 groupFlags
union Evt::@9 owner2
Initially -1.
@ PARTNER_NONE
Definition enums.h:2885
@ PARTNER_WATT
Definition enums.h:2891
@ PARTNER_CMD_INIT
Definition enums.h:2946
@ EVT_PRIORITY_14
Definition evt.h:154
@ EVT_GROUP_PASSIVE_NPC
Definition evt.h:143
@ EVT_FLAG_RUN_IMMEDIATELY
don't wait for next update_scripts call
Definition evt.h:161
Evt * start_script(EvtScript *source, s32 priority, s32 initialState)
void kill_script_by_ID(s32 id)
s32 does_script_exist(s32 id)
PartnerStatus gPartnerStatus
Definition partners.c:42
BSS s32 wPartnerCurrentScriptID
Definition partners.c:58
BSS s32 NextPartnerCommand
Definition partners.c:61
BSS Evt * wPartnerCurrentScript
Definition partners.c:56
BSS s32 wCurrentPartnerId
Definition partners.c:57
BSS WorldPartner * wPartner
Definition partners.c:62
Npc * wPartnerNpc
Definition partners.c:43
EvtScript * update
Definition partners.h:15
PartnerFunc postBattle
Definition partners.h:23
PlayerStatus * gPlayerStatusPtr
PlayerData gPlayerData
Definition 77480.c:40

Referenced by update_encounters_post_battle().

◆ get_coin_drop_amount()

s32 get_coin_drop_amount ( Enemy * enemy)

Definition at line 312 of file 23680.c.

312 {
313 EncounterStatus* currentEncounter = &gCurrentEncounter;
314 EnemyDrops* enemyDrops = enemy->drops;
315 s32 max = enemyDrops->maxCoinBonus;
316 s32 amt = enemyDrops->minCoinBonus;
317 s32 minTemp = enemyDrops->minCoinBonus;
318
319 if (max < amt) {
320 amt = enemyDrops->maxCoinBonus;
321 max = enemyDrops->minCoinBonus;
322 }
323
324 minTemp = max - amt;
325 if ((amt < 0) || (minTemp != 0)) {
326 amt = rand_int(minTemp) - -amt;
327 }
328
329 if (amt < 0) {
330 amt = 0;
331 }
332
334 amt += currentEncounter->damageTaken / 2;
335 }
336
337 if (currentEncounter->hasMerleeCoinBonus) {
338 amt *= 3;
339 }
340
342 amt *= 2;
343 }
344
345 amt += currentEncounter->coinsEarned;
346
348 amt = 0;
349 }
350
351 if (amt > 20) {
352 amt = 20;
353 }
354
355 return amt;
356}
#define rand_int
@ ENEMY_FLAG_NO_DROPS
Definition enums.h:4544
@ ENEMY_FLAG_NO_DELAY_AFTER_FLEE
Definition enums.h:4539
@ ABILITY_PAY_OFF
Definition enums.h:461
@ ABILITY_MONEY_MONEY
Definition enums.h:452
s32 is_ability_active(s32 arg0)
Definition inventory.c:1725
s16 coinsEarned
Definition npc.h:377
s32 flags
Definition npc.h:295
EnemyDrops * drops
Definition npc.h:343
u8 damageTaken
Definition npc.h:375
b8 hasMerleeCoinBonus
Definition npc.h:374
s16 maxCoinBonus
Definition npc.h:193
EncounterStatus gCurrentEncounter
Definition encounter.c:176
s16 minCoinBonus
Definition npc.h:192

Referenced by update_encounters_post_battle().

◆ get_defeated()

s32 get_defeated ( s32 mapID,
s32 encounterID )

Definition at line 202 of file encounter.c.

202 {
203 EncounterStatus* currentEncounter = &gCurrentEncounter;
204 s32 encounterIdx = encounterID / 32;
205 s32 encounterShift = encounterID % 32;
206
207 return currentEncounter->defeatFlags[mapID][encounterIdx] & (1 << encounterShift);
208}
EncounterStatus gCurrentEncounter
Definition encounter.c:176
s32 defeatFlags[60][12]
Definition npc.h:403

Referenced by create_encounters().

◆ set_defeated()

void set_defeated ( s32 mapID,
s32 encounterID )

Definition at line 210 of file encounter.c.

210 {
211 EncounterStatus* currentEncounter = &gCurrentEncounter;
212 s32 encounterIdx = encounterID / 32;
213 s32 encounterShift;
214 s32 flag;
215
216 flag = encounterID % 32;
217 encounterShift = flag;
218 flag = currentEncounter->defeatFlags[mapID][encounterIdx];
219 currentEncounter->defeatFlags[mapID][encounterIdx] = flag | (1 << encounterShift);
220
221 // TODO: The below should work but has regalloc issues:
222 /*EncounterStatus *currentEncounter = &gCurrentEncounter;
223 s32 encounterIdx = encounterID / 32;
224 s32 encounterShift = encounterID % 32;
225
226 currentEncounter->defeatFlags[mapID][encounterIdx] |= (1 << encounterShift);*/
227}

Referenced by update_encounters_post_battle().

◆ update_encounters_neutral()

void update_encounters_neutral ( void )

Definition at line 481 of file encounter.c.

481 {
482 EncounterStatus* currentEncounter = &gCurrentEncounter;
483 PlayerStatus* playerStatus = &gPlayerStatus;
484 Camera* camera = &gCameras[gCurrentCameraID];
485 s32 screenX, screenY, screenZ;
486 f32 npcX, npcY, npcZ;
487 f32 npcYaw;
488 f32 testX, testY, testZ;
489 f32 x, y, z;
490 s32 e;
491 f32 playerX, playerY, playerZ;
492 f32 playerYaw;
493 Encounter* encounter;
494 Evt* script;
495 Npc* npc;
496 f32 distance;
497 f32 colHeight;
498 f32 colRadius;
499 f32 hammerDir;
500
501 s32 triggeredBattle;
502 s32 cond2;
503 s32 firstStrikeType;
504 s32 suspendTime;
505
506 Enemy* enemy;
507 Enemy* currentEnemy;
508 s32 i;
509
510 f32 playerJumpColHeight = 37.0f;
511 f32 playerColRadius = 14.0f;
512 f32 playerColHeight = 18.0f;
513
514 f32 dx, dz;
515 f32 angle1, angle2;
516
517 if (currentEncounter->hitType == ENCOUNTER_TRIGGER_CONVERSATION) {
518 goto START_BATTLE;
519 }
520
521 currentEncounter->songID = -1;
522 currentEncounter->unk_18 = -1;
523 currentEncounter->hitType = 0;
524 currentEncounter->forbidFleeing = FALSE;
525 currentEncounter->dropWhackaBump = FALSE;
526 currentEncounter->flags &= ~ENCOUNTER_FLAG_THUMBS_UP;
527 currentEncounter->flags &= ~ENCOUNTER_FLAG_CANT_SKIP_WIN_DELAY;
528 currentEncounter->flags &= ~ENCOUNTER_FLAG_SKIP_FLEE_DROPS;
529
530 playerX = playerStatus->pos.x;
531 playerY = playerStatus->pos.y;
532 playerZ = playerStatus->pos.z;
533 playerYaw = playerStatus->spriteFacingAngle;
534
535 if (playerYaw < 180.0f) {
536 playerYaw = clamp_angle(camera->curYaw - 90.0f);
537 } else {
538 playerYaw = clamp_angle(camera->curYaw + 90.0f);
539 }
540
541 if (currentEncounter->battleTriggerCooldown != 0) {
543 currentEncounter->battleTriggerCooldown--;
544 }
545 if (playerStatus->blinkTimer != 0) {
546 if (!(playerStatus->flags & PS_FLAG_INPUT_DISABLED)) {
547 playerStatus->blinkTimer = currentEncounter->battleTriggerCooldown;
548 } else {
549 playerStatus->blinkTimer = 1;
550 }
551 }
552 }
553
554 for (e = 0; e < currentEncounter->numEncounters; e++) {
555 encounter = currentEncounter->encounterList[e];
556 if (encounter == NULL) {
557 continue;
558 }
559 for (i = 0; i < encounter->count; i++) {
560 enemy = encounter->enemy[i];
561 if (enemy == NULL || (enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
562 continue;
563 }
564 npc = get_npc_unsafe(enemy->npcID);
565 if (enemy->aiSuspendTime != 0) {
567 enemy->aiSuspendTime--;
568 suspendTime = enemy->aiSuspendTime;
569 } else {
570 suspendTime = 0;
571 }
572
573 if (suspendTime & 1) {
575 enemy->flags |= ENEMY_FLAG_SUSPENDED;
576 } else {
577 npc->flags &= ~NPC_FLAG_SUSPENDED;
578 enemy->flags &= ~ENEMY_FLAG_SUSPENDED;
579 }
580
581 script = get_script_by_id(enemy->auxScriptID);
582 if (script != NULL) {
584 }
585 script = get_script_by_id(enemy->aiScriptID);
586 if (script != NULL) {
588 }
589
591 script = get_script_by_id(enemy->auxScriptID);
592 if (script != NULL) {
594 }
595 script = get_script_by_id(enemy->aiScriptID);
596 if (script != NULL) {
598 }
599 }
600 } else if (!(enemy->flags & ENEMY_FLAG_ACTIVE_WHILE_OFFSCREEN)) {
601 get_screen_coords(gCurrentCameraID, npc->pos.x, npc->pos.y, npc->pos.z, &screenX, &screenY, &screenZ);
602 if ((screenX < -160 || screenX > 480 || screenY < -120 || screenY > 360 || screenZ < 0) && !(enemy->flags & ENEMY_FLAG_PASSIVE)) {
604 enemy->flags |= ENEMY_FLAG_SUSPENDED;
605 script = get_script_by_id(enemy->auxScriptID);
606 if (script != NULL) {
608 }
609 script = get_script_by_id(enemy->aiScriptID);
610 if (script != NULL) {
612 }
613 } else {
614 npc->flags &= ~NPC_FLAG_SUSPENDED;
615 enemy->flags &= ~ENEMY_FLAG_SUSPENDED;
616 script = get_script_by_id(enemy->auxScriptID);
617 if (script != NULL) {
619 }
620 script = get_script_by_id(enemy->aiScriptID);
621 if (script != NULL) {
623 }
624 }
625 } else {
626 npc->flags &= ~NPC_FLAG_SUSPENDED;
627 enemy->flags &= ~ENEMY_FLAG_SUSPENDED;
628 script = get_script_by_id(enemy->auxScriptID);
629 if (script != NULL) {
631 }
632 script = get_script_by_id(enemy->aiScriptID);
633 if (script != NULL) {
635 }
636 }
637
638 if (enemy->flags & ENEMY_FLAG_SUSPENDED) {
639 continue;
640 }
641 if (enemy->flags & ENEMY_FLAG_PASSIVE) {
643 if (npc == playerStatus->encounteredNPC) {
644 enemy->savedNpcYaw = npc->yaw;
645 npc->yaw = atan2(npc->pos.x, npc->pos.z, playerStatus->pos.x, playerStatus->pos.z);
646 script = get_script_by_id(enemy->aiScriptID);
647 if (script != NULL) {
649 }
650 } else {
651 if (enemy->savedNpcYaw != 12345) {
652 npc->yaw = enemy->savedNpcYaw;
653 enemy->savedNpcYaw = 12345;
654 }
655 script = get_script_by_id(enemy->aiScriptID);
656 if (script != NULL) {
658 }
659 }
660 } else {
661 script = get_script_by_id(enemy->aiScriptID);
662 if (script != NULL) {
664 }
665 }
666 }
667
668 if (currentEncounter->battleTriggerCooldown != 0
670 || (playerStatus->flags & PS_FLAG_ARMS_RAISED)
673 || (enemy->flags & ENEMY_FLAG_PASSIVE)
676 ) {
677 continue;
678 }
679
681 currentEncounter->hitType = ENCOUNTER_TRIGGER_PARTNER;
683 currentEncounter->curEncounter = encounter;
684 currentEncounter->curEnemy = enemy;
685 currentEncounter->firstStrikeType = FIRST_STRIKE_PLAYER;
686 goto START_BATTLE;
687 }
688
689 npcX = npc->pos.x;
690 npcY = npc->pos.y;
691 npcZ = npc->pos.z;
692 npcYaw = npc->yaw;
693 colHeight = npc->collisionHeight;
694 colRadius = npc->collisionDiameter / 2;
695
696 if (enemy->unk_DC != 0) {
697 npcYaw = npc->yawCamOffset;
698 if (npcYaw < 180.0f) {
699 npcYaw = clamp_angle(camera->curYaw - 90.0f);
700 } else {
701 npcYaw = clamp_angle(camera->curYaw + 90.0f);
702 }
703
704 add_vec2D_polar(&npcX, &npcZ, enemy->unk_DC, npcYaw);
705 }
706
707 dx = npcX - playerX;
708 dz = npcZ - playerZ;
709 distance = sqrtf(SQ(dx) + SQ(dz));
710
711 switch (playerStatus->actionState) {
713 x = playerX;
714 y = playerY;
715 z = playerZ;
716 if (clamp_angle(playerStatus->spriteFacingAngle) < 180.0f) {
717 hammerDir = clamp_angle(camera->curYaw - 90.0f);
718 if (playerStatus->trueAnimation & SPRITE_ID_BACK_FACING) {
719 hammerDir = clamp_angle(hammerDir + 30.0f);
720 }
721 } else {
722 hammerDir = clamp_angle(camera->curYaw + 90.0f);
723 if (playerStatus->trueAnimation & SPRITE_ID_BACK_FACING) {
724 hammerDir = clamp_angle(hammerDir - 30.0f);
725 }
726 }
727 add_vec2D_polar(&x, &z, 24.0f, hammerDir);
728 dx = npcX - x;
729 dz = npcZ - z;
730 distance = sqrtf(SQ(dx) + SQ(dz));
731 if (enemy->flags & ENEMY_FLAG_IGNORE_HAMMER) {
732 break;
733 }
734 if (!(playerStatus->flags & PS_FLAG_HAMMER_CHECK)) {
735 break;
736 }
737 if (distance >= playerColRadius + colRadius || y > npcY + colHeight || npcY > y + playerColHeight) {
738 break;
739 }
740
741 testX = npcX;
742 testY = npcY;
743 testZ = npcZ;
744
745 if (npc_test_move_taller_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &testX, &testY, &testZ, distance, atan2(npcX, npcZ, playerX, playerZ), colHeight, colRadius * 2.0f)) {
746 testX = playerX;
747 testY = playerY;
748 testZ = playerZ;
749 if (npc_test_move_taller_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &testX, &testY, &testZ, distance, atan2(playerX, playerZ, npcX, npcZ), colHeight, colRadius * 2.0f)) {
750 break;
751 }
752 }
753 if (enemy->hitboxIsActive) {
754 npcX = enemy->unk_10.x;
755 npcY = enemy->unk_10.y;
756 npcZ = enemy->unk_10.z;
757 }
758
759 angle1 = fabsf(get_clamped_angle_diff(atan2(playerX, playerZ, npcX, npcZ), playerYaw));
760 angle2 = fabsf(get_clamped_angle_diff(atan2(npcX, npcZ, playerX, playerZ), npcYaw));
761 triggeredBattle = FALSE;
762 if (angle1 >= 90.0f && angle2 >= 90.0f) {
763 triggeredBattle = FALSE;
764 }
765 if (angle1 < 90.0f && angle2 >= 90.0f) {
766 triggeredBattle = TRUE;
767 }
768 if (angle1 >= 90.0f && angle2 < 90.0f) {
769 triggeredBattle = FALSE;
770 }
771 if (angle1 < 90.0f && angle2 < 90.0f) {
772 triggeredBattle = TRUE;
773 }
774 if (triggeredBattle) {
775 sfx_play_sound_at_position(SOUND_HIT_PLAYER_NORMAL, SOUND_SPACE_DEFAULT, playerStatus->pos.x, playerStatus->pos.y, playerStatus->pos.z);
776 currentEncounter->hitType = ENCOUNTER_TRIGGER_HAMMER;
777 currentEncounter->hitTier = gPlayerData.hammerLevel;
779 currentEncounter->curEncounter = encounter;
780 currentEncounter->curEnemy = enemy;
781 currentEncounter->firstStrikeType = FIRST_STRIKE_PLAYER;
782 goto START_BATTLE;
783 }
784 break;
795 x = playerX;
796 z = playerZ;
797 if (!(enemy->flags & ENEMY_FLAG_IGNORE_JUMP)) {
798 if (distance >= playerColRadius + colRadius) {
799 continue;
800 }
801 if (playerY > npcY + colHeight || npcY > playerY + playerJumpColHeight) {
802 continue;
803 }
804
805 testX = npcX;
806 testY = npcY;
807 testZ = npcZ;
808 if (npc_test_move_taller_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &testX, &testY, &testZ, distance, atan2(npcX, npcZ, playerX, playerZ), colHeight, colRadius * 2.0f)) {
809 testX = playerX;
810 testY = playerY;
811 testZ = playerZ;
812 if (npc_test_move_taller_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &testX, &testY, &testZ, distance, atan2(playerX, playerZ, npcX, npcZ), colHeight, colRadius * 2.0f)) {
813 break;
814 }
815 }
816 triggeredBattle = FALSE;
817 if (npcY + colHeight < playerY + playerJumpColHeight * 0.5f) {
818 if (playerStatus->actionState == ACTION_STATE_FALLING ||
819 playerStatus->actionState == ACTION_STATE_STEP_DOWN ||
820 playerStatus->actionState == ACTION_STATE_LAND ||
821 playerStatus->actionState == ACTION_STATE_STEP_DOWN_LAND ||
822 playerStatus->actionState == ACTION_STATE_SPIN_JUMP ||
823 playerStatus->actionState == ACTION_STATE_SPIN_POUND ||
824 playerStatus->actionState == ACTION_STATE_TORNADO_JUMP ||
825 playerStatus->actionState == ACTION_STATE_TORNADO_POUND) {
826 triggeredBattle = TRUE;
827 }
828 }
829 if (playerY + playerJumpColHeight < npcY + colHeight * 0.5f) {
830 triggeredBattle = FALSE;
831 }
832 if (triggeredBattle) {
833 if (gPlayerData.bootsLevel < 0) {
834 currentEncounter->hitType = ENCOUNTER_TRIGGER_NONE;
836 currentEncounter->curEncounter = encounter;
837 currentEncounter->curEnemy = enemy;
838 currentEncounter->firstStrikeType = FIRST_STRIKE_NONE;
839 currentEncounter->hitTier = 0;
840 goto START_BATTLE;
841 }
842 currentEncounter->hitType = ENCOUNTER_TRIGGER_JUMP;
843 switch (playerStatus->actionState) {
850 currentEncounter->hitTier = 0;
851 break;
854 currentEncounter->hitTier = 1;
855 break;
858 currentEncounter->hitTier = 2;
859 break;
860 }
861 sfx_play_sound_at_position(SOUND_HIT_PLAYER_NORMAL, SOUND_SPACE_DEFAULT, playerStatus->pos.x, playerStatus->pos.y, playerStatus->pos.z);
863 currentEncounter->curEncounter = encounter;
864 currentEncounter->curEnemy = enemy;
865 currentEncounter->firstStrikeType = FIRST_STRIKE_PLAYER;
866 goto START_BATTLE;
867 }
868 }
869 break;
870 }
871
872 if (enemy->flags & ENEMY_FLAG_IGNORE_TOUCH) {
873 continue;
874 }
875
876 dx = npcX - playerX;
877 dz = npcZ - playerZ;
878 distance = sqrtf(SQ(dx) + SQ(dz));
879
880 if (distance >= (playerColRadius + colRadius) * 0.8) {
881 continue;
882 }
883 if (npcY + colHeight < playerY) {
884 continue;
885 }
886 if (playerY + playerJumpColHeight < npcY) {
887 continue;
888 }
889
890 testX = npcX;
891 testY = npcY;
892 testZ = npcZ;
893 if (npc_test_move_taller_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &testX, &testY, &testZ, distance, atan2(npcX, npcZ, playerX, playerZ), colHeight, colRadius * 2.0f)) {
894 testX = playerX;
895 testY = playerY;
896 testZ = playerZ;
897 if (npc_test_move_taller_with_slipping(COLLIDER_FLAG_IGNORE_PLAYER, &testX, &testY, &testZ, distance, atan2(playerX, playerZ, npcX, npcZ), colHeight, colRadius * 2.0f)) {
898 continue;
899 }
900 }
901 triggeredBattle = FALSE;
903 triggeredBattle = !currentEncounter->scriptedBattle;
904 }
906 triggeredBattle = TRUE;
907 }
908 if ((playerStatus->animFlags & PA_FLAG_SPINNING) && !(enemy->flags & ENEMY_FLAG_IGNORE_SPIN) && triggeredBattle) {
909 sfx_play_sound_at_position(SOUND_HIT_PLAYER_NORMAL, SOUND_SPACE_DEFAULT, playerStatus->pos.x, playerStatus->pos.y, playerStatus->pos.z);
910 testX = playerStatus->pos.x + ((npc->pos.x - playerStatus->pos.x) * 0.5f);
911 testY = playerStatus->pos.y + (((npc->pos.y + npc->collisionHeight) - (playerStatus->pos.y + playerStatus->colliderHeight)) * 0.5f);
912 testZ = playerStatus->pos.z + ((npc->pos.z - playerStatus->pos.z) * 0.5f);
913 fx_damage_stars(FX_DAMAGE_STARS_3, testX, testY, testZ, 0.0f, -1.0f, 0.0f, 3);
914 currentEncounter->hitType = ENCOUNTER_TRIGGER_SPIN;
917 currentEncounter->curEncounter = encounter;
918 currentEncounter->curEnemy = enemy;
919 currentEncounter->firstStrikeType = FIRST_STRIKE_NONE;
920 } else {
921 currentEncounter->hitType = ENCOUNTER_TRIGGER_NONE;
922 playerStatus->animFlags &= ~PA_FLAG_DIZZY_ATTACK_ENCOUNTER;
924 currentEncounter->curEncounter = encounter;
925 currentEncounter->curEnemy = enemy;
926 testX = playerStatus->pos.x + ((npc->pos.x - playerStatus->pos.x) * 0.5f);
927 testY = playerStatus->pos.y + (((npc->pos.y + npc->collisionHeight) - (playerStatus->pos.y + playerStatus->colliderHeight)) * 0.5f);
928 testZ = playerStatus->pos.z + ((npc->pos.z - playerStatus->pos.z) * 0.5f);
929 fx_damage_stars(FX_DAMAGE_STARS_3, testX, testY, testZ, 0.0f, -1.0f, 0.0f, 3);
930 // if the hitbox is active, trigger a first strike
931 firstStrikeType = FIRST_STRIKE_NONE;
932 if (enemy->hitboxIsActive) {
934 firstStrikeType = FIRST_STRIKE_NONE;
935 } else {
936 firstStrikeType = FIRST_STRIKE_ENEMY;
937 }
938 }
939 // cancel the first strike if bump attack is applicable
941 && (gPlayerData.level >= enemy->npcSettings->level)
942 && !(enemy->flags & ENEMY_FLAG_PROJECTILE))
943 && !currentEncounter->scriptedBattle
944 ) {
945 firstStrikeType = FIRST_STRIKE_NONE;
946 }
947 currentEncounter->firstStrikeType = firstStrikeType;
948 }
949 goto START_BATTLE;
950 }
951 }
952
953START_BATTLE:
954 switch (currentEncounter->hitType) {
955 case 0:
956 break;
958 currentEnemy = enemy = currentEncounter->curEnemy;
959 if (enemy->aiScript != NULL) {
961 }
962 if (enemy->auxScript != NULL) {
964 }
965 encounter = currentEncounter->curEncounter;
966 for (i = 0; i < encounter->count; i++) {
967 enemy = encounter->enemy[i];
968 if (enemy == NULL) {
969 continue;
970 }
971 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
972 continue;
973 }
974 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
975 continue;
976 }
977 if ((currentEnemy->flags & ENEMY_FLAG_PROJECTILE) && enemy != currentEncounter->curEnemy) {
978 continue;
979 }
980
981 if (enemy->hitBytecode != NULL) {
983 script = start_script(enemy->hitBytecode, EVT_PRIORITY_A, 0);
984 enemy->hitScript = script;
985 enemy->hitScriptID = script->id;
986 script->owner1.enemy = enemy;
987 script->owner2.npcID = enemy->npcID;
988 script->groupFlags = enemy->scriptGroup;
989 }
990 }
993 if (playerStatus->actionState != ACTION_STATE_TORNADO_JUMP &&
994 playerStatus->actionState != ACTION_STATE_TORNADO_POUND &&
995 playerStatus->actionState != ACTION_STATE_SPIN_JUMP &&
996 playerStatus->actionState != ACTION_STATE_SPIN_POUND) {
997 playerStatus->flags |= PS_FLAG_ENTERING_BATTLE;
998 }
1001 npc = get_npc_unsafe(enemy->npcID);
1003 }
1004 currentEncounter->scriptedBattle = FALSE;
1005 currentEncounter->fadeOutAmount = 0;
1006 currentEncounter->substateDelay = 0;
1008 EncounterStateChanged = TRUE;
1010 break;
1012 currentEnemy = enemy = currentEncounter->curEnemy;
1013 if (enemy->aiScript != NULL) {
1015 }
1016 if (enemy->auxScript != NULL) {
1018 }
1019 encounter = currentEncounter->curEncounter;
1020 for (i = 0; i < encounter->count; i++) {
1021 enemy = encounter->enemy[i];
1022 if (enemy == NULL) {
1023 continue;
1024 }
1025 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
1026 continue;
1027 }
1028 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
1029 continue;
1030 }
1031 if ((currentEnemy->flags & ENEMY_FLAG_PROJECTILE) && enemy != currentEncounter->curEnemy) {
1032 continue;
1033 }
1034
1035 if (enemy->hitBytecode != NULL) {
1037 script = start_script(enemy->hitBytecode, EVT_PRIORITY_A, 0);
1038 enemy->hitScript = script;
1039 enemy->hitScriptID = script->id;
1040 script->owner1.enemy = enemy;
1041 script->owner2.npcID = enemy->npcID;
1042 script->groupFlags = enemy->scriptGroup;
1043 }
1044 }
1047 currentEncounter->scriptedBattle = FALSE;
1048 currentEncounter->fadeOutAmount = 0;
1049 currentEncounter->substateDelay = 0;
1051 EncounterStateChanged = TRUE;
1053 playerStatus->flags |= PS_FLAG_ENTERING_BATTLE;
1054 break;
1056 currentEnemy = enemy = currentEncounter->curEnemy;
1057 if (enemy->aiScript != NULL) {
1059 }
1060 if (enemy->auxScript != NULL) {
1062 }
1063 encounter = currentEncounter->curEncounter;
1064
1065 cond2 = FALSE;
1066 for (i = 0; i < encounter->count; i++) {
1067 enemy = encounter->enemy[i];
1068 enemy = encounter->enemy[i];
1069 if (enemy == NULL) {
1070 continue;
1071 }
1072 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
1073 continue;
1074 }
1075 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
1076 continue;
1077 }
1078 if ((currentEnemy->flags & ENEMY_FLAG_PROJECTILE) && enemy != currentEncounter->curEnemy) {
1079 continue;
1080 }
1081 if (enemy->hitBytecode != NULL) {
1083 script = start_script(enemy->hitBytecode, EVT_PRIORITY_A, 0);
1084 enemy->hitScript = script;
1085 enemy->hitScriptID = script->id;
1086 script->owner1.enemy = enemy;
1087 script->owner2.npcID = enemy->npcID;
1088 script->groupFlags = enemy->scriptGroup;
1089 npc = get_npc_unsafe(enemy->npcID);
1090 cond2 = TRUE;
1091 testX = playerStatus->pos.x + ((npc->pos.x - playerStatus->pos.x) * 0.5f);
1092 testY = playerStatus->pos.y + (((npc->pos.y + npc->collisionHeight) - (playerStatus->pos.y + playerStatus->colliderHeight)) * 0.5f);
1093 testZ = playerStatus->pos.z + ((npc->pos.z - playerStatus->pos.z) * 0.5f);
1094 fx_damage_stars(FX_DAMAGE_STARS_3, testX, testY, testZ, 0.0f, -1.0f, 0.0f, 3);
1095 } else if (!(enemy->flags & ENEMY_FLAG_PASSIVE)) {
1096 npc = get_npc_unsafe(enemy->npcID);
1097 cond2 = TRUE;
1098 testX = playerStatus->pos.x + ((npc->pos.x - playerStatus->pos.x) * 0.5f);
1099 testY = playerStatus->pos.y + (((npc->pos.y + npc->collisionHeight) - (playerStatus->pos.y + playerStatus->colliderHeight)) * 0.5f);
1100 testZ = playerStatus->pos.z + ((npc->pos.z - playerStatus->pos.z) * 0.5f);
1101 fx_damage_stars(FX_DAMAGE_STARS_3, testX, testY, testZ, 0.0f, -1.0f, 0.0f, 3);
1102 }
1103 }
1106 playerStatus->flags |= PS_FLAG_ENTERING_BATTLE;
1107 if (cond2) {
1109 }
1110 currentEncounter->fadeOutAmount = 0;
1111 currentEncounter->substateDelay = 0;
1112 currentEncounter->scriptedBattle = FALSE;
1115 EncounterStateChanged = TRUE;
1117 break;
1119 currentEnemy = enemy = currentEncounter->curEnemy;
1120 if (enemy->aiScript != NULL) {
1122 }
1123 if (enemy->auxScript != NULL) {
1125 }
1126 encounter = currentEncounter->curEncounter;
1127 for (i = 0; i < encounter->count; i++) {
1128 enemy = encounter->enemy[i];
1129 if (enemy == NULL) {
1130 continue;
1131 }
1132 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
1133 continue;
1134 }
1135 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
1136 continue;
1137 }
1138 if ((currentEnemy->flags & ENEMY_FLAG_PROJECTILE) && enemy != currentEncounter->curEnemy) {
1139 continue;
1140 }
1141 if (enemy->hitBytecode != NULL) {
1143 script = start_script(enemy->hitBytecode, EVT_PRIORITY_A, 0);
1144 enemy->hitScript = script;
1145 enemy->hitScriptID = script->id;
1146 script->owner1.enemy = enemy;
1147 script->owner2.npcID = enemy->npcID;
1148 script->groupFlags = enemy->scriptGroup;
1149 npc = get_npc_unsafe(enemy->npcID);
1150 testX = playerStatus->pos.x + ((npc->pos.x - playerStatus->pos.x) * 0.5f);
1151 testY = playerStatus->pos.y + (((npc->pos.y + npc->collisionHeight) - (playerStatus->pos.y + playerStatus->colliderHeight)) * 0.5f);
1152 testZ = playerStatus->pos.z + ((npc->pos.z - playerStatus->pos.z) * 0.5f);
1153 fx_damage_stars(FX_DAMAGE_STARS_3, testX, testY, testZ, 0.0f, -1.0f, 0.0f, 3);
1154 } else if (!(enemy->flags & ENEMY_FLAG_PASSIVE)) {
1155 npc = get_npc_unsafe(enemy->npcID);
1156 testX = playerStatus->pos.x + ((npc->pos.x - playerStatus->pos.x) * 0.5f);
1157 testY = playerStatus->pos.y + (((npc->pos.y + npc->collisionHeight) - (playerStatus->pos.y + playerStatus->colliderHeight)) * 0.5f);
1158 testZ = playerStatus->pos.z + ((npc->pos.z - playerStatus->pos.z) * 0.5f);
1159 fx_damage_stars(FX_DAMAGE_STARS_3, npc->pos.x, npc->pos.y + npc->collisionHeight, npc->pos.z, 0.0f, -1.0f, 0.0f, 3);
1160 }
1161 }
1164 currentEncounter->fadeOutAmount = 0;
1165 currentEncounter->substateDelay = 0;
1166 currentEncounter->scriptedBattle = FALSE;
1167 playerStatus->flags |= PS_FLAG_ENTERING_BATTLE;
1170 EncounterStateChanged = TRUE;
1172 break;
1175 enemy = currentEncounter->curEnemy;
1176 if (enemy != NULL && enemy->aiScript != NULL) {
1178 }
1179 enemy = currentEncounter->curEnemy;
1180 if (enemy->interactBytecode != NULL) {
1182 script = start_script(enemy->interactBytecode, EVT_PRIORITY_A, 0);
1183 enemy->interactScript = script;
1184 enemy->interactScriptID = script->id;
1185 script->owner1.enemy = enemy;
1186 script->owner2.npcID = enemy->npcID;
1187 script->groupFlags = enemy->scriptGroup;
1188 }
1192 currentEncounter->fadeOutAmount = 0;
1193 currentEncounter->substateDelay = 0;
1194 func_800EF3D4(1);
1196 EncounterStateChanged = TRUE;
1198 break;
1200 currentEnemy = enemy = currentEncounter->curEnemy;
1201 if (enemy->aiScript != NULL) {
1203 }
1204 if (enemy->auxScript != NULL) {
1206 }
1207 encounter = currentEncounter->curEncounter;
1208
1209 for (i = 0; i < encounter->count; i++) {
1210 enemy = encounter->enemy[i];
1211 if (enemy == NULL) {
1212 continue;
1213 }
1214 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
1215 continue;
1216 }
1217 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
1218 continue;
1219 }
1220 if ((currentEnemy->flags & ENEMY_FLAG_PROJECTILE) && enemy != currentEncounter->curEnemy) {
1221 continue;
1222 }
1223 if (enemy->hitBytecode != NULL) {
1225 script = start_script(enemy->hitBytecode, EVT_PRIORITY_A, 0);
1226 enemy->hitScript = script;
1227 enemy->hitScriptID = script->id;
1228 script->owner1.enemy = enemy;
1229 script->owner2.npcID = enemy->npcID;
1230 script->groupFlags = enemy->scriptGroup;
1231 npc = get_npc_unsafe(enemy->npcID);
1232 testX = npc->pos.x;
1233 testY = npc->pos.y + npc->collisionHeight;
1234 testZ = npc->pos.z;
1235 fx_damage_stars(FX_DAMAGE_STARS_3, testX, testY, testZ, 0.0f, -1.0f, 0.0f, 3);
1236 } else if (!(enemy->flags & ENEMY_FLAG_PASSIVE)) {
1237 npc = get_npc_unsafe(enemy->npcID);
1238 testX = npc->pos.x;
1239 testY = npc->pos.y + npc->collisionHeight;
1240 testZ = npc->pos.z;
1241 fx_damage_stars(FX_DAMAGE_STARS_3, testX, testY, testZ, 0.0f, -1.0f, 0.0f, 3);
1242 }
1243 }
1246 currentEncounter->fadeOutAmount = 0;
1247 currentEncounter->substateDelay = 0;
1248 currentEncounter->scriptedBattle = FALSE;
1249 playerStatus->flags |= PS_FLAG_ENTERING_BATTLE;
1252 EncounterStateChanged = TRUE;
1254 break;
1255 }
1256}
AnimID trueAnimation
Encoding back-facing sprite.
union Evt::@8 owner1
Initially -1.
#define sfx_play_sound_at_position
#define sqrtf
#define clamp_angle
#define atan2
@ FX_DAMAGE_STARS_3
Definition effects.h:359
s32 gEncounterState
Definition encounter.c:174
b32 EncounterStateChanged
Definition encounter.c:24
s32 gEncounterSubState
Definition encounter.c:175
@ DEBUG_CONTACT_CANT_TOUCH
Definition enums.h:4268
@ ENCOUNTER_SUBSTATE_CONVERSATION_INIT
Definition enums.h:6320
@ PS_FLAG_ENTERING_BATTLE
Definition enums.h:3061
@ PS_FLAG_ARMS_RAISED
Definition enums.h:3063
@ PS_FLAG_HAMMER_CHECK
Definition enums.h:3073
@ PS_FLAG_INPUT_DISABLED
Definition enums.h:3052
@ ENCOUNTER_TRIGGER_CONVERSATION
Definition enums.h:272
@ ENCOUNTER_TRIGGER_JUMP
Definition enums.h:269
@ ENCOUNTER_TRIGGER_HAMMER
Definition enums.h:271
@ ENCOUNTER_TRIGGER_NONE
Definition enums.h:268
@ ENCOUNTER_TRIGGER_PARTNER
Definition enums.h:273
@ ENCOUNTER_TRIGGER_SPIN
Definition enums.h:270
@ ENEMY_FLAG_DISABLE_AI
Definition enums.h:4526
@ ENEMY_FLAG_IGNORE_HAMMER
Definition enums.h:4547
@ ENEMY_FLAG_DO_NOT_AUTO_FACE_PLAYER
Definition enums.h:4543
@ ENEMY_FLAG_PASSIVE
Definition enums.h:4521
@ ENEMY_FLAG_IGNORE_PARTNER
Definition enums.h:4549
@ ENEMY_FLAG_ENABLE_HIT_SCRIPT
Definition enums.h:4524
@ ENEMY_FLAG_PROJECTILE
Definition enums.h:4527
@ ENEMY_FLAG_DONT_SUSPEND_SCRIPTS
Definition enums.h:4540
@ ENEMY_FLAG_IGNORE_SPIN
Definition enums.h:4550
@ ENEMY_FLAG_SUSPENDED
Definition enums.h:4552
@ ENEMY_FLAG_IGNORE_TOUCH
Definition enums.h:4545
@ ENEMY_FLAG_IGNORE_JUMP
Definition enums.h:4546
@ ENEMY_FLAG_ACTIVE_WHILE_OFFSCREEN
Definition enums.h:4542
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4696
@ PA_FLAG_DIZZY_ATTACK_ENCOUNTER
Definition enums.h:3109
@ PA_FLAG_SPINNING
Definition enums.h:3107
@ ENCOUNTER_SUBSTATE_PRE_BATTLE_INIT
Definition enums.h:6313
@ ABILITY_BUMP_ATTACK
Definition enums.h:478
@ ABILITY_SPIN_ATTACK
Definition enums.h:476
@ ABILITY_CHILL_OUT
Definition enums.h:453
@ ABILITY_DIZZY_ATTACK
Definition enums.h:481
@ SOUND_NONE
Definition enums.h:547
@ SOUND_HIT_PLAYER_NORMAL
Definition enums.h:719
@ PARTNER_BOW
Definition enums.h:2894
@ ACTION_STATE_JUMP
Definition enums.h:2430
@ ACTION_STATE_STEP_DOWN_LAND
Definition enums.h:2438
@ ACTION_STATE_SPIN_POUND
Definition enums.h:2442
@ ACTION_STATE_SPIN_JUMP
Definition enums.h:2441
@ ACTION_STATE_TALK
Reading signs doesn't count.
Definition enums.h:2440
@ ACTION_STATE_TORNADO_POUND
Definition enums.h:2444
@ ACTION_STATE_FALLING
Definition enums.h:2435
@ ACTION_STATE_LAND
Definition enums.h:2437
@ ACTION_STATE_ENEMY_FIRST_STRIKE
Definition enums.h:2455
@ ACTION_STATE_BOUNCE
Used with Kooper.
Definition enums.h:2431
@ ACTION_STATE_STEP_DOWN
Definition enums.h:2436
@ ACTION_STATE_HAMMER
Definition enums.h:2446
@ ACTION_STATE_TORNADO_JUMP
Definition enums.h:2443
@ ENCOUNTER_STATE_CONVERSATION
Definition enums.h:6298
@ ENCOUNTER_STATE_NEUTRAL
Definition enums.h:6296
@ ENCOUNTER_STATE_PRE_BATTLE
Definition enums.h:6297
@ FIRST_STRIKE_NONE
Definition enums.h:3458
@ FIRST_STRIKE_ENEMY
Definition enums.h:3460
@ FIRST_STRIKE_PLAYER
Definition enums.h:3459
@ SOUND_SPACE_DEFAULT
Definition enums.h:1737
@ GLOBAL_OVERRIDES_40
Definition enums.h:4325
@ GLOBAL_OVERRIDES_800
Definition enums.h:4330
@ GLOBAL_OVERRIDES_200
Definition enums.h:4328
@ GLOBAL_OVERRIDES_400
Definition enums.h:4329
@ GLOBAL_OVERRIDES_DISABLE_BATTLES
Definition enums.h:4327
@ NPC_FLAG_SUSPENDED
Definition enums.h:3029
@ EVT_PRIORITY_A
Definition evt.h:153
@ EVT_GROUP_FLAG_INTERACT
Definition evt.h:134
@ EVT_FLAG_SUSPENDED
doesn't affect child
Definition evt.h:163
f32 fabsf(f32 f)
void get_screen_coords(s32 camID, f32 x, f32 y, f32 z, s32 *screenX, s32 *screenY, s32 *screenZ)
Definition cam_main.c:410
void partner_disable_input(void)
Definition partners.c:2489
void func_800EF3D4(s32)
Definition partners.c:2414
s32 disable_player_input(void)
Definition 77480.c:990
s32 suspend_all_script(s32 id)
void set_script_flags(Evt *script, s32 flags)
s32 is_picking_up_item(void)
void set_action_state(s32 actionState)
Definition 7E9D0.c:209
void clear_script_flags(Evt *script, s32 flags)
s32 partner_test_enemy_collision(Npc *enemy)
Definition partners.c:1051
b32 npc_test_move_taller_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
void start_bounce_a(void)
Definition 7E9D0.c:300
void add_vec2D_polar(f32 *x, f32 *y, f32 r, f32 theta)
Definition 43F0.c:685
Evt * get_script_by_id(s32 id)
f32 get_clamped_angle_diff(f32, f32)
Definition 43F0.c:606
void suspend_all_group(s32 groupFlags)
struct Evt * interactScript
Definition npc.h:312
s8 scriptedBattle
battle started by StartBattle but not by encounter
Definition npc.h:380
s16 savedNpcYaw
Definition npc.h:346
s16 npcID
Definition npc.h:300
s32 interactScriptID
Definition npc.h:318
struct Evt * hitScript
Definition npc.h:314
EvtScript * hitBytecode
Definition npc.h:308
u8 scriptGroup
Definition npc.h:298
s32 auxScriptID
Definition npc.h:321
Encounter * encounterList[24]
Definition npc.h:392
s8 battleTriggerCooldown
set to 15 after victory, 45 after fleeing
Definition npc.h:373
Enemy * curEnemy
Definition npc.h:394
s8 numEncounters
Definition npc.h:384
Enemy * enemy[16]
Definition npc.h:352
s8 aiSuspendTime
Definition npc.h:333
s32 unk_DC
Definition npc.h:345
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
Vec3s unk_10
Definition npc.h:302
s32 count
Definition npc.h:351
s8 forbidFleeing
Definition npc.h:379
s8 hitboxIsActive
Definition npc.h:299
EvtScript * interactBytecode
Definition npc.h:306
s32 aiScriptID
Definition npc.h:319
s32 fadeOutAmount
Definition npc.h:395
NpcSettings * npcSettings
Definition npc.h:304
s8 dropWhackaBump
Definition npc.h:381
s16 level
Definition npc.h:155
struct Evt * auxScript
Definition npc.h:315
s8 encountered
Definition npc.h:297
s8 firstStrikeType
Definition npc.h:367
s32 substateDelay
Definition npc.h:396
Encounter * curEncounter
Definition npc.h:393
struct Evt * aiScript
Definition npc.h:313
s32 hitScriptID
Definition npc.h:320
Definition npc.h:294
void sfx_play_sound(s32 soundID)
Definition sfx.c:517
#define SQ(x)
Definition macros.h:166
@ SPRITE_ID_BACK_FACING
Definition sprite.h:13
s16 collisionDiameter
s32 flags
s16 collisionHeight
s16 yawCamOffset
Vec3f pos
s32 gOverrideFlags
Definition main_loop.c:11
PartnerStatus gPartnerStatus
Definition partners.c:42
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Camera gCameras[4]
Definition cam_main.c:17
PlayerStatus gPlayerStatus
Definition 77480.c:39
s32 gCurrentCameraID
Definition cam_math.c:4
void fx_damage_stars(s32, f32, f32, f32, f32, f32, f32, s32)

Referenced by update_encounters().

◆ draw_encounters_neutral()

void draw_encounters_neutral ( void )

Definition at line 1258 of file encounter.c.

1258 {
1259}

Referenced by draw_encounter_ui().

◆ update_encounters_pre_battle()

void update_encounters_pre_battle ( void )

Definition at line 1261 of file encounter.c.

1261 {
1262 EncounterStatus* currentEncounter = &gCurrentEncounter;
1263 PlayerData* playerData = &gPlayerData;
1264 Encounter* encounter;
1265 Enemy* enemy;
1266 s32 i;
1267 s32 j;
1268
1269 switch (gEncounterSubState) {
1271 currentEncounter->fadeOutAmount = 0;
1272 currentEncounter->substateDelay = 1;
1273 currentEncounter->fadeOutAccel = 1;
1274 currentEncounter->unk_08 = -1;
1275 HasPreBattleSongPushed = FALSE;
1276 D_80077C40 = FALSE;
1278
1279 // suspend all ai scripts
1280 for (i = 0; i < currentEncounter->numEncounters; i++) {
1281 encounter = currentEncounter->encounterList[i];
1282
1283 if (encounter != NULL) {
1284 for (j = 0; j < encounter->count; j++) {
1285 enemy = encounter->enemy[j];
1286 if (enemy != NULL && !(enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
1287 if (enemy->aiScript != NULL) {
1289 }
1290 if (enemy->auxScript != NULL) {
1292 }
1293 }
1294 }
1295 }
1296 }
1297
1298 // try skip-on-contact
1299 enemy = currentEncounter->curEnemy;
1300 if ((enemy->flags & ENEMY_FLAG_SKIP_BATTLE) && !currentEncounter->scriptedBattle) {
1301 currentEncounter->substateDelay = 0;
1302 currentEncounter->battleStartCountdown = 0;
1305 return;
1306 }
1307
1308 // try kill-on-contact
1310 currentEncounter->substateDelay = 0;
1311 currentEncounter->battleStartCountdown = 10;
1314 return;
1315 }
1316
1317 // try first attack kill
1318 enemy = currentEncounter->curEnemy;
1319 if (currentEncounter->hitType != ENCOUNTER_TRIGGER_NONE
1320 && currentEncounter->hitType != ENCOUNTER_TRIGGER_SPIN
1322 && (playerData->level >= enemy->npcSettings->level)
1323 && !(enemy->flags & ENEMY_FLAG_PROJECTILE)
1324 && !currentEncounter->scriptedBattle
1325 ) {
1326 currentEncounter->substateDelay = 0;
1327 currentEncounter->battleStartCountdown = 10;
1328 D_80077C40 = TRUE;
1330 return;
1331 }
1332
1333 // try bump attack kill
1334 enemy = currentEncounter->curEnemy;
1336 && (playerData->level >= enemy->npcSettings->level)
1337 && !(enemy->flags & ENEMY_FLAG_PROJECTILE)
1338 && !(currentEncounter->scriptedBattle)
1339 ) {
1340 currentEncounter->substateDelay = 0;
1341 currentEncounter->battleStartCountdown = 10;
1342 D_80077C40 = TRUE;
1344 return;
1345 }
1346
1347 // try spin attack kill
1348 enemy = currentEncounter->curEnemy;
1349 if (currentEncounter->hitType == ENCOUNTER_TRIGGER_SPIN
1351 && playerData->level >= enemy->npcSettings->level
1352 && !(enemy->flags & ENEMY_FLAG_PROJECTILE)
1353 && !currentEncounter->scriptedBattle
1354 ) {
1355 currentEncounter->substateDelay = 0;
1356 currentEncounter->battleStartCountdown = 10;
1357 D_80077C40 = TRUE;
1359 return;
1360 }
1361
1362 // start battle music
1363 if (currentEncounter->songID < 0) {
1364 switch (currentEncounter->firstStrikeType) {
1365 case FIRST_STRIKE_NONE:
1367 break;
1370 break;
1371 case FIRST_STRIKE_ENEMY:
1373 break;
1374 }
1375 } else {
1376 bgm_set_battle_song(currentEncounter->songID, FIRST_STRIKE_NONE);
1377 }
1380
1381 currentEncounter->battleStartCountdown = 10;
1383 // fallthrough
1385 // wait for screen to fade out
1386 if (currentEncounter->fadeOutAmount != 255) {
1387 break;
1388 }
1389 // delay before loading the battle
1390 if (currentEncounter->battleStartCountdown != 0) {
1391 currentEncounter->battleStartCountdown--;
1392 break;
1393 }
1394
1395 // kill all enemy hit scripts
1396 encounter = currentEncounter->curEncounter;
1397 for (i = 0; i < encounter->count; i++) {
1398 enemy = encounter->enemy[i];
1399 if (enemy != NULL &&
1400 ((!(enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) || enemy == currentEncounter->curEnemy)) &&
1401 !(enemy->flags & ENEMY_FLAG_DISABLE_AI) &&
1402 enemy->hitScript != NULL)
1403 {
1405 enemy->hitScript = NULL;
1406 }
1407 }
1408
1410 currentEncounter->dizzyAttack.status = 0;
1411 currentEncounter->dizzyAttack.duration = 0;
1412
1413 enemy = currentEncounter->curEnemy;
1414 currentEncounter->instigatorValue = enemy->instigatorValue;
1415
1417 currentEncounter->dizzyAttack.status = 4;
1418 currentEncounter->dizzyAttack.duration = 3;
1419 }
1420
1426 set_battle_stage(encounter->stage);
1427 load_battle(encounter->battle);
1428 currentEncounter->unk_07 = 1;
1429 currentEncounter->unk_08 = 0;
1430 currentEncounter->hasMerleeCoinBonus = FALSE;
1431 currentEncounter->damageTaken = 0;
1432 currentEncounter->coinsEarned = 0;
1433 currentEncounter->fadeOutAccel = 0;
1434 currentEncounter->fadeOutAmount = 255;
1436
1437 // prepare to resume after battle
1439 EncounterStateChanged = TRUE;
1441 break;
1443 if (currentEncounter->battleStartCountdown != 0) {
1444 currentEncounter->battleStartCountdown--;
1445 break;
1446 }
1447
1448 encounter = currentEncounter->curEncounter;
1449 for (i = 0; i < encounter->count; i++) {
1450 enemy = encounter->enemy[i];
1451 if (enemy != NULL &&
1452 (!(enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) || enemy == currentEncounter->curEnemy) &&
1453 !(enemy->flags & ENEMY_FLAG_DISABLE_AI) &&
1454 (enemy->hitScript != 0))
1455 {
1457 enemy->hitScript = NULL;
1458 }
1459 }
1460
1461 currentEncounter->unk_08 = 1;
1462 currentEncounter->unk_07 = 1;
1463 currentEncounter->battleOutcome = OUTCOME_PLAYER_WON;
1464 currentEncounter->hasMerleeCoinBonus = FALSE;
1465 currentEncounter->damageTaken = 0;
1466 currentEncounter->coinsEarned = 0;
1467
1468 currentEncounter->fadeOutAccel = 0;
1469 currentEncounter->fadeOutAmount = 0;
1471 EncounterStateChanged = TRUE;
1473 break;
1475 currentEncounter->battleOutcome = OUTCOME_SKIP;
1476 currentEncounter->unk_08 = 1;
1477
1478 currentEncounter->fadeOutAmount = 0;
1479 currentEncounter->fadeOutAccel = 0;
1481 EncounterStateChanged = TRUE;
1483 break;
1484 }
1485}
s8 HasPreBattleSongPushed
Definition encounter.c:178
void set_battle_formation(Battle *)
Definition battle.c:141
b32 D_80077C40
Definition encounter.c:22
@ OVERLAY_SCREEN_COLOR
Definition enums.h:2388
@ DEBUG_CONTACT_DIE_ON_TOUCH
Definition enums.h:4269
@ SONG_NORMAL_BATTLE
Definition enums.h:284
@ ENCOUNTER_SUBSTATE_POST_BATTLE_INIT
Definition enums.h:6325
@ ENEMY_FLAG_SKIP_BATTLE
Definition enums.h:4541
@ ENCOUNTER_SUBSTATE_PRE_BATTLE_AUTO_WIN
Definition enums.h:6315
@ ENCOUNTER_SUBSTATE_PRE_BATTLE_LOAD
Definition enums.h:6314
@ ENCOUNTER_SUBSTATE_PRE_BATTLE_SKIP
Definition enums.h:6316
@ ABILITY_FIRST_ATTACK
Definition enums.h:439
@ SOUND_SPEEDY_SPIN_ATTACK
Definition enums.h:1553
@ SOUND_SPEEDY_SPIN
Definition enums.h:1551
@ SOUND_SPIN_ATTACK
Definition enums.h:1552
@ SOUND_SPIN
Definition enums.h:1550
@ OUTCOME_PLAYER_WON
Definition enums.h:1902
@ OUTCOME_SKIP
Definition enums.h:1906
@ ENCOUNTER_STATE_POST_BATTLE
Definition enums.h:6299
@ EVT_GROUP_FLAG_BATTLE
Definition evt.h:138
void set_battle_stage(s32)
Definition battle.c:137
void set_screen_overlay_params_front(u8, f32)
void partner_handle_before_battle(void)
Definition partners.c:1067
void load_battle(s32)
Definition battle.c:129
void bgm_set_battle_song(s32, s32)
void bgm_push_battle_song(void)
char unk_07
Definition npc.h:370
s8 instigatorValue
Definition npc.h:334
FieldStatus dizzyAttack
Definition npc.h:399
s32 fadeOutAccel
Definition npc.h:397
s16 duration
Definition npc.h:362
s8 status
Definition npc.h:360
s8 instigatorValue
Definition npc.h:378
s8 battleOutcome
Definition npc.h:372
s16 stage
Definition npc.h:354
s32 battleStartCountdown
Definition npc.h:398
s16 battle
Definition npc.h:353
void sfx_stop_sound(s32 soundID)
Definition sfx.c:507

Referenced by update_encounters().

◆ draw_encounters_pre_battle()

void draw_encounters_pre_battle ( void )

Definition at line 1487 of file encounter.c.

1487 {
1488 EncounterStatus* encounter = &gCurrentEncounter;
1489 PlayerStatus* playerStatus = &gPlayerStatus;
1490
1491#if DX_DEBUG_MENU
1492 Npc* npc = NULL;
1493 if (encounter->curEnemy->npcID != (s16) DX_DEBUG_DUMMY_ID) {
1494 npc = get_npc_unsafe(encounter->curEnemy->npcID);
1495 }
1496#else
1497 Npc* npc = get_npc_unsafe(encounter->curEnemy->npcID);
1498#endif
1499
1500 if (encounter->substateDelay != 0) {
1501 f32 playerX, playerY, playerZ;
1502 f32 otherX, otherY, otherZ;
1503 s32 pScreenX, pScreenY, pScreenZ;
1504 s32 oScreenX, oScreenY, oScreenZ;
1505
1506 if (encounter->fadeOutAmount != 255) {
1507 encounter->fadeOutAccel++;
1508 if (encounter->fadeOutAccel > 10) {
1509 encounter->fadeOutAccel = 10;
1510 }
1511
1512 encounter->fadeOutAmount += encounter->fadeOutAccel;
1513 if (encounter->fadeOutAmount > 255) {
1514 encounter->fadeOutAmount = 255;
1515 }
1516
1517 playerX = playerStatus->pos.x;
1518 playerY = playerStatus->pos.y;
1519 playerZ = playerStatus->pos.z;
1520
1521 #if DX_DEBUG_MENU
1522 if (npc != NULL) {
1523 otherX = npc->pos.x;
1524 otherY = npc->pos.y;
1525 otherZ = npc->pos.z;
1526 } else {
1527 otherX = playerX;
1528 otherY = playerY;
1529 otherZ = playerZ;
1530 }
1531 #else
1532 otherX = npc->pos.x;
1533 otherY = npc->pos.y;
1534 otherZ = npc->pos.z;
1535 #endif
1536 if (otherY < -990.0f) {
1537 otherX = playerX;
1538 otherY = playerY;
1539 otherZ = playerZ;
1540 }
1541
1546 get_screen_coords(gCurrentCameraID, playerX, playerY + 20.0f, playerZ, &pScreenX, &pScreenY, &pScreenZ);
1547 get_screen_coords(gCurrentCameraID, otherX, otherY + 15.0f, otherZ, &oScreenX, &oScreenY, &oScreenZ);
1548 set_screen_overlay_center(SCREEN_LAYER_BACK, 0, (pScreenX - oScreenX) / 2 + oScreenX,
1549 (pScreenY - oScreenY) / 2 + oScreenY);
1550 } else {
1554 get_screen_coords(gCurrentCameraID, playerX, playerY + 20.0f, playerZ, &pScreenX, &pScreenY, &pScreenZ);
1555 get_screen_coords(gCurrentCameraID, otherX, otherY + 15.0f, otherZ, &oScreenX, &oScreenY, &oScreenZ);
1556 set_screen_overlay_center(SCREEN_LAYER_FRONT, 0, (pScreenX - oScreenX) / 2 + oScreenX,
1557 (pScreenY - oScreenY) / 2 + oScreenY);
1558 }
1559 }
1560 }
1561}
@ OVERLAY_START_BATTLE
Definition enums.h:2398
@ SCREEN_LAYER_FRONT
Definition enums.h:2382
@ SCREEN_LAYER_BACK
Definition enums.h:2383
@ DEMO_STATE_CHANGE_MAP
Definition enums.h:3537
void set_screen_overlay_params_back(u8, f32)
void set_screen_overlay_alpha(s32, f32)
void set_screen_overlay_center(s32, s32, s32, s32)
void set_screen_overlay_color(s32, u8, u8, u8)

Referenced by draw_encounter_ui().

◆ show_first_strike_message()

void show_first_strike_message ( void )

Definition at line 1563 of file encounter.c.

1563 {
1564 EncounterStatus* currentEncounter = &gCurrentEncounter;
1565 s32 posX;
1566 s32 width;
1567 s32 xOffset;
1568 s32 screenWidthHalf;
1569
1570 if (currentEncounter->substateDelay == 0) {
1572 return;
1573 }
1574
1576 xOffset = gFirstStrikeMessagePos;
1577 if (xOffset > 0) {
1578 if (xOffset < 1600) {
1579 xOffset = 0;
1580 } else {
1581 xOffset -= 1600;
1582 }
1583 }
1584
1585 screenWidthHalf = SCREEN_WIDTH / 2;
1586
1587 switch (currentEncounter->firstStrikeType) {
1589 switch (currentEncounter->hitType) {
1592 width = get_msg_width(MSG_Menus_PlayerFirstStrike, 0) + 24;
1593 posX = (xOffset + screenWidthHalf) - (width / 2);
1594 draw_box(0, WINDOW_STYLE_20, posX, 69, 0, width, 28, 255, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, NULL, 0, NULL,
1596 draw_msg(MSG_Menus_PlayerFirstStrike, posX + 11, 75, 0xFF, MSG_PAL_STANDARD, 0);
1597 break;
1599 width = get_msg_width(MSG_Menus_PartnerFirstStrike, 0) + 24;
1600 posX = (xOffset + screenWidthHalf) - (width / 2);
1601 draw_box(0, WINDOW_STYLE_20, posX, 69, 0, width, 28, 255, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, NULL, 0, NULL,
1603 draw_msg(MSG_Menus_PartnerFirstStrike, posX + 11, 75, 0xFF, MSG_PAL_STANDARD, 0);
1604 break;
1605 }
1606 break;
1607 case FIRST_STRIKE_ENEMY:
1609 width = get_msg_width(MSG_Menus_EnemyFirstStrike, 0) + 24;
1610 posX = (xOffset + screenWidthHalf) - (width / 2);
1611 draw_box(0, WINDOW_STYLE_4, posX, 69, 0, width, 28, 255, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, NULL, 0, NULL,
1613 draw_msg(MSG_Menus_EnemyFirstStrike, posX + 11, 75, 0xFF, MSG_PAL_STANDARD, 0);
1614 }
1615 break;
1616 }
1617}
#define get_msg_width
#define draw_msg
#define draw_box
s16 gFirstStrikeMessagePos
Definition encounter.c:181
@ WINDOW_STYLE_4
Definition enums.h:6374
@ WINDOW_STYLE_20
Definition enums.h:6390
@ MSG_PAL_STANDARD
Definition enums.h:5415
#define SCREEN_WIDTH
Definition macros.h:105
#define SCREEN_HEIGHT
Definition macros.h:106

Referenced by draw_first_strike_ui().

◆ update_encounters_post_battle()

void update_encounters_post_battle ( void )

Definition at line 1619 of file encounter.c.

1619 {
1620 EncounterStatus* currentEncounter = &gCurrentEncounter;
1621 PlayerStatus* playerStatus = &gPlayerStatus;
1622 PlayerData* playerData = &gPlayerData;
1623 PartnerStatus* partnerStatus = &gPartnerStatus;
1624 Encounter* encounter;
1625 Evt* script;
1626 Enemy* enemy;
1627 s32 i, j;
1628 s32 hasDefeatScript;
1629 Npc* npc;
1630
1631 switch (gEncounterSubState) {
1633 if (currentEncounter->unk_08 == 0) {
1634 return;
1635 }
1636
1637 currentEncounter->unk_08 = 0;
1639 currentEncounter->scriptedBattle = FALSE;
1641 currentEncounter->dizzyAttack.status = 0;
1642 currentEncounter->unusedAttack1.status = 0;
1643 currentEncounter->unusedAttack2.status = 0;
1644 currentEncounter->unusedAttack3.status = 0;
1645 currentEncounter->dizzyAttack.duration = 0;
1646 currentEncounter->unusedAttack1.duration = 0;
1647 currentEncounter->unusedAttack2.duration = 0;
1648 currentEncounter->unusedAttack3.duration = 0;
1649 if (HasPreBattleSongPushed == TRUE) {
1651 }
1652 currentEncounter->fadeOutAccel = 1;
1653 currentEncounter->battleStartCountdown = 0;
1655 gPlayerStatus.flags &= ~PS_FLAG_ENTERING_BATTLE;
1656 if (currentEncounter->hitType == ENCOUNTER_TRIGGER_SPIN) {
1658 }
1659 currentEncounter->hitType = 0;
1660 if (!D_80077C40) {
1662 }
1664 if (partnerStatus->shouldResumeAbility) {
1666 } else if (!LastBattleStartedBySpin
1670 ) {
1672 }
1673 switch (currentEncounter->battleOutcome) {
1674 case OUTCOME_PLAYER_WON:
1676 break;
1679 break;
1682 break;
1683 case OUTCOME_SKIP:
1685 break;
1686 case OUTCOME_ENEMY_FLED:
1688 break;
1689 }
1690 break;
1692 if (currentEncounter->hasMerleeCoinBonus) {
1693 if (get_coin_drop_amount(currentEncounter->curEnemy) != 0) {
1697 } else {
1698 playerData->merleeTurnCount = 0;
1699 playerData->merleeCastsLeft++;
1700 }
1701 }
1703 break;
1705 // fade screen in and wait for merlee bonus to finish (if applicable)
1706 if (currentEncounter->hasMerleeCoinBonus) {
1707 if (get_coin_drop_amount(currentEncounter->curEnemy) != 0) {
1708 currentEncounter->fadeOutAccel += 4;
1709 currentEncounter->fadeOutAmount -= currentEncounter->fadeOutAccel;
1710 if (currentEncounter->fadeOutAmount < 0) {
1711 currentEncounter->fadeOutAmount = 0;
1712 }
1714 break;
1715 }
1716 }
1717 }
1718 // start defeat scripts for current enemy
1719 encounter = currentEncounter->curEncounter;
1720 for (i = 0; i < encounter->count; i++) {
1721 enemy = encounter->enemy[i];
1722 if (enemy == NULL) {
1723 continue;
1724 }
1725 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
1726 continue;
1727 }
1728 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
1729 continue;
1730 }
1731 if (enemy->defeatBytecode != NULL) {
1733 enemy->defeatScript = script;
1734 enemy->defeatScriptID = script->id;
1735 script->owner1.enemy = enemy;
1736 script->owner2.npcID = enemy->npcID;
1738 currentEncounter->battleStartCountdown = 1;
1739 } else {
1741 enemy->defeatScript = script;
1742 enemy->defeatScriptID = script->id;
1743 script->owner1.enemy = enemy;
1744 script->owner2.npcID = enemy->npcID;
1746 }
1747 }
1748 if (!(currentEncounter->flags & ENCOUNTER_FLAG_THUMBS_UP)
1750 && currentEncounter->battleStartCountdown == 0
1752 ) {
1753 suggest_player_anim_allow_backward(ANIM_Mario1_ThumbsUp);
1754 }
1756 break;
1758 if (currentEncounter->fadeOutAmount == 0) {
1760 } else {
1761 currentEncounter->fadeOutAccel += 4;
1762 currentEncounter->fadeOutAmount -= currentEncounter->fadeOutAccel;
1763 if (currentEncounter->fadeOutAmount < 0) {
1764 currentEncounter->fadeOutAmount = 0;
1765 }
1766 }
1767 break;
1769 // wait for all defeat scripts to finish
1770 hasDefeatScript = FALSE;
1771 encounter = currentEncounter->curEncounter;
1772 for (i = 0; i < encounter->count; i++) {
1773 enemy = encounter->enemy[i];
1774 if (enemy == NULL) {
1775 continue;
1776 }
1777 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
1778 continue;
1779 }
1780 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
1781 continue;
1782 }
1783 if (does_script_exist(enemy->defeatScriptID)) {
1784 hasDefeatScript = TRUE;
1785 } else {
1786 enemy->defeatScript = NULL;
1787 }
1788 }
1789 // kill defeated enemies
1790 if (!hasDefeatScript) {
1791 if (!(currentEncounter->flags & ENCOUNTER_FLAG_THUMBS_UP)
1793 && currentEncounter->battleStartCountdown == 1
1794 ) {
1795 suggest_player_anim_allow_backward(ANIM_Mario1_ThumbsUp);
1796 }
1797 encounter = currentEncounter->curEncounter;
1798 for (i = 0; i < encounter->count; i++) {
1799 enemy = encounter->enemy[i];
1800 enemy = encounter->enemy[i];
1801 if (enemy == NULL) {
1802 continue;
1803 }
1804 if (enemy->flags & ENEMY_FLAG_DO_NOT_KILL) {
1805 continue;
1806 }
1807 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
1808 continue;
1809 }
1810 if (!(enemy->flags & ENEMY_FLAG_PASSIVE)) {
1811 if (!(enemy->flags & ENEMY_FLAG_FLED)) {
1812 set_defeated(currentEncounter->mapID, encounter->encounterID + i);
1813 }
1814 }
1815 kill_enemy(enemy);
1816 }
1817
1818 currentEncounter->substateDelay = 0;
1819 if (!(currentEncounter->flags & ENCOUNTER_FLAG_THUMBS_UP)
1821 && currentEncounter->battleStartCountdown == 1
1822 ) {
1823 currentEncounter->substateDelay = 30;
1824 }
1826 }
1827 break;
1829 if (!(currentEncounter->flags & ENCOUNTER_FLAG_CANT_SKIP_WIN_DELAY)) {
1830 if (gGameStatusPtr->stickX[0] != 0 || gGameStatusPtr->stickY[0] != 0) {
1831 currentEncounter->substateDelay = 0;
1832 }
1833 }
1834 if (currentEncounter->substateDelay != 0) {
1835 currentEncounter->substateDelay--;
1836 break;
1837 }
1838
1839 for (i = 0; i < currentEncounter->numEncounters; i++) {
1840 encounter = currentEncounter->encounterList[i];
1841 if (encounter == NULL) {
1842 continue;
1843 }
1844 for (j = 0; j < encounter->count; j++) {
1845 enemy = encounter->enemy[j];
1846 if (enemy == NULL || (enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
1847 continue;
1848 }
1849 if (enemy->aiScript != NULL) {
1851 }
1852 if (enemy->auxScript != NULL) {
1854 }
1855 }
1856 }
1857
1858 currentEncounter->battleTriggerCooldown = 15;
1862 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
1863 }
1867 EncounterStateChanged = TRUE;
1869 break;
1871 encounter = currentEncounter->curEncounter;
1872 for (i = 0; i < encounter->count; i++) {
1873 enemy = encounter->enemy[i];
1874 if (enemy == NULL) {
1875 continue;
1876 }
1877 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
1878 continue;
1879 }
1880 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
1881 continue;
1882 }
1883
1884 if (enemy->defeatBytecode != NULL) {
1885 script = start_script(enemy->defeatBytecode, EVT_PRIORITY_A, 0);
1886 enemy->defeatScript = script;
1887 enemy->defeatScriptID = script->id;
1888 enemy->aiFlags |= AI_FLAG_1;
1889 script->owner1.enemy = enemy;
1890 script->owner2.npcID = enemy->npcID;
1891 script->groupFlags = enemy->scriptGroup;
1892 }
1893 }
1895 break;
1897 if (currentEncounter->fadeOutAmount == 0) {
1899 } else {
1900 currentEncounter->fadeOutAccel += 4;
1901 currentEncounter->fadeOutAmount -= currentEncounter->fadeOutAccel;
1902 if (currentEncounter->fadeOutAmount < 0) {
1903 currentEncounter->fadeOutAmount = 0;
1904 }
1905 }
1906 break;
1908 encounter = currentEncounter->curEncounter;
1909 hasDefeatScript = FALSE;
1910 for (i = 0; i < encounter->count; i++) {
1911 enemy = encounter->enemy[i];
1912 if (enemy == NULL) {
1913 continue;
1914 }
1915 if (!(enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
1916 if (does_script_exist(enemy->defeatScriptID)) {
1917 hasDefeatScript = TRUE;
1918 } else {
1919 enemy->defeatScript = NULL;
1920 }
1921 }
1922 }
1923 if (!hasDefeatScript) {
1924 for (i = 0; i < currentEncounter->numEncounters; i++) {
1925 encounter = currentEncounter->encounterList[i];
1926 if (encounter == NULL) {
1927 continue;
1928 }
1929 for (j = 0; j < encounter->count; j++) {
1930 enemy = encounter->enemy[j];
1931 if (enemy == NULL || (enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
1932 continue;
1933 }
1934 if (enemy->aiScript != NULL) {
1936 }
1937 if (enemy->auxScript != NULL) {
1939 }
1940 }
1941 }
1942
1943 enemy = currentEncounter->curEnemy;
1944 encounter = currentEncounter->curEncounter;
1945 if (!(enemy->flags & ENEMY_FLAG_NO_DELAY_AFTER_FLEE)) {
1946 enemy->aiSuspendTime = 45;
1947 playerStatus->blinkTimer = 45;
1948 for (j = 0; j < encounter->count; j++) {
1949 enemy = encounter->enemy[j];
1950 if (enemy == NULL) {
1951 continue;
1952 }
1953 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
1954 continue;
1955 }
1956 if (enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) {
1957 continue;
1958 }
1959 enemy->aiSuspendTime = 45;
1960 playerStatus->blinkTimer = 45;
1961 }
1962 }
1963
1964 enemy = currentEncounter->curEnemy;
1965 if (!(currentEncounter->flags & ENCOUNTER_FLAG_SKIP_FLEE_DROPS)) {
1967 enemy->defeatScript = script;
1968 enemy->defeatScriptID = script->id;
1969 script->owner1.enemy = enemy;
1970 script->owner2.npcID = enemy->npcID;
1971 script->groupFlags = enemy->scriptGroup;
1972 }
1973
1974 currentEncounter->battleTriggerCooldown = 45;
1975 playerStatus->blinkTimer = 45;
1980 currentEncounter->substateDelay = 15;
1981 } else {
1982 currentEncounter->substateDelay = 0;
1983 }
1985 }
1986 break;
1988 if (currentEncounter->substateDelay != 0) {
1989 currentEncounter->substateDelay--;
1990 if (gGameStatusPtr->curButtons[0] == 0 && gGameStatusPtr->stickX[0] == 0 && gGameStatusPtr->stickY[0] == 0) {
1991 break;
1992 }
1993 }
1994 if (!PendingPartnerAbilityResume && playerStatus->anim == ANIM_MarioB3_Hustled) {
1995 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
1996 }
1999 EncounterStateChanged = TRUE;
2001 break;
2003 suggest_player_anim_allow_backward(ANIM_MarioW2_LayingDown);
2004 encounter = currentEncounter->curEncounter;
2005 for (i = 0; i < encounter->count; i++) {
2006 enemy = encounter->enemy[i];
2007 if (enemy == NULL) {
2008 continue;
2009 }
2010 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
2011 continue;
2012 }
2013
2014 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
2015 continue;
2016 }
2017
2018 if (enemy->defeatBytecode != NULL) {
2019 script = start_script(enemy->defeatBytecode, EVT_PRIORITY_A, 0);
2020 enemy->defeatScript = script;
2021 enemy->defeatScriptID = script->id;
2022 script->owner1.enemy = enemy;
2023 script->owner2.npcID = enemy->npcID;
2024 script->groupFlags = enemy->scriptGroup;
2025 }
2026 }
2028 break;
2030 if (currentEncounter->fadeOutAmount == 0) {
2032 } else {
2033 currentEncounter->fadeOutAccel += 4;
2034 currentEncounter->fadeOutAmount -= currentEncounter->fadeOutAccel;
2035 if (currentEncounter->fadeOutAmount < 0) {
2036 currentEncounter->fadeOutAmount = 0;
2037 }
2038 }
2039 break;
2041 hasDefeatScript = FALSE;
2042 encounter = currentEncounter->curEncounter;
2043 for (i = 0; i < encounter->count; i++) {
2044 enemy = encounter->enemy[i];
2045 if (enemy == NULL) {
2046 continue;
2047 }
2048 if (!(enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
2049 if (does_script_exist(enemy->defeatScriptID)) {
2050 hasDefeatScript = TRUE;
2051 } else {
2052 enemy->defeatScript = NULL;
2053 }
2054 }
2055 }
2056 if (!hasDefeatScript) {
2057 for (i = 0; i < currentEncounter->numEncounters; i++) {
2058 encounter = currentEncounter->encounterList[i];
2059 if (encounter == NULL) {
2060 continue;
2061 }
2062 for (j = 0; j < encounter->count; j++) {
2063 enemy = encounter->enemy[j];
2064 if (enemy == NULL || (enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
2065 continue;
2066 }
2067 if (enemy->aiScript != NULL) {
2069 }
2070 if (enemy->auxScript != NULL) {
2072 }
2073 }
2074 }
2078 currentEncounter->substateDelay = 15;
2080 }
2081 break;
2083 if (currentEncounter->substateDelay != 0) {
2084 currentEncounter->substateDelay--;
2085 if (gGameStatusPtr->curButtons[0] == 0 && gGameStatusPtr->stickX[0] == 0 && gGameStatusPtr->stickY[0] == 0) {
2086 break;
2087 }
2088 }
2091 EncounterStateChanged = TRUE;
2093 break;
2095 // resume all ai scripts
2096 for (i = 0; i < currentEncounter->numEncounters; i++) {
2097 encounter = currentEncounter->encounterList[i];
2098 if (encounter == NULL) {
2099 continue;
2100 }
2101 for (j = 0; j < encounter->count; j++) {
2102 enemy = encounter->enemy[j];
2103 if (enemy == NULL || (enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
2104 continue;
2105 }
2106 if (enemy->aiScript != NULL) {
2108 }
2109 if (enemy->auxScript != NULL) {
2111 }
2112 }
2113 }
2119 EncounterStateChanged = TRUE;
2121 break;
2123 encounter = currentEncounter->curEncounter;
2124 for (i = 0; i < encounter->count; i++) {
2125 enemy = encounter->enemy[i];
2126 if (enemy == NULL) {
2127 continue;
2128 }
2129 if ((enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) && enemy != currentEncounter->curEnemy) {
2130 continue;
2131 }
2132
2133 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
2134 continue;
2135 }
2136
2137 if (enemy->defeatBytecode != NULL) {
2138 script = start_script(enemy->defeatBytecode, EVT_PRIORITY_A, 0);
2139 enemy->defeatScript = script;
2140 enemy->defeatScriptID = script->id;
2141 script->owner1.enemy = enemy;
2142 script->owner2.npcID = enemy->npcID;
2143 script->groupFlags = enemy->scriptGroup;
2144 }
2145 }
2147 break;
2149 if (currentEncounter->fadeOutAmount == 0) {
2151 } else {
2152 currentEncounter->fadeOutAccel += 4;
2153 currentEncounter->fadeOutAmount -= currentEncounter->fadeOutAccel;
2154 if (currentEncounter->fadeOutAmount < 0) {
2155 currentEncounter->fadeOutAmount = 0;
2156 }
2157 }
2158 break;
2160 hasDefeatScript = FALSE;
2161 encounter = currentEncounter->curEncounter;
2162 for (i = 0; i < encounter->count; i++) {
2163 enemy = encounter->enemy[i];
2164 if (enemy == NULL) {
2165 continue;
2166 }
2167 if (!(enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
2168 if (does_script_exist(enemy->defeatScriptID)) {
2169 hasDefeatScript = TRUE;
2170 } else {
2171 enemy->defeatScript = NULL;
2172 }
2173 }
2174 }
2175 if (!hasDefeatScript) {
2176 for (i = 0; i < currentEncounter->numEncounters; i++) {
2177 encounter = currentEncounter->encounterList[i];
2178 if (encounter == NULL) {
2179 continue;
2180 }
2181 for (j = 0; j < encounter->count; j++) {
2182 enemy = encounter->enemy[j];
2183 if (enemy == NULL || (enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
2184 continue;
2185 }
2186 if (enemy->aiScript != NULL) {
2188 }
2189 if (enemy->auxScript != NULL) {
2191 }
2192 }
2193 }
2194
2195 enemy = currentEncounter->curEnemy;
2196 if (!(enemy->flags & ENEMY_FLAG_DO_NOT_KILL)) {
2197 encounter = currentEncounter->curEncounter;
2198 enemy->aiSuspendTime = 45;
2199 playerStatus->blinkTimer = 45;
2200 for (j = 0; j < encounter->count; j++) {
2201 enemy = encounter->enemy[j];
2202 if (enemy == NULL) {
2203 continue;
2204 }
2205 if (enemy->flags & ENEMY_FLAG_DISABLE_AI) {
2206 continue;
2207 }
2208 if (enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) {
2209 continue;
2210 }
2211 enemy->aiSuspendTime = 45;
2212 playerStatus->blinkTimer = 45;
2213 }
2214 }
2215
2216 currentEncounter->battleTriggerCooldown = 45;
2222 EncounterStateChanged = TRUE;
2224 }
2225 break;
2226 }
2227
2228 for (i = 0; i < currentEncounter->numEncounters; i++) {
2229 encounter = currentEncounter->encounterList[i];
2230 if (encounter == NULL) {
2231 continue;
2232 }
2233 for (j = 0; j < encounter->count; j++) {
2234 enemy = encounter->enemy[j];
2235 if (enemy == NULL || (enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
2236 continue;
2237 }
2238
2239 npc = get_npc_unsafe(enemy->npcID);
2240 if (enemy->aiSuspendTime != 0) {
2241 if (enemy->aiSuspendTime & 1) {
2242 npc->flags |= NPC_FLAG_SUSPENDED;
2243 enemy->flags |= ENEMY_FLAG_SUSPENDED;
2244 } else {
2245 npc->flags &= ~NPC_FLAG_SUSPENDED;
2246 enemy->flags &= ~ENEMY_FLAG_SUSPENDED;
2247 }
2248 }
2249 }
2250 }
2251}
void setup_status_bar_for_world(void)
Definition inventory.c:1450
b8 LastBattleStartedBySpin
Definition encounter.c:180
s32 get_coin_drop_amount(Enemy *enemy)
Definition 23680.c:312
BSS s32 MerleeDropCoinsEvtID
Definition encounter.c:188
void set_defeated(s32 mapID, s32 encounterID)
Definition encounter.c:210
EvtScript EVS_NpcDefeat
Definition encounter.c:65
BSS Evt * MerleeDropCoinsEvt
Definition encounter.c:187
EvtScript EVS_MerleeDropCoins
Definition encounter.c:26
EvtScript EVS_FleeBattleDrops
Definition encounter.c:77
void partner_handle_after_battle(void)
Definition partners.c:1081
b8 PendingPartnerAbilityResume
Definition encounter.c:179
@ OVERLAY_NONE
Definition enums.h:2387
@ ENCOUNTER_FLAG_SKIP_FLEE_DROPS
Definition enums.h:4989
@ ENCOUNTER_FLAG_THUMBS_UP
Mario will do a 'thumbs up' animation after winning.
Definition enums.h:4987
@ ENCOUNTER_FLAG_CANT_SKIP_WIN_DELAY
Definition enums.h:4988
@ AI_FLAG_1
Definition enums.h:4569
@ PS_FLAG_FALLING
Definition enums.h:3036
@ PS_FLAG_JUMPING
Definition enums.h:3035
@ ENCOUNTER_SUBSTATE_POST_BATTLE_WON_FADE_IN
Definition enums.h:6326
@ ENCOUNTER_SUBSTATE_POST_BATTLE_LOST_RESUME
Definition enums.h:6337
@ ENCOUNTER_SUBSTATE_POST_BATTLE_LOST_FADE_IN
Definition enums.h:6336
@ ENCOUNTER_SUBSTATE_POST_BATTLE_SKIP
Definition enums.h:6339
@ ENCOUNTER_SUBSTATE_POST_BATTLE_FLED_RESUME
Definition enums.h:6333
@ ENCOUNTER_SUBSTATE_POST_BATTLE_WON_KILL
Definition enums.h:6327
@ ENCOUNTER_SUBSTATE_POST_BATTLE_FLED_INIT
Definition enums.h:6331
@ ENCOUNTER_SUBSTATE_POST_BATTLE_WON_RESUME
Definition enums.h:6328
@ ENCOUNTER_SUBSTATE_POST_BATTLE_ENEMY_FLED_INIT
Definition enums.h:6340
@ ENCOUNTER_SUBSTATE_POST_BATTLE_LOST_DELAY
Definition enums.h:6338
@ ENCOUNTER_SUBSTATE_POST_BATTLE_FLED_FADE_IN
Definition enums.h:6332
@ ENCOUNTER_SUBSTATE_POST_BATTLE_LOST_INIT
Definition enums.h:6335
@ ENCOUNTER_SUBSTATE_POST_BATTLE_ENEMY_FLED_FADE_IN
Definition enums.h:6341
@ ENCOUNTER_SUBSTATE_POST_BATTLE_PLAY_NPC_DEFEAT
Definition enums.h:6330
@ ENCOUNTER_SUBSTATE_POST_BATTLE_ENEMY_FLED_RESUME
Definition enums.h:6342
@ ENCOUNTER_SUBSTATE_POST_BATTLE_FLED_DELAY
Definition enums.h:6334
@ ENCOUNTER_SUBSTATE_POST_BATTLE_WON_CHECK_MERLEE
Definition enums.h:6329
@ ENEMY_FLAG_DO_NOT_KILL
Definition enums.h:4523
@ ENEMY_FLAG_FLED
Definition enums.h:4525
@ OUTCOME_ENEMY_FLED
Definition enums.h:1905
@ OUTCOME_PLAYER_LOST
Definition enums.h:1903
@ OUTCOME_PLAYER_FLED
Definition enums.h:1904
@ ACTION_STATE_RIDE
Definition enums.h:2461
@ ACTION_STATE_IDLE
Definition enums.h:2426
@ ACTION_STATE_USE_SPINNING_FLOWER
Definition enums.h:2457
@ ENCOUNTER_SUBSTATE_NEUTRAL
Definition enums.h:6309
@ EVT_GROUP_NEVER_PAUSE
Definition evt.h:142
s32 resume_all_group(s32 groupFlags)
s32 enable_player_input(void)
Definition 77480.c:998
void bgm_pop_battle_song(void)
void suggest_player_anim_allow_backward(AnimID anim)
Definition 77480.c:894
s32 resume_all_script(s32 id)
Evt * start_script_in_group(EvtScript *source, u8 priority, u8 initialState, u8 groupFlags)
s16 encounterID
Definition npc.h:355
FieldStatus unusedAttack3
Definition npc.h:402
FieldStatus unusedAttack1
Definition npc.h:400
void kill_enemy(Enemy *enemy)
Definition npc.c:2374
struct Evt * defeatScript
Definition npc.h:316
s32 defeatScriptID
Definition npc.h:322
FieldStatus unusedAttack2
Definition npc.h:401
u32 aiFlags
Definition npc.h:332
EvtScript * defeatBytecode
Definition npc.h:310
void partner_enable_input(void)
Definition partners.c:2480

Referenced by update_encounters().

◆ draw_encounters_post_battle()

void draw_encounters_post_battle ( void )

Definition at line 2253 of file encounter.c.

2253 {
2254 EncounterStatus* currentEncounter = &gCurrentEncounter;
2255 s32 ret = currentEncounter->fadeOutAccel;
2256
2257 if (ret != 0) {
2260 }
2261}

Referenced by draw_encounter_ui().

◆ update_encounters_conversation()

void update_encounters_conversation ( void )

Definition at line 2263 of file encounter.c.

2263 {
2264 EncounterStatus* encounter = &gCurrentEncounter;
2265 PlayerStatus* playerStatus = &gPlayerStatus;
2266 Enemy* currentEnemy;
2267 s32 flag;
2268
2269 switch (gEncounterSubState) {
2271 currentEnemy = encounter->curEnemy;
2272 flag = FALSE;
2273
2274 if (currentEnemy->interactScript != NULL) {
2275 if (does_script_exist(currentEnemy->interactScriptID)) {
2276 flag = TRUE;
2277 } else {
2278 currentEnemy->interactScript = NULL;
2279 }
2280 }
2281
2282 if (currentEnemy->hitScript != NULL) {
2283 if (does_script_exist(currentEnemy->hitScriptID)) {
2284 flag = TRUE;
2285 } else {
2286 currentEnemy->hitScript = NULL;
2287 }
2288 }
2289
2290 if (!flag) {
2292 }
2293 break;
2296
2297 currentEnemy = encounter->curEnemy;
2298 if (currentEnemy != NULL && currentEnemy->aiScript != NULL) {
2299 resume_all_script(currentEnemy->aiScriptID);
2300 }
2301
2304
2305 if (playerStatus->actionState == ACTION_STATE_TALK) {
2307 }
2308
2309 func_800EF3D4(0);
2310 encounter->hitType = 0;
2313 EncounterStateChanged = TRUE;
2315 break;
2316 }
2317}
@ ENCOUNTER_SUBSTATE_CONVERSATION_END
Definition enums.h:6321

Referenced by update_encounters().

◆ draw_encounters_conversation()

void draw_encounters_conversation ( void )

Definition at line 2319 of file encounter.c.

2319 {
2320}

Referenced by draw_encounter_ui().

◆ check_conversation_trigger()

b32 check_conversation_trigger ( void )

Definition at line 2322 of file encounter.c.

2322 {
2323 PlayerStatus* playerStatus = &gPlayerStatus;
2324 Camera* camera = &gCameras[gCurrentCameraID];
2325 EncounterStatus* encounterStatus = &gCurrentEncounter;
2326 f32 npcX, npcY, npcZ;
2327 f32 angle;
2328 f32 deltaX, deltaZ;
2329 Encounter* resultEncounter;
2330 f32 playerX, playerY, playerZ;
2331 f32 playerHeight;
2332 f32 playerRadius;
2333 f32 length;
2334 f32 npcHeight;
2335 f32 npcRadius;
2336 Encounter* encounter;
2337 Npc* resultNpc;
2338 Npc* npc;
2339 Enemy* resultEnemy;
2340 Enemy* enemy;
2341 f32 minLength;
2342 s32 i, j;
2343 f32 yaw;
2344
2345 playerStatus->encounteredNPC = NULL;
2346 playerStatus->flags &= ~PS_FLAG_HAS_CONVERSATION_NPC;
2347 playerHeight = playerStatus->colliderHeight;
2348 playerRadius = playerStatus->colliderDiameter / 2;
2349 playerX = playerStatus->pos.x;
2350 playerY = playerStatus->pos.y;
2351 playerZ = playerStatus->pos.z;
2352
2354 return FALSE;
2355 }
2356
2357 resultEncounter = NULL;
2358 resultNpc = NULL;
2359 resultEnemy = NULL;
2360 minLength = 65535.0f;
2361
2362 for (i = 0; i < encounterStatus->numEncounters; i++) {
2363 encounter = encounterStatus->encounterList[i];
2364
2365 if (encounter == NULL) {
2366 continue;
2367 }
2368
2369 for (j = 0; j < encounter->count; j++) {
2370 enemy = encounter->enemy[j];
2371
2372 if (enemy == NULL) {
2373 continue;
2374 }
2375
2377 continue;
2378 }
2379
2380 if (!(enemy->flags & ENEMY_FLAG_PASSIVE)) {
2381 continue;
2382 }
2383
2384 if ((enemy->flags & ENEMY_FLAG_CANT_INTERACT) || enemy->interactBytecode == NULL) {
2385 continue;
2386 }
2387
2388 npc = get_npc_unsafe(enemy->npcID);
2389
2390 npcX = npc->pos.x;
2391 npcY = npc->pos.y;
2392 npcZ = npc->pos.z;
2393 deltaX = npcX - playerX;
2394 deltaZ = npcZ - playerZ;
2395 npcHeight = npc->collisionHeight;
2396 npcRadius = npc->collisionDiameter;
2397 length = sqrtf(SQ(deltaX) + SQ(deltaZ));
2398
2399 // check cylinder-cylinder overlap
2400 if ((playerRadius + npcRadius <= length) ||
2401 (npcY + npcHeight < playerY) ||
2402 (playerY + playerHeight < npcY)) {
2403 continue;
2404 }
2405
2406 if (clamp_angle(playerStatus->spriteFacingAngle) < 180.0f) {
2407 angle = clamp_angle(camera->curYaw - 120.0f);
2408 if (playerStatus->trueAnimation & SPRITE_ID_BACK_FACING) {
2409 angle = clamp_angle(angle + 60.0f);
2410 }
2411 } else {
2412 angle = clamp_angle(camera->curYaw + 120.0f);
2413 if (playerStatus->trueAnimation & SPRITE_ID_BACK_FACING) {
2414 angle = clamp_angle(angle - 60.0f);
2415 }
2416 }
2417
2418 yaw = atan2(playerX, playerZ, npcX, npcZ);
2419 if (fabsf(get_clamped_angle_diff(angle, yaw)) > 90.0f) {
2420 continue;
2421 }
2422
2423 // only allow interact if line of sight exists
2424 // @bug? flag combination does not make sense
2426 f32 x = npcX;
2427 f32 y = npcY;
2428 f32 z = npcZ;
2429 yaw = atan2(npcX, npcZ, playerX, playerZ);
2430
2431 if (npc_test_move_taller_with_slipping(0, &x, &y, &z, length, yaw, npcHeight, 2.0f * npcRadius)) {
2432 continue;
2433 }
2434 }
2435
2436 if (length < minLength) {
2437 minLength = length;
2438 resultEncounter = encounter;
2439 resultNpc = npc;
2440 resultEnemy = enemy;
2441 }
2442 }
2443 }
2444
2445 if (!(playerStatus->animFlags & PA_FLAG_8BIT_MARIO) && resultNpc != NULL && !is_picking_up_item()) {
2446 playerStatus->encounteredNPC = resultNpc;
2447 playerStatus->flags |= PS_FLAG_HAS_CONVERSATION_NPC;
2448 if (playerStatus->pressedButtons & BUTTON_A) {
2452 encounterStatus->curEncounter = resultEncounter;
2453 encounterStatus->curEnemy = resultEnemy;
2454 encounterStatus->firstStrikeType = FIRST_STRIKE_PLAYER;
2455 return TRUE;
2456 }
2457 }
2458 return FALSE;
2459}
@ BUTTON_A
Definition enums.h:2790
@ PS_FLAG_HAS_CONVERSATION_NPC
Definition enums.h:3074
@ PARTNER_ACTION_NONE
Definition enums.h:2932
@ ENEMY_FLAG_RAYCAST_TO_INTERACT
Definition enums.h:4537
@ ENEMY_FLAG_CANT_INTERACT
Definition enums.h:4548
@ PA_FLAG_8BIT_MARIO
Definition enums.h:3105
@ NPC_FLAG_RAYCAST_TO_INTERACT
Definition enums.h:3027
void close_status_bar(void)
Definition inventory.c:1440

Referenced by phys_peach_update(), and phys_update_action_state().

◆ create_encounters()

void create_encounters ( void )

Definition at line 2461 of file encounter.c.

2461 {
2462 EncounterStatus* currentEncounter = &gCurrentEncounter;
2463 NpcBlueprint sp10;
2464 NpcBlueprint* bp = &sp10;
2465 NpcGroup* groupList = (NpcGroup*)(currentEncounter->npcGroupList);
2466 s32 groupNpcCount;
2467 s32 mapID = currentEncounter->mapID;
2468
2469 Npc* newNpc;
2470 s32 newNpcIndex;
2471 s32 npcCount;
2472
2473 NpcSettings* npcSettings;
2474 NpcData* npcData;
2475 Enemy* enemy;
2476 Encounter* encounter;
2477 Evt* script;
2478
2479 s32 totalNpcCount;
2480
2481 s32 cond1;
2482 s32 cond2;
2483 s32 i;
2484 s32 k;
2485 s32 e;
2486
2487 switch (gEncounterSubState) {
2489 if (currentEncounter->resetMapEncounterFlags != 1) {
2490 // check for current map among most recently visited
2491 for (i = 0; i < ARRAY_COUNT(currentEncounter->recentMaps); i++) {
2492 if (currentEncounter->recentMaps[i] == mapID) {
2493 break;
2494 }
2495 }
2496 // current map not found in recent: reset all defeat flags
2497 if (i >= ARRAY_COUNT(currentEncounter->recentMaps)) {
2498 for (k = 0; k < ARRAY_COUNT(currentEncounter->defeatFlags[mapID]); k++) {
2499 currentEncounter->defeatFlags[mapID][k] = FALSE;
2500 }
2501 }
2502 // add current map to recent maps, pushing out the least recent
2503 for (i = 0; i < ARRAY_COUNT(currentEncounter->recentMaps) - 1; i++) {
2504 currentEncounter->recentMaps[i] = currentEncounter->recentMaps[i + 1];
2505 }
2506 currentEncounter->recentMaps[i] = mapID;
2507 }
2508
2509 e = 0;
2510 totalNpcCount = 0;
2511 while (TRUE) {
2512 if (groupList->npcCount == 0) {
2513 break;
2514 }
2515
2516 npcData = groupList->npcs;
2517 groupNpcCount = groupList->npcCount;
2518
2519 encounter = heap_malloc(sizeof(*encounter));
2520
2521 currentEncounter->encounterList[e] = encounter;
2522 ASSERT(encounter != NULL);
2523 encounter->count = groupNpcCount;
2524 encounter->battle = groupList->battle;
2525 encounter->stage = groupList->stage - 1;
2526 encounter->encounterID = totalNpcCount;
2527 for (i = 0; i < groupNpcCount; i++) {
2528 if (get_defeated(mapID, encounter->encounterID + i)) {
2529 npcData++;
2530 encounter->enemy[i] = NULL;
2531 continue;
2532 }
2533
2534 enemy = encounter->enemy[i] = heap_malloc(sizeof(*enemy));
2535 ASSERT (enemy != NULL);
2536
2537 for (k = 0; k < ARRAY_COUNT(enemy->varTable); k++) {
2538 enemy->varTable[k] = 0;
2539 }
2540 enemy->encounterIndex = e;
2541 enemy->npcID = npcData->id;
2542 npcSettings = enemy->npcSettings = npcData->settings;
2543 enemy->drops = &npcData->drops;
2544 if ((*(s16*)(&npcData->drops) & 0xFF00) != 0x8000) { //TODO s16?
2545 enemy->drops = &DefaultEnemyDrops;
2546 }
2547 enemy->encountered = 0;
2548 if ((s32) npcData->init < EVT_LIMIT) {
2549 enemy->initBytecode = npcData->init;
2550 } else {
2551 enemy->initBytecode = NULL;
2552 }
2553 enemy->interactBytecode = npcSettings->onInteract;
2554 enemy->aiBytecode = npcSettings->ai;
2555 enemy->hitBytecode = npcSettings->onHit;
2556 enemy->auxBytecode = npcSettings->aux;
2557 enemy->defeatBytecode = npcSettings->onDefeat;
2558 enemy->initScript = NULL;
2559 enemy->interactScript = NULL;
2560 enemy->aiScript = NULL;
2561 enemy->hitScript = NULL;
2562 enemy->auxScript = NULL;
2563 enemy->defeatScript = NULL;
2564 enemy->interactScriptID = 0;
2565 enemy->aiScriptID = 0;
2566 enemy->hitScriptID = 0;
2567 enemy->auxScriptID = 0;
2568 enemy->defeatScriptID = 0;
2569 enemy->hitboxIsActive = FALSE;
2570 enemy->instigatorValue = 0;
2571 enemy->aiDetectFlags = npcData->aiDetectFlags;
2572
2573
2574 enemy->aiFlags = npcData->aiFlags;
2575 enemy->unk_DC = 0;
2576 enemy->aiSuspendTime = 0;
2577 enemy->unk_B8 = (EvtScript*)npcSettings->unk_24; // ??
2578 enemy->unk_BC = NULL;
2579 enemy->unk_C0 = 0;
2580 enemy->unk_C4 = 0;
2581
2582 enemy->animList = (s32*)&npcData->animations;
2583 enemy->territory = &npcData->territory;
2584
2585 enemy->flags = npcSettings->flags;
2586 enemy->flags |= npcData->flags;
2587 enemy->unk_64 = NULL;
2588 enemy->tattleMsg = npcData->tattle;
2589 if (npcData->initVarCount != 0) {
2590 if (npcData->initVarCount == 1) {
2591 enemy->varTable[0] = npcData->initVar.value;
2592 } else {
2593 s32* initialVars = npcData->initVar.array;
2594 for (k = 0; k < npcData->initVarCount; k++) {
2595 enemy->varTable[k] = *initialVars++;
2596 }
2597 }
2598 }
2599
2600 // create the new NPC
2601 bp->flags = 0;
2602 if (npcSettings->defaultAnim == 0) {
2603 bp->initialAnim = enemy->animList[0];
2604 } else {
2605 bp->initialAnim = npcSettings->defaultAnim;
2606 }
2607 bp->onUpdate = NULL;
2608 bp->onRender = NULL;
2609 if (!(enemy->flags & ENEMY_FLAG_USE_PLAYER_SPRITE)) {
2610 newNpcIndex = create_standard_npc(bp, npcData->extraAnimations);
2611 } else {
2612 newNpcIndex = create_peach_npc(bp);
2613 }
2614
2615 newNpc = get_npc_by_index(newNpcIndex);
2616 newNpc->npcID = npcData->id;
2617 newNpc->collisionDiameter = npcSettings->radius;
2618 newNpc->collisionHeight = npcSettings->height;
2619 enemy->spawnPos[0] = newNpc->pos.x = npcData->pos.x;
2620 enemy->spawnPos[1] = newNpc->pos.y = npcData->pos.y;
2621 enemy->spawnPos[2] = newNpc->pos.z = npcData->pos.z;
2622 newNpc->unk_96 = 0;
2623 newNpc->planarFlyDist = 0.0f;
2624 newNpc->homePos.x = newNpc->pos.x;
2625 newNpc->homePos.y = newNpc->pos.y;
2626 newNpc->homePos.z = newNpc->pos.z;
2627 set_npc_yaw(newNpc, npcData->yaw);
2628 enemy->savedNpcYaw = 12345;
2629 if (newNpc->collisionDiameter >= 24.0) {
2630 newNpc->shadowScale = newNpc->collisionDiameter / 24.0;
2631 } else {
2632 newNpc->shadowScale = 1.0f;
2633 }
2636 }
2639 }
2642 }
2643 if (enemy->flags & ENEMY_FLAG_FLYING) {
2644 newNpc->flags |= NPC_FLAG_FLYING;
2645 }
2646 if (enemy->flags & ENEMY_FLAG_GRAVITY) {
2647 newNpc->flags |= NPC_FLAG_GRAVITY;
2648 }
2649 if (!(enemy->flags & ENEMY_FLAG_PASSIVE)) {
2651 }
2652 if (enemy->flags & ENEMY_FLAG_HAS_NO_SPRITE) {
2653 newNpc->flags |= NPC_FLAG_HAS_NO_SPRITE;
2654 }
2655 if (enemy->flags & ENEMY_FLAG_NO_SHADOW_RAYCAST) {
2657 }
2658 if (enemy->flags & ENEMY_FLAG_USE_INSPECT_ICON) {
2660 }
2663 }
2666 }
2668 if (enemy->flags & ENEMY_FLAG_PASSIVE) {
2670 }
2671 if (npcSettings->otherAI != NULL) {
2672 script = start_script(npcSettings->otherAI, EVT_PRIORITY_A, 0);
2673 enemy->aiScript = script;
2674 enemy->aiScriptID = script->id;
2675 script->owner1.enemy = enemy;
2676 script->owner2.npcID = enemy->npcID;
2677 script->groupFlags = enemy->scriptGroup;
2678 }
2679
2680 npcData++;
2681 }
2682 groupList++;
2683 e++;
2684 totalNpcCount += groupNpcCount;
2685 }
2686 currentEncounter->numEncounters = e;
2688 break;
2689
2691 cond2 = FALSE;
2692 for (e = 0; e < currentEncounter->numEncounters; e++) {
2693 encounter = currentEncounter->encounterList[e];
2694 if (encounter == NULL) {
2695 continue;
2696 }
2697 for (i = 0; i < encounter->count; i++) {
2698 enemy = encounter->enemy[i];
2699 if (enemy == NULL) {
2700 continue;
2701 }
2702 if (enemy->aiScript != NULL) {
2703 if (does_script_exist(enemy->aiScriptID)) {
2704 cond2 = TRUE;
2705 }
2706 }
2707 }
2708 }
2709 if (!cond2) {
2710 for (e = 0; e < currentEncounter->numEncounters; e++) {
2711 encounter = currentEncounter->encounterList[e];
2712 if (encounter == NULL) {
2713 continue;
2714 }
2715 for (i = 0; i < encounter->count; i++) {
2716 enemy = encounter->enemy[i];
2717 if (enemy == NULL) {
2718 continue;
2719 }
2720 if (enemy->initBytecode != NULL) {
2721 script = start_script(enemy->initBytecode, EVT_PRIORITY_A, 0);
2722 enemy->initScript = script;
2723 enemy->initScriptID = script->id;
2724 script->owner1.enemy = enemy;
2725 script->owner2.npcID = enemy->npcID;
2726 script->groupFlags = enemy->scriptGroup;
2727 }
2728 }
2729 }
2731 }
2732 break;
2733
2735 cond1 = FALSE;
2736
2737 for (e = 0; e < currentEncounter->numEncounters; e++) {
2738 encounter = currentEncounter->encounterList[e];
2739 if (encounter == NULL) {
2740 continue;
2741 }
2742 for (i = 0; i < encounter->count; i++) {
2743 enemy = encounter->enemy[i];
2744 if (enemy == NULL) {
2745 continue;
2746 }
2747 if (enemy->initScript != NULL) {
2748 if (does_script_exist(enemy->initScriptID)) {
2749 cond1 = TRUE;
2750 } else {
2751 enemy->initScript = NULL;
2752 }
2753 }
2754 }
2755 }
2756
2757 if (cond1) {
2758 break;
2759 }
2760
2761 for (e = 0; e < currentEncounter->numEncounters; e++) {
2762 encounter = currentEncounter->encounterList[e];
2763 if (encounter == NULL) {
2764 continue;
2765 }
2766 for (i = 0; i < encounter->count; i++) {
2767 enemy = encounter->enemy[i];
2768 if (enemy == NULL) {
2769 continue;
2770 }
2771 if (!(enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
2772 if (enemy->aiBytecode != NULL) {
2773 script = start_script(enemy->aiBytecode, EVT_PRIORITY_A, 0);
2774 enemy->aiScript = script;
2775 enemy->aiScriptID = script->id;
2776 enemy->unk_C8 = 100;
2777 script->owner1.enemy = enemy;
2778 script->owner2.npcID = enemy->npcID;
2779 script->groupFlags = enemy->scriptGroup;
2780 }
2781 }
2782 }
2783 }
2784
2785 for (e = 0; e < currentEncounter->numEncounters; e++) {
2786 encounter = currentEncounter->encounterList[e];
2787 if (encounter == NULL) {
2788 continue;
2789 }
2790 for (i = 0; i < encounter->count; i++) {
2791 enemy = encounter->enemy[i];
2792 if (enemy == NULL) {
2793 continue;
2794 }
2795 if (!(enemy->flags & ENEMY_FLAG_DISABLE_AI)) {
2796 if (enemy->auxBytecode != NULL) {
2797 script = start_script(enemy->auxBytecode, EVT_PRIORITY_A, 0);
2798 enemy->auxScript = script;
2799 enemy->auxScriptID = script->id;
2800 script->owner1.enemy = enemy;
2801 script->owner2.npcID = enemy->npcID;
2802 script->groupFlags = enemy->scriptGroup;
2803 }
2804 }
2805 }
2806 }
2809 EncounterStateChanged = TRUE;
2811 break;
2812 }
2813}
Bytecode EvtScript[]
#define ASSERT(condition)
s32 get_defeated(s32 mapID, s32 encounterID)
Definition encounter.c:202
EnemyDrops DefaultEnemyDrops
Definition encounter.c:83
@ ENEMY_FLAG_FLYING
Definition enums.h:4532
@ ENEMY_FLAG_IGNORE_ENTITY_COLLISION
Definition enums.h:4531
@ ENEMY_FLAG_HAS_NO_SPRITE
Definition enums.h:4535
@ ENEMY_FLAG_GRAVITY
Definition enums.h:4533
@ ENEMY_FLAG_USE_PLAYER_SPRITE
Definition enums.h:4538
@ ENEMY_FLAG_USE_INSPECT_ICON
Definition enums.h:4536
@ ENEMY_FLAG_NO_SHADOW_RAYCAST
Definition enums.h:4534
@ ENEMY_FLAG_DONT_UPDATE_SHADOW_Y
Definition enums.h:4528
@ ENEMY_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:4530
@ ENEMY_FLAG_IGNORE_WORLD_COLLISION
Definition enums.h:4529
@ ENCOUNTER_SUBSTATE_CREATE_RUN_INIT_SCRIPT
Definition enums.h:6304
@ ENCOUNTER_SUBSTATE_CREATE_RUN_AI
Definition enums.h:6305
@ ENCOUNTER_SUBSTATE_CREATE_INIT
Definition enums.h:6303
@ NPC_FLAG_IGNORE_ENTITY_COLLISION
Definition enums.h:3013
@ NPC_FLAG_FLYING
Definition enums.h:3001
@ NPC_FLAG_HAS_NO_SPRITE
Definition enums.h:3022
@ NPC_FLAG_IGNORE_WORLD_COLLISION
Definition enums.h:3004
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:3006
@ NPC_FLAG_GRAVITY
Definition enums.h:3007
@ NPC_FLAG_NO_SHADOW_RAYCAST
Definition enums.h:3003
@ NPC_FLAG_USE_INSPECT_ICON
Definition enums.h:3026
@ NPC_FLAG_DONT_UPDATE_SHADOW_Y
Definition enums.h:3008
@ EVT_GROUP_HOSTILE_NPC
Definition evt.h:144
void * heap_malloc(s32 size)
Definition heap.c:34
s8 resetMapEncounterFlags
Definition npc.h:389
EvtScript * ai
Definition npc.h:149
EvtScript * onDefeat
Definition npc.h:152
s16 height
Definition npc.h:145
s32 unk_C0
Definition npc.h:338
NpcInitialVars initVar
Definition npc.h:250
u8 aiDetectFlags
Definition npc.h:275
s16 battle
Definition npc.h:285
EnemyDrops drops
Definition npc.h:252
EvtScript * aux
Definition npc.h:151
EnemyTerritory territory
Definition npc.h:253
s16 radius
Definition npc.h:146
struct NpcData::@52 animations
s32 * array
Definition npc.h:240
u32 aiFlags
Definition npc.h:276
s16 recentMaps[2]
Definition npc.h:404
s8 encounterIndex
Definition npc.h:296
s32 yaw
Definition npc.h:251
s32 initScriptID
Definition npc.h:317
s32 create_peach_npc(NpcBlueprint *blueprint)
Definition npc.c:198
s32 initVarCount
Definition npc.h:249
s32 id
Definition npc.h:244
s32 * npcGroupList
Definition npc.h:391
EvtScript * onInteract
Definition npc.h:148
void * otherAI
Definition npc.h:147
s32 * animList
Definition npc.h:341
s32 create_standard_npc(NpcBlueprint *blueprint, AnimID *animList)
Definition npc.c:194
s16 stage
Definition npc.h:286
s32 unk_24
Definition npc.h:154
EvtScript * initBytecode
Definition npc.h:305
s16 spawnPos[3]
Definition npc.h:301
NpcData * npcs
Definition npc.h:284
s32 unk_C4
Definition npc.h:339
AnimID * extraAnimations
Definition npc.h:277
s32 flags
Definition npc.h:247
s32 value
Definition npc.h:238
struct Evt * initScript
Definition npc.h:311
Npc * get_npc_by_index(s32 listIndex)
Definition npc.c:271
u8 aiDetectFlags
Definition npc.h:330
EvtScript * init
Definition npc.h:248
Vec3f pos
Definition npc.h:246
EvtScript * unk_B8
Definition npc.h:336
NpcSettings * settings
Definition npc.h:245
s32 unk_C8
Definition npc.h:340
s32 npcCount
Definition npc.h:283
u32 tattleMsg
Definition npc.h:344
s32 tattle
Definition npc.h:278
void set_npc_yaw(Npc *npc, f32 yaw)
Definition npc.c:1246
void * unk_64
Definition npc.h:323
EvtScript * onHit
Definition npc.h:150
EvtScript * aiBytecode
Definition npc.h:307
struct Evt * unk_BC
Definition npc.h:337
s32 flags
Definition npc.h:153
AnimID defaultAnim
Definition npc.h:144
EvtScript * auxBytecode
Definition npc.h:309
EnemyTerritory * territory
Definition npc.h:342
Definition npc.h:243
Zero-terminated.
Definition npc.h:282
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define EVT_LIMIT
Definition macros.h:47
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 unk_96
f32 planarFlyDist
f32 shadowScale
Vec3s homePos

Referenced by update_encounters().

◆ init_encounters_ui()

void init_encounters_ui ( void )

Definition at line 2815 of file encounter.c.

2815 {
2816}

Referenced by draw_encounter_ui().

◆ is_starting_conversation()

s32 is_starting_conversation ( void )

Definition at line 2818 of file encounter.c.

2818 {
2820
2822 ret = TRUE;
2823 }
2824 return ret;
2825}

Referenced by partner_use_ability(), phys_update_jump(), should_continue_pulse_stone(), and test_item_entity_position().

Variable Documentation

◆ D_80077C40

b32 D_80077C40 = FALSE

Definition at line 22 of file encounter.c.

Referenced by update_encounters_post_battle(), and update_encounters_pre_battle().

◆ EncounterStateChanged

◆ EVS_MerleeDropCoins

EvtScript EVS_MerleeDropCoins

Definition at line 26 of file encounter.c.

26 {
27 Wait(10)
29 Wait(10)
30 Call(CreateNpc, NPC_BTL_MERLEE, ANIM_BattleMerlee_Gather)
35 Thread
39 Wait(30)
40 Call(SetNpcAnimation, NPC_BTL_MERLEE, ANIM_BattleMerlee_Release)
43 Wait(20)
44 Thread
52 Wait(15)
54 Wait(15)
56 IfEq(LVar0, 1)
57 Return
58 EndIf
60 Wait(15)
61 Return
62 End
63};
@ NPC_BTL_MERLEE
Definition enums.h:2529
@ SOUND_MAGIC_DESCENDING
Definition enums.h:1414
ApiStatus ShowMerleeCoinMessage(Evt *script, b32 isInitialCall)
ApiStatus PlaySound(Evt *script, b32 isInitialCall)
ApiStatus FadeBackgroundLighten(Evt *script, b32 isInitialCall)
ApiStatus DeleteNpc(Evt *script, b32 isInitialCall)
ApiStatus PlayMerleeGatherFX(Evt *script, b32 isInitialCall)
ApiStatus SetNpcAnimation(Evt *script, b32 isInitialCall)
ApiStatus FadeInMerlee(Evt *script, b32 isInitialCall)
ApiStatus MerleeStopFX(Evt *script, b32 isInitialCall)
ApiStatus FadeOutMerlee(Evt *script, b32 isInitialCall)
ApiStatus MerleeUpdateFX(Evt *script, b32 isInitialCall)
ApiStatus FadeBackgroundDarken(Evt *script, b32 isInitialCall)
ApiStatus CreateNpc(Evt *script, b32 isInitialCall)
ApiStatus SetNpcPos(Evt *script, b32 isInitialCall)
ApiStatus PlayMerleeOrbFX(Evt *script, b32 isInitialCall)
ApiStatus HasMerleeCasts(Evt *script, b32 isInitialCall)
ApiStatus SetNpcYaw(Evt *script, b32 isInitialCall)
ApiStatus GetCamLookAtObjVector(Evt *script, b32 isInitialCall)
ApiStatus ShowMerleeRanOutMessage(Evt *script, b32 isInitialCall)
ApiStatus SetNpcFlagBits(Evt *script, b32 isInitialCall)
ApiStatus GetPlayerPos(Evt *script, b32 isInitialCall)
#define End
Signals the end of EVT script data. A script missing this will likely crash on load.
Definition macros.h:213
#define EndIf
Marks the end of an if statement or an else block.
Definition macros.h:298
#define Thread
Marks the start of a thread block.
Definition macros.h:544
#define EndThread
Marks the end of a thread block.
Definition macros.h:547
#define LVar2
Definition macros.h:150
#define LVar1
Definition macros.h:149
#define Wait(NUM_FRAMES)
Blocks for the given number of frames.
Definition macros.h:254
#define IfEq(LVAR, RVAR)
Marks the beginning of an if statement that only executes if LVAR == RVAR.
Definition macros.h:269
#define Call(FUNC, ARGS...)
Calls a given C EVT API function with any number of arguments.
Definition macros.h:576
#define LVar0
Definition macros.h:148
#define Return
Kills the current EVT thread.
Definition macros.h:217

Referenced by update_encounters_post_battle().

◆ EVS_NpcDefeat

EvtScript EVS_NpcDefeat
Initial value:
= {
}
ApiStatus OnDefeatEnemy(Evt *script, b32 isInitialCall)
ApiStatus GetBattleOutcome(Evt *script, b32 isInitialCall)
#define Switch(LVAR)
Marks the start of a switch statement.
Definition macros.h:311
#define CaseEq(RVAR)
Marks the start of a switch case that executes only if LVAR == RVAR. It also marks the end of any pre...
Definition macros.h:319
#define EndSwitch
Marks the end of a switch statement and any case.
Definition macros.h:362

Definition at line 65 of file encounter.c.

Referenced by update_encounters_post_battle().

◆ EVS_FleeBattleDrops

EvtScript EVS_FleeBattleDrops
Initial value:
= {
}
ApiStatus OnFleeBattleDrops(Evt *script, b32 isInitialCall)

Definition at line 77 of file encounter.c.

77 {
79 Return
80 End
81};

Referenced by update_encounters_post_battle().

◆ DefaultEnemyDrops

EnemyDrops DefaultEnemyDrops

Definition at line 83 of file encounter.c.

83 {
84 .dropFlags = NPC_DROP_FLAG_80,
85 .itemDropChance = 10,
86 .itemDrops = {
87 {
88 .item = ITEM_MUSHROOM,
89 .weight = 50,
90 .flagIdx = -1,
91 },
92 },
93 .heartDrops = {
94 {
95 .cutoff = F16(75),
96 .generalChance = F16(100),
97 .attempts = 0,
98 .chancePerAttempt = 1,
99 },
100 {
101 .cutoff = F16(50),
102 .generalChance = F16(75),
103 .attempts = 0,
104 .chancePerAttempt = 2,
105 },
106 {
107 .cutoff = F16(25),
108 .generalChance = F16(50),
109 .attempts = 0,
110 .chancePerAttempt = 3,
111 },
112 {
113 .cutoff = F16(0),
114 .generalChance = F16(25),
115 .attempts = 0,
116 .chancePerAttempt = 4,
117 },
118 },
119 .flowerDrops = {
120 {
121 .cutoff = 1,
122 .generalChance = 3,
123 .attempts = 0,
124 .chancePerAttempt = 0,
125 },
126 },
127 .minCoinBonus = 0,
128 .maxCoinBonus = 0,
129};
@ NPC_DROP_FLAG_80
Definition enums.h:5089
#define F16(f)
Fixed-point short literal.
Definition macros.h:171

Referenced by create_encounters().

◆ EnemyNpcHit

EvtScript EnemyNpcHit
Initial value:
= {
IfEq(LVar0, 0)
Set(LVarA, 0)
Loop(30)
Add(LVarA, 40)
Wait(1)
}
@ ENEMY_ANIM_INDEX_HIT
Definition enums.h:3433
@ NPC_SELF
Definition enums.h:2526
ApiStatus SetNpcRotation(Evt *script, b32 isInitialCall)
ApiStatus GetSelfAnimationFromTable(Evt *script, b32 isInitialCall)
ApiStatus GetOwnerEncounterTrigger(Evt *script, b32 isInitialCall)
ApiStatus func_800458CC(Evt *script, b32 isInitialCall)
#define Set(VAR, INT_VALUE)
Sets the given variable to a given value casted to an integer.
Definition macros.h:365
#define Add(VAR, INT_VALUE)
Definition macros.h:376
#define EndLoop
Marks the end of a loop.
Definition macros.h:248
#define EndCaseGroup
Marks the end of a switch case group (CaseOrEq and/or CaseAndEq), stopping fallthrough.
Definition macros.h:352
#define CaseOrEq(RVAR)
Marks the start of a switch case that executes only if LVAR == RVAR.
Definition macros.h:341
#define ExecWait(EVT_SOURCE)
Launches a new child thread.
Definition macros.h:475
#define LVarA
Definition macros.h:158
#define Loop(TIMES)
Marks the beginning of a loop.
Definition macros.h:245
EvtScript EVS_NpcHitRecoil
Definition 38F00.c:13

Definition at line 131 of file encounter.c.

◆ EnemyNpcDefeat

EvtScript EnemyNpcDefeat
Initial value:
= {
}
ApiStatus SetEnemyFlagBits(Evt *script, b32 isInitialCall)
ApiStatus RemoveNpc(Evt *script, b32 isInitialCall)
ApiStatus DoNpcDefeat(Evt *script, b32 isInitialCall)
ApiStatus OnPlayerFled(Evt *script, b32 isInitialCall)

Definition at line 158 of file encounter.c.

◆ gEncounterState

◆ gEncounterSubState

◆ gCurrentEncounter

◆ HasPreBattleSongPushed

s8 HasPreBattleSongPushed

Definition at line 178 of file encounter.c.

Referenced by update_encounters_post_battle(), and update_encounters_pre_battle().

◆ PendingPartnerAbilityResume

b8 PendingPartnerAbilityResume

Definition at line 179 of file encounter.c.

Referenced by update_encounters_post_battle().

◆ LastBattleStartedBySpin

b8 LastBattleStartedBySpin

Definition at line 180 of file encounter.c.

Referenced by update_encounters_post_battle().

◆ gFirstStrikeMessagePos

s16 gFirstStrikeMessagePos

Definition at line 181 of file encounter.c.

Referenced by show_first_strike_message().

◆ WorldMerleeEffectsTime

BSS s32 WorldMerleeEffectsTime

Definition at line 183 of file encounter.c.

◆ WorldMerleeBasePosY

BSS f32 WorldMerleeBasePosY

Definition at line 184 of file encounter.c.

◆ WorldMerleeOrbEffect

BSS EffectInstance* WorldMerleeOrbEffect

Definition at line 185 of file encounter.c.

◆ WorldMerleeWaveEffect

BSS EffectInstance* WorldMerleeWaveEffect

Definition at line 186 of file encounter.c.

◆ MerleeDropCoinsEvt

BSS Evt* MerleeDropCoinsEvt

Definition at line 187 of file encounter.c.

Referenced by update_encounters_post_battle().

◆ MerleeDropCoinsEvtID

BSS s32 MerleeDropCoinsEvtID

Definition at line 188 of file encounter.c.

Referenced by update_encounters_post_battle().

◆ WorldMerleeEffectsState

BSS s16 WorldMerleeEffectsState

Definition at line 189 of file encounter.c.