Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
Boo_Patrol.inc.c
Go to the documentation of this file.
1#include "Boo.h"
2
4
5void N(BooPatrolAI_Move)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
6 Enemy* enemy = script->owner1.enemy;
7 Npc* npc = get_npc_unsafe(enemy->npcID);
8 f32 posX, posY, posZ, posW;
9 f32 temp_f20;
10 f32 temp_f22;
11
12 posX = npc->pos.x;
13 posZ = npc->pos.z;
14 temp_f22 = script->functionTemp[2][enemy->territory->patrol.points].x;
15 temp_f20 = script->functionTemp[2][enemy->territory->patrol.points].z;
16
17 npc->yaw = atan2(posX, posZ, temp_f22, temp_f20);
18 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
19
20 posX = npc->pos.x;
21 posY = npc->pos.y + script->functionTemp[2][enemy->territory->patrol.points].y;
22 posZ = npc->pos.z;
23 posW = 1000.0f;
24 npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &posW);
25 posY += script->functionTemp[2][enemy->territory->patrol.points].y;
26 posW = posY - npc->pos.y;
27 if (posW > 2.0) {
28 npc->pos.y += 2.0;
29 } else if (posW < -2.0) {
30 npc->pos.y -= 2.0;
31 } else {
32 npc->pos.y = posY;
33 }
34
35 posW = dist2D(npc->pos.x, npc->pos.z, temp_f22, temp_f20);
36 if (!(posW > npc->moveSpeed)) {
37 script->functionTemp[0] = 2;
38 }
39}
40
41void N(BooPatrolAI_Loiter)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
42 Enemy* enemy = script->owner1.enemy;
43 Npc* npc = get_npc_unsafe(enemy->npcID);
44
45 npc->duration--;
46 if (npc->duration < 0) {
47 script->functionTemp[1]--;
48 if (script->functionTemp[1] >= 0) {
49 npc->yaw = clamp_angle(npc->yaw + 180.0f);
50 npc->duration = aiSettings->waitTime / 2 + rand_int(aiSettings->waitTime / 2 + 1);
51 } else {
52 script->functionTemp[0] = 4;
54 }
55 }
56}
57
58API_CALLABLE(N(BooPatrolAI_Main)) {
59 Enemy* enemy = script->owner1.enemy;
60 Bytecode* args = script->ptrReadPos;
61 Npc* npc = get_npc_unsafe(enemy->npcID);
62 EnemyDetectVolume territory;
63 EnemyDetectVolume* territoryPtr = &territory;
64 MobileAISettings* aiSettings = (MobileAISettings*)evt_get_variable(script, *args++);
65
66 territory.skipPlayerDetectChance = 0;
67 territory.shape = enemy->territory->patrol.detectShape;
68 territory.pointX = enemy->territory->patrol.detectPos.x;
69 territory.pointZ = enemy->territory->patrol.detectPos.z;
70 territory.sizeX = enemy->territory->patrol.detectSize.x;
71 territory.sizeZ = enemy->territory->patrol.detectSize.z;
72 territory.halfHeight = 100.0f;
73 territory.detectFlags = 0;
74
75 if (isInitialCall) {
76 script->functionTemp[0] = 0;
77 npc->duration = 0;
78 npc->flags &= ~NPC_FLAG_JUMPING;
79 }
80
81 switch (script->functionTemp[0]) {
82 case 0:
83 N(PatrolAI_MoveInit)(script, aiSettings, territoryPtr);
84 case 1:
85 N(BooPatrolAI_Move)(script, aiSettings, territoryPtr);
86 break;
87 case 2:
88 N(PatrolAI_LoiterInit)(script, aiSettings, territoryPtr);
89 case 3:
90 N(BooPatrolAI_Loiter)(script, aiSettings, territoryPtr);
91 break;
92 case 4:
93 N(PatrolAI_PostLoiter)(script, aiSettings, territoryPtr);
94 }
95
96 enemy->varTable[0] = npc->pos.y;
97 return ApiStatus_BLOCK;
98}
99
100MobileAISettings N(AISettings_Boo_Patrol) = {
101 .moveSpeed = 1.0f,
102 .moveTime = 25,
103 .waitTime = 30,
104 .alertRadius = 50.0f,
105 .alertOffsetDist = 50.0f,
106 .playerSearchInterval = 10,
107 .chaseRadius = 100.0f,
108 .chaseOffsetDist = 80.0f,
109 .unk_AI_2C = 1,
110};
111
112EvtScript N(EVS_NpcAI_Boo_Patrol) = {
113 Call(N(BooPatrolAI_Main), Ref(N(AISettings_Boo_Patrol)))
114 Return
115 End
116};
117
118NpcSettings N(NpcSettings_Boo_Patrol) = {
119 .height = 24,
120 .radius = 24,
121 .level = ACTOR_LEVEL_NONE,
122 .ai = &N(EVS_NpcAI_Boo_Patrol),
123};
void N BooPatrolAI_Loiter(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N BooPatrolAI_Move(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N PatrolAI_MoveInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N PatrolAI_PostLoiter(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
Bytecode EvtScript[]
#define npc_raycast_down_sides
#define rand_int
#define clamp_angle
#define atan2
@ ENEMY_ANIM_INDEX_IDLE
Definition enums.h:3426
s32 Bytecode
Definition evt.h:7
#define ApiStatus_BLOCK
Definition evt.h:116
s32 evt_get_variable(Evt *script, Bytecode var)
Definition evt.c:1690
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
void PatrolAI_LoiterInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
enum TerritoryShape shape
Definition npc.h:201
s16 npcID
Definition npc.h:300
s32 * animList
Definition npc.h:341
Vec3i points[10]
Definition npc.h:223
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
VecXZi detectSize
Definition npc.h:226
s16 detectFlags
Definition npc.h:207
EnemyTerritoryPatrol patrol
Definition npc.h:233
void npc_move_heading(Npc *npc, f32 speed, f32 yaw)
Definition npc.c:986
s32 skipPlayerDetectChance
Definition npc.h:200
enum TerritoryShape detectShape
Definition npc.h:227
EnemyTerritory * territory
Definition npc.h:342
Definition npc.h:294
#define Ref(sym)
Address/pointer constant.
Definition macros.h:60
#define End
Signals the end of EVT script data. A script missing this will likely crash on load.
Definition macros.h:213
#define Call(FUNC, ARGS...)
Calls a given C EVT API function with any number of arguments.
Definition macros.h:576
#define Return
Kills the current EVT thread.
Definition macros.h:217
s32 flags
AnimID curAnim
s32 collisionChannel
Vec3f pos
f32 moveSpeed
s16 duration