Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
encounter.c
Go to the documentation of this file.
1#include "battle/battle.h"
2#include "script_api/battle.h"
3#include "npc.h"
4#include "effects.h"
5#include "hud_element.h"
6#include "world/partners.h"
7#include "sprite.h"
8#include "sprite/npc/BattleMerlee.h"
9#include "sprite/player.h"
10#include "model.h"
11#include "dx/debug_menu.h"
12
13API_CALLABLE(ShowMerleeCoinMessage);
14API_CALLABLE(ShowMerleeRanOutMessage);
15API_CALLABLE(FadeInMerlee);
16API_CALLABLE(FadeOutMerlee);
17API_CALLABLE(MerleeUpdateFX);
18API_CALLABLE(MerleeStopFX);
19API_CALLABLE(PlayMerleeGatherFX);
20API_CALLABLE(PlayMerleeOrbFX);
21
23
25
64
76
82
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};
130
157
173
177
182
190
191enum {
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};
196
200s32 get_coin_drop_amount(Enemy* enemy);
201
202s32 get_defeated(s32 mapID, s32 encounterID) {
203 EncounterStatus* currentEncounter = &gCurrentEncounter;
204 s32 encounterIdx = encounterID / 32;
205 s32 encounterShift = encounterID % 32;
206
207 return currentEncounter->defeatFlags[mapID][encounterIdx] & (1 << encounterShift);
208}
209
210void set_defeated(s32 mapID, s32 encounterID) {
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}
228
229API_CALLABLE(ShowMerleeCoinMessage) {
230 if (isInitialCall) {
231 show_merlee_message(0, 60);
232 }
233
235 return ApiStatus_BLOCK;
236 } else {
237 return ApiStatus_DONE2;
238 }
239}
240
241API_CALLABLE(ShowMerleeRanOutMessage) {
242 if (isInitialCall) {
243 show_merlee_message(1, 60);
244 }
245
247 return ApiStatus_BLOCK;
248 } else {
249 return ApiStatus_DONE2;
250 }
251}
252
253API_CALLABLE(FadeBackgroundDarken) {
254 if (isInitialCall) {
257 mdl_set_shroud_tint_params(0, 0, 0, 0);
258 script->functionTemp[0] = 25;
259 }
260
261 mdl_set_shroud_tint_params(0, 0, 0, ((25 - script->functionTemp[0]) * 10) & 254);
262 script->functionTemp[0]--;
263
264 if (script->functionTemp[0] == 0) {
265 return ApiStatus_DONE2;
266 } else {
267 return ApiStatus_BLOCK;
268 }
269}
270
271API_CALLABLE(FadeBackgroundLighten) {
272 if (isInitialCall) {
273 script->functionTemp[0] = 25;
274 }
275
276 mdl_set_shroud_tint_params(0, 0, 0, (script->functionTemp[0] * 10) & 254);
277 script->functionTemp[0] -= 5;
278
279 if (script->functionTemp[0] == 0) {
280 mdl_set_shroud_tint_params(0, 0, 0, 0);
281 return ApiStatus_DONE2;
282 } else {
283 return ApiStatus_BLOCK;
284 }
285}
286
287API_CALLABLE(FadeInMerlee) {
289
290 if (isInitialCall) {
292 npc->alpha = 0;
293 }
294
295 npc->alpha += 17;
296
297 if ((u32)(npc->alpha & 0xFF) >= 0xFF) {
298 npc->alpha = 0xFF;
299 return ApiStatus_DONE1;
300 } else {
301 return ApiStatus_BLOCK;
302 }
303}
304
305API_CALLABLE(FadeOutMerlee) {
307
308 npc->alpha -= 17;
309 if (npc->alpha == 0) {
310 npc->alpha = 0;
311 return ApiStatus_DONE1;
312 } else {
313 return ApiStatus_BLOCK;
314 }
315}
316
317// same as BattleMerleeUpdateFX aside from syms
318API_CALLABLE(MerleeUpdateFX) {
320 EnergyOrbWaveFXData* effectData;
321
322 if (isInitialCall) {
323 script->functionTemp[1] = 0;
324 WorldMerleeBasePosY = merlee->pos.y;
325 WorldMerleeOrbEffect = fx_energy_orb_wave(0, merlee->pos.x, merlee->pos.y, merlee->pos.z, 0.4f, 0);
326 WorldMerleeWaveEffect = fx_energy_orb_wave(3, merlee->pos.x, merlee->pos.y, merlee->pos.z, 0.00001f, 0);
330 }
331
332 merlee->pos.y = WorldMerleeBasePosY + sin_rad(DEG_TO_RAD(script->functionTemp[1])) * 3.0f;
333
334 script->functionTemp[1] += 10;
335 script->functionTemp[1] = clamp_angle(script->functionTemp[1]);
336
338 effectData->pos.x = merlee->pos.x;
339 effectData->pos.y = merlee->pos.y + 16.0f;
340 effectData->pos.z = merlee->pos.z;
341
343 effectData->pos.x = merlee->pos.x;
344 effectData->pos.y = merlee->pos.y + 16.0f;
345 effectData->pos.z = merlee->pos.z + 5.0f;
346
352 return ApiStatus_DONE1;
353 }
354
357 effectData->scale += 0.35;
358 if (effectData->scale > 3.5) {
359 effectData->scale = 3.5;
360 }
361
362 if (WorldMerleeEffectsTime != 0) {
364 } else {
366 effectData->scale += 0.5;
367 if (effectData->scale > 5.0) {
369 }
370 }
371 }
372 return ApiStatus_BLOCK;
373}
374
375API_CALLABLE(MerleeStopFX) {
377 return ApiStatus_DONE2;
378}
379
380API_CALLABLE(GetCamLookAtObjVector) {
381 script->varTable[0] = gCameras[gCurrentCameraID].lookAt_obj.x;
382 script->varTable[1] = gCameras[gCurrentCameraID].lookAt_obj.y;
383 script->varTable[2] = gCameras[gCurrentCameraID].lookAt_obj.z;
384
385 return ApiStatus_DONE2;
386}
387
388API_CALLABLE(HasMerleeCasts) {
389 script->varTable[0] = FALSE;
391 script->varTable[0] = TRUE;
392 }
393
394 return ApiStatus_DONE2;
395}
396
397API_CALLABLE(PlayMerleeGatherFX) {
398 Bytecode* args = script->ptrReadPos;
399 s32 var0 = evt_get_variable(script, *args++);
400 s32 var1 = evt_get_variable(script, *args++);
401 s32 var2 = evt_get_variable(script, *args++);
402
403 fx_energy_in_out(6, var0, var1, var2, 1.2f, 30);
404 return ApiStatus_DONE2;
405}
406
407API_CALLABLE(PlayMerleeOrbFX) {
408 Bytecode* args = script->ptrReadPos;
409 s32 var0 = evt_get_variable(script, *args++);
410 s32 var1 = evt_get_variable(script, *args++);
411 s32 var2 = evt_get_variable(script, *args++);
412
413 fx_energy_orb_wave(9, var0, var1, var2, 5.0f, 15);
414 return ApiStatus_DONE2;
415}
416
417API_CALLABLE(OnDefeatEnemy) {
418 Enemy* enemy = script->owner1.enemy;
419 Npc* npc = get_npc_unsafe(enemy->npcID);
420 s32 temp1;
421
422 if (isInitialCall) {
423 script->functionTemp[0] = 0;
424 script->functionTemp[1] = 20;
425 }
426
427 if (script->functionTemp[1] & 1) {
428 npc->flags &= ~NPC_FLAG_INVISIBLE;
429 } else {
431 }
432
433 if (script->functionTemp[1] == 15) {
435 fx_damage_stars(FX_DAMAGE_STARS_1, npc->pos.x, npc->pos.y + (npc->collisionHeight / 2), npc->pos.z, 0, -1.0f, 0, 10);
436 }
437
438 temp1 = script->functionTemp[1];
439 if (script->functionTemp[1] == 10) {
440 fx_big_smoke_puff(npc->pos.x, npc->pos.y + 10.0f, npc->pos.z + 10.0f);
441 if (script->functionTemp[1] == temp1) { // what? (never can be false, seemingly)
442 spawn_drops(enemy);
443 }
444 }
445
446 script->functionTemp[1]--;
447 if (script->functionTemp[1] == 0) {
449 return ApiStatus_DONE1;
450 }
451
452 return ApiStatus_BLOCK;
453}
454
455API_CALLABLE(OnFleeBattleDrops) {
456 PlayerStatus* playerStatus = &gPlayerStatus;
457 PlayerData* playerData = &gPlayerData;
458
459 if (isInitialCall) {
460 script->functionTemp[0] = 0;
461 script->functionTemp[1] = 40;
462 script->functionTemp[2] = 0;
463 }
464
465 script->functionTemp[2]++;
466 if (script->functionTemp[2] >= 5) {
467 if (rand_int(100) < 50) {
468 if (playerData->coins != 0) {
469 playerData->coins--;
470 make_item_entity_delayed(ITEM_COIN, playerStatus->pos.x,
471 playerStatus->pos.y + playerStatus->colliderHeight, playerStatus->pos.z,
473 }
474 }
475 script->functionTemp[2] = 0;
476 }
477
478 return --script->functionTemp[1] == 0;
479}
480
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}
1257
1259}
1260
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}
1486
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}
1562
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}
1618
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}
2252
2254 EncounterStatus* currentEncounter = &gCurrentEncounter;
2255 s32 ret = currentEncounter->fadeOutAccel;
2256
2257 if (ret != 0) {
2260 }
2261}
2262
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}
2318
2321
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}
2460
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}
2814
2816}
2817
2820
2822 ret = TRUE;
2823 }
2824 return ret;
2825}
u8 groupFlags
s32 b32
AnimID trueAnimation
Encoding back-facing sprite.
union Evt::@8 owner1
Initially -1.
union Evt::@9 owner2
Initially -1.
Bytecode EvtScript[]
s8 b8
#define get_msg_width
#define sfx_play_sound_at_position
#define sqrtf
#define rand_int
#define clamp_angle
#define draw_msg
#define atan2
#define draw_box
@ FX_DAMAGE_STARS_3
Definition effects.h:359
@ FX_DAMAGE_STARS_1
Definition effects.h:357
struct EnergyOrbWaveFXData * energyOrbWave
Definition effects.h:2546
EffectData data
Definition effects.h:2605
#define ASSERT(condition)
void create_encounters(void)
Definition encounter.c:2461
b32 check_conversation_trigger(void)
Definition encounter.c:2322
void update_encounters_conversation(void)
Definition encounter.c:2263
void setup_status_bar_for_world(void)
Definition inventory.c:1450
void update_encounters_neutral(void)
Definition encounter.c:481
void show_first_strike_message(void)
Definition encounter.c:1563
BSS EffectInstance * WorldMerleeOrbEffect
Definition encounter.c:185
b8 LastBattleStartedBySpin
Definition encounter.c:180
void update_encounters_post_battle(void)
Definition encounter.c:1619
s8 HasPreBattleSongPushed
Definition encounter.c:178
s32 get_coin_drop_amount(Enemy *enemy)
Definition 23680.c:312
BSS s32 WorldMerleeEffectsTime
Definition encounter.c:183
BSS s16 WorldMerleeEffectsState
Definition encounter.c:189
void init_encounters_ui(void)
Definition encounter.c:2815
BSS f32 WorldMerleeBasePosY
Definition encounter.c:184
BSS s32 MerleeDropCoinsEvtID
Definition encounter.c:188
EvtScript EnemyNpcDefeat
Definition encounter.c:158
void update_encounters_pre_battle(void)
Definition encounter.c:1261
s32 get_defeated(s32 mapID, s32 encounterID)
Definition encounter.c:202
s32 is_starting_conversation(void)
Definition encounter.c:2818
s16 gFirstStrikeMessagePos
Definition encounter.c:181
void set_defeated(s32 mapID, s32 encounterID)
Definition encounter.c:210
EvtScript EnemyNpcHit
Definition encounter.c:131
EvtScript EVS_NpcDefeat
Definition encounter.c:65
void draw_encounters_pre_battle(void)
Definition encounter.c:1487
void set_battle_formation(Battle *)
Definition battle.c:141
b32 D_80077C40
Definition encounter.c:22
BSS Evt * MerleeDropCoinsEvt
Definition encounter.c:187
s32 gEncounterState
Definition encounter.c:174
void draw_encounters_conversation(void)
Definition encounter.c:2319
EvtScript EVS_MerleeDropCoins
Definition encounter.c:26
EvtScript EVS_FleeBattleDrops
Definition encounter.c:77
EncounterStatus gCurrentEncounter
Definition encounter.c:176
b32 EncounterStateChanged
Definition encounter.c:24
void draw_encounters_neutral(void)
Definition encounter.c:1258
void partner_handle_after_battle(void)
Definition partners.c:1081
void draw_encounters_post_battle(void)
Definition encounter.c:2253
b8 PendingPartnerAbilityResume
Definition encounter.c:179
BSS EffectInstance * WorldMerleeWaveEffect
Definition encounter.c:186
@ MERLEE_EFFECTS_DISMISS
Definition encounter.c:194
@ MERLEE_EFFECTS_RELEASE
Definition encounter.c:193
@ MERLEE_EFFECTS_HOLD
Definition encounter.c:192
s32 gEncounterSubState
Definition encounter.c:175
EnemyDrops DefaultEnemyDrops
Definition encounter.c:83
@ FX_INSTANCE_FLAG_DISMISS
Definition enums.h:3517
@ WINDOW_STYLE_4
Definition enums.h:6374
@ WINDOW_STYLE_20
Definition enums.h:6390
@ OVERLAY_NONE
Definition enums.h:2387
@ OVERLAY_START_BATTLE
Definition enums.h:2398
@ OVERLAY_SCREEN_COLOR
Definition enums.h:2388
@ ENV_TINT_SHROUD
Definition enums.h:4387
@ BUTTON_A
Definition enums.h:2790
@ NPC_DROP_FLAG_80
Definition enums.h:5089
@ DEBUG_CONTACT_CANT_TOUCH
Definition enums.h:4268
@ DEBUG_CONTACT_DIE_ON_TOUCH
Definition enums.h:4269
@ SCREEN_LAYER_FRONT
Definition enums.h:2382
@ SCREEN_LAYER_BACK
Definition enums.h:2383
@ ENEMY_ANIM_INDEX_HIT
Definition enums.h:3433
@ 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
@ MSG_PAL_STANDARD
Definition enums.h:5415
@ ITEM_SPAWN_MODE_TOSS_SPAWN_ALWAYS
Definition enums.h:2294
@ ENCOUNTER_SUBSTATE_CONVERSATION_END
Definition enums.h:6321
@ ENCOUNTER_SUBSTATE_CONVERSATION_INIT
Definition enums.h:6320
@ SONG_NORMAL_BATTLE
Definition enums.h:284
@ AI_FLAG_1
Definition enums.h:4569
@ PS_FLAG_FALLING
Definition enums.h:3036
@ PS_FLAG_ENTERING_BATTLE
Definition enums.h:3061
@ PS_FLAG_JUMPING
Definition enums.h:3035
@ PS_FLAG_ARMS_RAISED
Definition enums.h:3063
@ PS_FLAG_HAMMER_CHECK
Definition enums.h:3073
@ PS_FLAG_INPUT_DISABLED
Definition enums.h:3052
@ PS_FLAG_HAS_CONVERSATION_NPC
Definition enums.h:3074
@ PARTNER_ACTION_NONE
Definition enums.h:2932
@ 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
@ 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_INIT
Definition enums.h:6325
@ 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_DISABLE_AI
Definition enums.h:4526
@ ENEMY_FLAG_DO_NOT_KILL
Definition enums.h:4523
@ ENEMY_FLAG_FLYING
Definition enums.h:4532
@ ENEMY_FLAG_RAYCAST_TO_INTERACT
Definition enums.h:4537
@ ENEMY_FLAG_NO_DELAY_AFTER_FLEE
Definition enums.h:4539
@ ENEMY_FLAG_IGNORE_ENTITY_COLLISION
Definition enums.h:4531
@ ENEMY_FLAG_HAS_NO_SPRITE
Definition enums.h:4535
@ 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_GRAVITY
Definition enums.h:4533
@ ENEMY_FLAG_FLED
Definition enums.h:4525
@ ENEMY_FLAG_IGNORE_PARTNER
Definition enums.h:4549
@ ENEMY_FLAG_ENABLE_HIT_SCRIPT
Definition enums.h:4524
@ ENEMY_FLAG_USE_PLAYER_SPRITE
Definition enums.h:4538
@ ENEMY_FLAG_PROJECTILE
Definition enums.h:4527
@ ENEMY_FLAG_DONT_SUSPEND_SCRIPTS
Definition enums.h:4540
@ ENEMY_FLAG_SKIP_BATTLE
Definition enums.h:4541
@ ENEMY_FLAG_USE_INSPECT_ICON
Definition enums.h:4536
@ ENEMY_FLAG_IGNORE_SPIN
Definition enums.h:4550
@ ENEMY_FLAG_NO_SHADOW_RAYCAST
Definition enums.h:4534
@ ENEMY_FLAG_SUSPENDED
Definition enums.h:4552
@ ENEMY_FLAG_IGNORE_TOUCH
Definition enums.h:4545
@ ENEMY_FLAG_CANT_INTERACT
Definition enums.h:4548
@ ENEMY_FLAG_DONT_UPDATE_SHADOW_Y
Definition enums.h:4528
@ ENEMY_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:4530
@ ENEMY_FLAG_IGNORE_JUMP
Definition enums.h:4546
@ ENEMY_FLAG_IGNORE_WORLD_COLLISION
Definition enums.h:4529
@ ENEMY_FLAG_ACTIVE_WHILE_OFFSCREEN
Definition enums.h:4542
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4696
@ NPC_SELF
Definition enums.h:2526
@ NPC_BTL_MERLEE
Definition enums.h:2529
@ PA_FLAG_DIZZY_ATTACK_ENCOUNTER
Definition enums.h:3109
@ PA_FLAG_SPINNING
Definition enums.h:3107
@ PA_FLAG_8BIT_MARIO
Definition enums.h:3105
@ ENCOUNTER_SUBSTATE_PRE_BATTLE_INIT
Definition enums.h:6313
@ 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_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
@ ABILITY_FIRST_ATTACK
Definition enums.h:439
@ SOUND_ACTOR_DEATH
Definition enums.h:1293
@ SOUND_MAGIC_DESCENDING
Definition enums.h:1414
@ SOUND_SPEEDY_SPIN_ATTACK
Definition enums.h:1553
@ SOUND_NONE
Definition enums.h:547
@ SOUND_SPEEDY_SPIN
Definition enums.h:1551
@ SOUND_SPIN_ATTACK
Definition enums.h:1552
@ SOUND_MAGIC_ASCENDING
Definition enums.h:1413
@ SOUND_MERLEE_APPEAR
Definition enums.h:972
@ SOUND_SPIN
Definition enums.h:1550
@ SOUND_HIT_PLAYER_NORMAL
Definition enums.h:719
@ OUTCOME_ENEMY_FLED
Definition enums.h:1905
@ OUTCOME_PLAYER_WON
Definition enums.h:1902
@ OUTCOME_SKIP
Definition enums.h:1906
@ OUTCOME_PLAYER_LOST
Definition enums.h:1903
@ OUTCOME_PLAYER_FLED
Definition enums.h:1904
@ PARTNER_BOW
Definition enums.h:2894
@ ACTION_STATE_RIDE
Definition enums.h:2461
@ 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_IDLE
Definition enums.h:2426
@ ACTION_STATE_TALK
Reading signs doesn't count.
Definition enums.h:2440
@ ACTION_STATE_TORNADO_POUND
Definition enums.h:2444
@ ACTION_STATE_USE_SPINNING_FLOWER
Definition enums.h:2457
@ 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_POST_BATTLE
Definition enums.h:6299
@ 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
@ DEMO_STATE_CHANGE_MAP
Definition enums.h:3537
@ 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
@ ENCOUNTER_SUBSTATE_NEUTRAL
Definition enums.h:6309
@ 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_SUSPENDED
Definition enums.h:3029
@ NPC_FLAG_RAYCAST_TO_INTERACT
Definition enums.h:3027
@ 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_INVISIBLE
Definition enums.h:2999
@ 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_PRIORITY_A
Definition evt.h:153
#define ApiStatus_DONE2
Definition evt.h:118
s32 Bytecode
Definition evt.h:7
@ EVT_GROUP_HOSTILE_NPC
Definition evt.h:144
@ EVT_GROUP_FLAG_BATTLE
Definition evt.h:138
@ EVT_GROUP_FLAG_INTERACT
Definition evt.h:134
@ EVT_GROUP_PASSIVE_NPC
Definition evt.h:143
@ EVT_GROUP_NEVER_PAUSE
Definition evt.h:142
#define ApiStatus_DONE1
Definition evt.h:117
#define ApiStatus_BLOCK
Definition evt.h:116
@ EVT_FLAG_SUSPENDED
doesn't affect child
Definition evt.h:163
void set_screen_overlay_params_back(u8, f32)
void set_battle_stage(s32)
Definition battle.c:137
s32 evt_get_variable(Evt *script, Bytecode var)
Definition evt.c:1690
s32 is_ability_active(s32 arg0)
Definition inventory.c:1725
f32 fabsf(f32 f)
s32 is_merlee_message_done(void)
void get_screen_coords(s32 camID, f32 x, f32 y, f32 z, s32 *screenX, s32 *screenY, s32 *screenZ)
Definition cam_main.c:410
void set_screen_overlay_alpha(s32, f32)
void spawn_drops(Enemy *enemy)
Definition 23680.c:8
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 resume_all_group(s32 groupFlags)
s32 suspend_all_script(s32 id)
void set_screen_overlay_params_front(u8, f32)
void close_status_bar(void)
Definition inventory.c:1440
void mdl_set_all_tint_type(s32)
Definition model.c:4521
s32 enable_player_input(void)
Definition 77480.c:998
void set_script_flags(Evt *script, s32 flags)
void bgm_pop_battle_song(void)
Evt * start_script(EvtScript *source, s32 priority, s32 initialState)
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 show_merlee_message(s16, s16)
void set_screen_overlay_center(s32, s32, s32, s32)
void kill_script_by_ID(s32 id)
void set_screen_overlay_color(s32, u8, u8, u8)
void start_bounce_a(void)
Definition 7E9D0.c:300
void suggest_player_anim_allow_backward(AnimID anim)
Definition 77480.c:894
void partner_handle_before_battle(void)
Definition partners.c:1067
s32 resume_all_script(s32 id)
s32 does_script_exist(s32 id)
void load_battle(s32)
Definition battle.c:129
f32 sin_rad(f32 x)
Definition 43F0.c:713
void bgm_set_battle_song(s32, s32)
void bgm_push_battle_song(void)
Evt * start_script_in_group(EvtScript *source, u8 priority, u8 initialState, u8 groupFlags)
s32 make_item_entity_delayed(s32 itemID, f32 x, f32 y, f32 z, s32 itemSpawnMode, s32 pickupDelay, s32 pickupVar)
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)
void * heap_malloc(s32 size)
Definition heap.c:34
void mdl_set_shroud_tint_params(u8 r, u8 g, u8 b, u8 a)
Definition model.c:3906
s8 resetMapEncounterFlags
Definition npc.h:389
EvtScript * ai
Definition npc.h:149
EvtScript * onDefeat
Definition npc.h:152
s16 height
Definition npc.h:145
struct Evt * interactScript
Definition npc.h:312
s32 unk_C0
Definition npc.h:338
char unk_07
Definition npc.h:370
s16 coinsEarned
Definition npc.h:377
s8 scriptedBattle
battle started by StartBattle but not by encounter
Definition npc.h:380
NpcInitialVars initVar
Definition npc.h:250
u8 aiDetectFlags
Definition npc.h:275
s32 flags
Definition npc.h:295
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 savedNpcYaw
Definition npc.h:346
s16 radius
Definition npc.h:146
s16 npcID
Definition npc.h:300
EnemyDrops * drops
Definition npc.h:343
struct NpcData::@52 animations
s32 * array
Definition npc.h:240
s32 interactScriptID
Definition npc.h:318
s16 encounterID
Definition npc.h:355
u32 aiFlags
Definition npc.h:276
struct Evt * hitScript
Definition npc.h:314
FieldStatus unusedAttack3
Definition npc.h:402
FieldStatus unusedAttack1
Definition npc.h:400
s16 recentMaps[2]
Definition npc.h:404
void kill_enemy(Enemy *enemy)
Definition npc.c:2374
EvtScript * hitBytecode
Definition npc.h:308
s8 encounterIndex
Definition npc.h:296
s32 yaw
Definition npc.h:251
s8 instigatorValue
Definition npc.h:334
u8 scriptGroup
Definition npc.h:298
s32 auxScriptID
Definition npc.h:321
s32 initScriptID
Definition npc.h:317
Encounter * encounterList[24]
Definition npc.h:392
s32 create_peach_npc(NpcBlueprint *blueprint)
Definition npc.c:198
s32 initVarCount
Definition npc.h:249
s32 id
Definition npc.h:244
s8 battleTriggerCooldown
set to 15 after victory, 45 after fleeing
Definition npc.h:373
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
u8 damageTaken
Definition npc.h:375
s16 stage
Definition npc.h:286
Enemy * curEnemy
Definition npc.h:394
s32 unk_24
Definition npc.h:154
struct Evt * defeatScript
Definition npc.h:316
EvtScript * initBytecode
Definition npc.h:305
b8 hasMerleeCoinBonus
Definition npc.h:374
s8 numEncounters
Definition npc.h:384
Enemy * enemy[16]
Definition npc.h:352
s16 spawnPos[3]
Definition npc.h:301
s8 aiSuspendTime
Definition npc.h:333
s32 unk_DC
Definition npc.h:345
NpcData * npcs
Definition npc.h:284
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
s32 unk_C4
Definition npc.h:339
Vec3s unk_10
Definition npc.h:302
FieldStatus dizzyAttack
Definition npc.h:399
s32 count
Definition npc.h:351
s8 forbidFleeing
Definition npc.h:379
s8 hitboxIsActive
Definition npc.h:299
AnimID * extraAnimations
Definition npc.h:277
s32 flags
Definition npc.h:247
s32 fadeOutAccel
Definition npc.h:397
u8 dropFlags
Definition npc.h:187
s32 value
Definition npc.h:238
EvtScript * interactBytecode
Definition npc.h:306
s32 aiScriptID
Definition npc.h:319
struct Evt * initScript
Definition npc.h:311
s32 fadeOutAmount
Definition npc.h:395
Npc * get_npc_by_index(s32 listIndex)
Definition npc.c:271
s16 duration
Definition npc.h:362
u8 aiDetectFlags
Definition npc.h:330
s8 status
Definition npc.h:360
s32 defeatScriptID
Definition npc.h:322
NpcSettings * npcSettings
Definition npc.h:304
FieldStatus unusedAttack2
Definition npc.h:401
s8 instigatorValue
Definition npc.h:378
s8 battleOutcome
Definition npc.h:372
EvtScript * init
Definition npc.h:248
s16 stage
Definition npc.h:354
Vec3f pos
Definition npc.h:246
u32 aiFlags
Definition npc.h:332
s8 dropWhackaBump
Definition npc.h:381
s16 level
Definition npc.h:155
struct Evt * auxScript
Definition npc.h:315
EvtScript * unk_B8
Definition npc.h:336
NpcSettings * settings
Definition npc.h:245
s32 defeatFlags[60][12]
Definition npc.h:403
s32 unk_C8
Definition npc.h:340
s32 npcCount
Definition npc.h:283
s32 battleStartCountdown
Definition npc.h:398
u32 tattleMsg
Definition npc.h:344
s32 tattle
Definition npc.h:278
void set_npc_yaw(Npc *npc, f32 yaw)
Definition npc.c:1246
s8 encountered
Definition npc.h:297
s16 battle
Definition npc.h:353
void * unk_64
Definition npc.h:323
EvtScript * onHit
Definition npc.h:150
s8 firstStrikeType
Definition npc.h:367
EvtScript * defeatBytecode
Definition npc.h:310
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
s32 substateDelay
Definition npc.h:396
Encounter * curEncounter
Definition npc.h:393
struct Evt * aiScript
Definition npc.h:313
EvtScript * auxBytecode
Definition npc.h:309
EnemyTerritory * territory
Definition npc.h:342
s32 hitScriptID
Definition npc.h:320
Definition npc.h:294
Definition npc.h:243
Zero-terminated.
Definition npc.h:282
void partner_enable_input(void)
Definition partners.c:2480
void sfx_stop_sound(s32 soundID)
Definition sfx.c:507
void sfx_play_sound(s32 soundID)
Definition sfx.c:517
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 SetEnemyFlagBits(Evt *script, b32 isInitialCall)
ApiStatus FadeInMerlee(Evt *script, b32 isInitialCall)
ApiStatus MerleeStopFX(Evt *script, b32 isInitialCall)
ApiStatus FadeOutMerlee(Evt *script, b32 isInitialCall)
ApiStatus OnFleeBattleDrops(Evt *script, b32 isInitialCall)
ApiStatus SetNpcRotation(Evt *script, b32 isInitialCall)
ApiStatus MerleeUpdateFX(Evt *script, b32 isInitialCall)
ApiStatus FadeBackgroundDarken(Evt *script, b32 isInitialCall)
ApiStatus CreateNpc(Evt *script, b32 isInitialCall)
ApiStatus RemoveNpc(Evt *script, b32 isInitialCall)
ApiStatus GetSelfAnimationFromTable(Evt *script, b32 isInitialCall)
ApiStatus DoNpcDefeat(Evt *script, b32 isInitialCall)
ApiStatus SetNpcPos(Evt *script, b32 isInitialCall)
ApiStatus OnDefeatEnemy(Evt *script, b32 isInitialCall)
ApiStatus GetOwnerEncounterTrigger(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 func_800458CC(Evt *script, b32 isInitialCall)
ApiStatus OnPlayerFled(Evt *script, b32 isInitialCall)
ApiStatus SetNpcFlagBits(Evt *script, b32 isInitialCall)
ApiStatus GetPlayerPos(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 Set(VAR, INT_VALUE)
Sets the given variable to a given value casted to an integer.
Definition macros.h:365
#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 SCREEN_WIDTH
Definition macros.h:105
#define End
Signals the end of EVT script data. A script missing this will likely crash on load.
Definition macros.h:213
#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 BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define CaseOrEq(RVAR)
Marks the start of a switch case that executes only if LVAR == RVAR.
Definition macros.h:341
#define EndIf
Marks the end of an if statement or an else block.
Definition macros.h:298
#define SCREEN_HEIGHT
Definition macros.h:106
#define ExecWait(EVT_SOURCE)
Launches a new child thread.
Definition macros.h:475
#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 DEG_TO_RAD(deg)
Definition macros.h:134
#define LVar1
Definition macros.h:149
#define LVarA
Definition macros.h:158
#define Wait(NUM_FRAMES)
Blocks for the given number of frames.
Definition macros.h:254
#define SQ(x)
Definition macros.h:166
#define EndSwitch
Marks the end of a switch statement and any case.
Definition macros.h:362
#define IfEq(LVAR, RVAR)
Marks the beginning of an if statement that only executes if LVAR == RVAR.
Definition macros.h:269
#define F16(f)
Fixed-point short literal.
Definition macros.h:171
#define Call(FUNC, ARGS...)
Calls a given C EVT API function with any number of arguments.
Definition macros.h:576
#define Loop(TIMES)
Marks the beginning of a loop.
Definition macros.h:245
#define EVT_LIMIT
Definition macros.h:47
#define LVar0
Definition macros.h:148
#define Return
Kills the current EVT thread.
Definition macros.h:217
EvtScript EVS_NpcHitRecoil
Definition 38F00.c:13
@ SPRITE_ID_BACK_FACING
Definition sprite.h:13
Zero-terminated.
Definition battle.h:195
Vec3f lookAt_obj
void(* onRender)(struct Npc *)
Definition npc.h:89
void(* onUpdate)(struct Npc *)
Definition npc.h:88
s32 initialAnim
Definition npc.h:87
s32 flags
Definition npc.h:86
s16 collisionDiameter
s16 unk_96
s32 flags
f32 planarFlyDist
f32 shadowScale
s16 collisionHeight
s16 yawCamOffset
Vec3f pos
Vec3s homePos
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
PlayerData gPlayerData
Definition 77480.c:40
u8 * gBackgroundTintModePtr
Definition model.c:105
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)