Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
FlyingAI.inc.c
Go to the documentation of this file.
1// This AI is used by:
2// - Paragoomba + variants
3// - Paratroopa + variants
4// - Sky Guy
5// - Bzzap
6
7#ifndef _AI_FLYING_INC_
8#define _AI_FLYING_INC_ 0
9
10#include "common.h"
11#include "npc.h"
12#include "effects.h"
13
14f32 N(FlyingAI_JumpVels)[] = {
15 4.5, 3.5, 2.6, 2.0, 1.5, 20.0,
16};
17
18void N(FlyingAI_WanderInit)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
19 Enemy* enemy = script->owner1.enemy;
20 Npc* npc = get_npc_unsafe(enemy->npcID);
21
22 npc->duration = aiSettings->moveTime / 2 + rand_int(aiSettings->moveTime / 2 + 1);
25 npc->pos.x, npc->pos.z,
27 npc->yaw = atan2(npc->pos.x, npc->pos.z, enemy->territory->wander.centerPos.x, enemy->territory->wander.centerPos.z);
28 } else {
29 npc->yaw = clamp_angle((npc->yaw + rand_int(60)) - 30.0f);
30 }
32 script->functionTemp[1] = 0;
33 if (enemy->territory->wander.moveSpeedOverride < 0) {
34 npc->moveSpeed = aiSettings->moveSpeed;
35 } else {
36 npc->moveSpeed = enemy->territory->wander.moveSpeedOverride / 32767.0;
37 }
38 enemy->varTable[4] = npc->pos.y * 100.0;
39 script->functionTemp[0] = AI_STATE_WANDER;
40}
41
42void N(FlyingAI_Wander)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
43 Enemy* enemy = script->owner1.enemy;
44 Npc* npc = get_npc_unsafe(enemy->npcID);
45 s32 cond = FALSE;
46 f32 vt7 = (f32)enemy->varTable[7] / 100.0;
47 f32 vt3 = (f32)enemy->varTable[3] / 100.0;
48 f32 vt4 = (f32)enemy->varTable[4] / 100.0;
49 f32 vt1 = (f32)enemy->varTable[1] / 100.0;
50 f32 posX, posY, posZ, posW;
51 f32 temp_f24;
52
53 enemy->varTable[4] = npc->pos.y * 100.0;
54
55 temp_f24 = vt3 + vt7;
56
57 if ((enemy->varTable[0] & 0x11) == 1) {
58 if (npc->flags & NPC_FLAG_FLYING) {
59 if (vt1 < temp_f24 - npc->pos.y) {
60 enemy->varTable[0] |= 0x10;
61 }
62 } else {
63 posX = npc->pos.x;
64 posY = npc->pos.y;
65 posZ = npc->pos.z;
66 posW = 1000.0f;
67 npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &posW);
68 if (vt1 < (vt3 - posW)) {
69 enemy->varTable[0] |= 0x10;
70 }
71 }
72 }
73
74 if ((enemy->varTable[0] & 0x11) == 0x11) {
75 f64 test;
76 f32 yTemp;
77
78 if (npc->flags & NPC_FLAG_FLYING) {
79 yTemp = temp_f24;
80 test = vt4 + ((temp_f24 - vt4) * 0.09);
81 npc->pos.y = test;
82 } else {
83 posX = npc->pos.x;
84 posY = vt4;
85 posZ = npc->pos.z;
86 posW = 1000.0f;
87 npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &posW);
88
89 yTemp = posY;
90 yTemp += vt3;
91 test = vt4 + ((yTemp - vt4) * 0.09);
92 npc->pos.y = test;
93 }
94
95 if (fabsf(yTemp - npc->pos.y) < 1.0) {
96 npc->pos.y = yTemp;
97 enemy->varTable[0] &= ~0x10;
98 }
99 } else {
100 if (enemy->varTable[1] > 0) {
101 f32 sinTemp = sin_deg(enemy->varTable[2]);
102 s32 hit;
103
104 if (npc->flags & NPC_FLAG_FLYING) {
105 hit = FALSE;
106 } else {
107 posX = npc->pos.x;
108 posY = npc->pos.y;
109 posZ = npc->pos.z;
110 posW = 1000.0f;
111 hit = npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &posW);
112 }
113
114 if (hit) {
115 npc->pos.y = posY + vt3 + (sinTemp * vt1);
116 } else {
117 npc->pos.y = temp_f24 + (sinTemp * vt1);
118 }
119
120 enemy->varTable[2] = clamp_angle(enemy->varTable[2] + 10);
121 }
122 }
123
124 if (enemy->varTable[9] <= 0) {
125 if (aiSettings->playerSearchInterval >= 0) {
126 if (script->functionTemp[1] <= 0) {
127 script->functionTemp[1] = aiSettings->playerSearchInterval;
128 if (gPlayerStatusPtr->pos.y < (npc->pos.y + npc->collisionHeight) + 10.0 &&
129 basic_ai_check_player_dist(territory, enemy, aiSettings->alertRadius, aiSettings->alertOffsetDist, 0) != 0)
130 {
131 EffectInstance* emoteTemp;
132 fx_emote(EMOTE_EXCLAMATION, npc, 0, npc->collisionHeight, 1.0f, 2.0f, -20.0f, 0xC, &emoteTemp);
133 npc->moveToPos.y = npc->pos.y;
135
137 script->AI_TEMP_STATE = AI_STATE_ALERT_INIT;
138 } else {
139 script->AI_TEMP_STATE = AI_STATE_CHASE_INIT;
140 }
141 return;
142 }
143 }
144 script->functionTemp[1]--;
145 }
146 } else {
147 enemy->varTable[9]--;
148 }
149
151 enemy->territory->wander.centerPos.x,
152 enemy->territory->wander.centerPos.z,
153 npc->pos.x, npc->pos.z,
155 posW = dist2D(enemy->territory->wander.centerPos.x, enemy->territory->wander.centerPos.z, npc->pos.x, npc->pos.z);
156 if (npc->moveSpeed < posW) {
157 npc->yaw = atan2(npc->pos.x, npc->pos.z, enemy->territory->wander.centerPos.x, enemy->territory->wander.centerPos.z);
158 cond = TRUE;
159 }
160 }
161
162 if (enemy->territory->wander.wanderSize.x | enemy->territory->wander.wanderSize.z | cond) {
163 if (npc->turnAroundYawAdjustment != 0) {
164 return;
165 }
166 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
167 }
168
169 enemy->varTable[4] = npc->pos.y * 100.0;
170 if (aiSettings->moveTime > 0) {
171 if ((npc->duration <= 0) || (--npc->duration <= 0)) {
172 script->AI_TEMP_STATE = AI_STATE_LOITER_INIT;
173 script->functionTemp[1] = (rand_int(1000) % 3) + 2;
174 if (aiSettings->unk_AI_2C <= 0 || aiSettings->waitTime <= 0 || script->functionTemp[1] < 3) {
175 script->AI_TEMP_STATE = AI_STATE_WANDER_INIT;
176 }
177 }
178 }
179}
180
181void N(FlyingAI_LoiterInit)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
182 Enemy* enemy = script->owner1.enemy;
183 Npc* npc = get_npc_unsafe(enemy->npcID);
184
185 npc->duration = (aiSettings->waitTime / 2) + rand_int((aiSettings->waitTime / 2) + 1);
186 npc->yaw = clamp_angle(npc->yaw + rand_int(180) - 90.0f);
188 script->functionTemp[0] = 3;
189}
190
191void N(FlyingAI_Loiter)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
192 Enemy* enemy = script->owner1.enemy;
193 Npc* npc = get_npc_unsafe(enemy->npcID);
194 f32 posX, posY, posZ, posW;
195 f32 hoverHeight = (f32)enemy->varTable[3] / 100.0;
196 f32 temp_f26 = hoverHeight + (f32)((f32)enemy->varTable[7] / 100.0);
197 EffectInstance* var;
198
199 if (npc->duration > 0) {
200 npc->duration--;
201 }
202
203 if (enemy->varTable[1] > 0) {
204 f32 undulateAmplitude = (f32)enemy->varTable[1] / 100.0;
205 f32 undulateAmount = sin_deg(enemy->varTable[2]);
206 b32 hasCollision;
207
208 if (npc->flags & NPC_FLAG_FLYING) {
209 hasCollision = FALSE;
210 } else {
211 posX = npc->pos.x;
212 posY = npc->pos.y;
213 posZ = npc->pos.z;
214 posW = 1000.0f;
215 hasCollision = npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &posW);
216 }
217
218 if (hasCollision) {
219 npc->pos.y = posY + hoverHeight + (undulateAmount * undulateAmplitude);
220 } else {
221 npc->pos.y = temp_f26 + (undulateAmount * undulateAmplitude);
222 }
223
224 enemy->varTable[2] = clamp_angle(enemy->varTable[2] + 10);
225 }
226
227 if (enemy->varTable[9] <= 0) {
228 if ((gPlayerStatusPtr->pos.y < npc->pos.y + npc->collisionHeight + 10.0)
229 && basic_ai_check_player_dist(territory, enemy, aiSettings->chaseRadius, aiSettings->chaseOffsetDist, 1)) {
230 fx_emote(EMOTE_EXCLAMATION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, -20.0f, 12, &var);
231 npc->moveToPos.y = npc->pos.y;
234 script->AI_TEMP_STATE = AI_STATE_ALERT_INIT;
235 } else {
236 script->AI_TEMP_STATE = AI_STATE_CHASE_INIT;
237 }
238 return;
239 }
240 } else {
241 enemy->varTable[9]--;
242 }
243
244 if ((npc->turnAroundYawAdjustment == 0) && (npc->duration <= 0)) {
245 script->functionTemp[1]--;
246 if (script->functionTemp[1] > 0) {
248 npc->yaw = clamp_angle(npc->yaw + 180.0f);
249 }
250 npc->duration = (rand_int(1000) % 11) + 5;
251 } else {
252 script->AI_TEMP_STATE = AI_STATE_WANDER_INIT;
253 }
254 }
255}
256
257void N(FlyingAI_JumpInit)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
258 Enemy* enemy = script->owner1.enemy;
259 Npc* npc = get_npc_unsafe(enemy->npcID);
260 PlayerStatus* playerStatus = gPlayerStatusPtr;
261
262 npc->duration = 0;
263 npc->yaw = atan2(npc->pos.x, npc->pos.z, playerStatus->pos.x, playerStatus->pos.z);
265 script->functionTemp[0] = AI_STATE_ALERT;
266}
267
268void N(FlyingAI_Jump)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
269 Enemy* enemy = script->owner1.enemy;
270 Npc* npc = get_npc_unsafe(enemy->npcID);
271
272 npc->pos.y += N(FlyingAI_JumpVels)[npc->duration++];
273 if (npc->duration >= 5) {
274 script->AI_TEMP_STATE = AI_STATE_CHASE_INIT;
275 }
276}
277
278void N(FlyingAI_ChaseInit)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
279 Enemy* enemy = script->owner1.enemy;
280 Npc* npc = get_npc_unsafe(enemy->npcID);
281 f32 jumpVel = (f32)enemy->varTable[5] / 100.0;
282 f32 jumpScale = (f32)enemy->varTable[6] / 100.0;
283
285 npc->jumpVel = jumpVel;
286 npc->jumpScale = jumpScale;
287 npc->moveSpeed = aiSettings->chaseSpeed;
288 npc->yaw = atan2(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z);
289
290 enemy->varTable[2] = 0;
291
292 if (enemy->npcSettings->actionFlags & AI_ACTION_02) {
293 npc->duration = 3;
294 script->AI_TEMP_STATE = AI_STATE_CHASE;
295 } else {
296 npc->duration = 1;
297 script->AI_TEMP_STATE = AI_STATE_LOSE_PLAYER;
298 enemy->unk_10.x = npc->pos.x;
299 enemy->unk_10.y = npc->pos.y;
300 enemy->unk_10.z = npc->pos.z;
301 enemy->hitboxIsActive = TRUE;
302 }
303}
304
305void N(FlyingAI_Chase)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
306 Npc* npc = get_npc_unsafe(script->owner1.enemy->npcID);
307
308 if ((npc->duration <= 0) || (--npc->duration <= 0)) {
309 if (npc->turnAroundYawAdjustment == 0) {
310 npc->duration = 0;
311 script->AI_TEMP_STATE = AI_STATE_LOSE_PLAYER;
312 }
313 }
314}
315
316void N(FlyingAI_LosePlayer)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
317 Enemy* enemy = script->owner1.enemy;
318 Npc* npc = get_npc_unsafe(enemy->npcID);
319 f32 posX, posY, posZ, posW;
320 f32 deltaAngle;
321 f32 temp_f20;
322 f32 temp_f22;
323 f32 temp_f2;
324 s32 hitBelow;
325 f32 angle;
326 f32 a = enemy->varTable[3];
327 f32 b = enemy->varTable[7];
328
329 npc->jumpVel += npc->jumpScale;
330 temp_f20 = a / 100.0;
331 temp_f22 = b / 100.0;
332 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
333
334 if (npc->jumpVel >= 0.0) {
335 npc->pos.y += npc->jumpVel;
337 enemy->hitboxIsActive = FALSE;
338 if (!(npc->flags & NPC_FLAG_FLYING)) {
339 posX = npc->pos.x;
340 posY = npc->pos.y;
341 posZ = npc->pos.z;
342 posW = 1000.0f;
343 hitBelow = npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &posW);
344 } else {
345 hitBelow = FALSE;
346 }
347 if (hitBelow) {
348 temp_f2 = posY + temp_f20;
349 if (temp_f2 <= npc->pos.y) {
350 npc->pos.y = temp_f2;
351 script->functionTemp[0] = 0;
352 }
353 } else if (npc->pos.y >= npc->moveToPos.y) {
354 script->functionTemp[0] = 0;
355 }
356 } else if (npc->jumpVel < 0.0) {
357 npc->duration++;
358 if (npc->duration >= aiSettings->chaseUpdateInterval) {
359 npc->duration = 0;
360 angle = atan2(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z);
361 deltaAngle = get_clamped_angle_diff(npc->yaw, angle);
362 if (aiSettings->chaseTurnRate < fabsf(deltaAngle)) {
363 angle = npc->yaw;
364 if (deltaAngle < 0.0f) {
365 angle += -aiSettings->chaseTurnRate;
366 } else {
367 angle += aiSettings->chaseTurnRate;
368 }
369 }
370 npc->yaw = clamp_angle(angle);
371 }
372
373 if (npc->flags & NPC_FLAG_FLYING) {
374 if (npc->pos.y + npc->jumpVel < temp_f22) {
375 npc->pos.y = temp_f22;
376 npc->jumpVel = 0.0f;
377 } else {
378 npc->pos.y += npc->jumpVel;
379 }
380 return;
381 }
382
383 posX = npc->pos.x;
384 posY = npc->pos.y + npc->collisionHeight;
385 posZ = npc->pos.z;
386 posW = (fabsf(npc->jumpVel) + npc->collisionHeight) + 10.0;
387 if (npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &posW)) {
388 if (posW <= (npc->collisionHeight + fabsf(npc->jumpVel))) {
389 npc->jumpVel = 0.0f;
390 npc->pos.y = posY;
391 } else {
392 npc->pos.y += npc->jumpVel;
393 }
394 return;
395 } else if (fabsf(npc->jumpVel) < ((npc->pos.y - temp_f22) + npc->collisionHeight)) {
396 npc->pos.y = npc->pos.y + npc->jumpVel;
397 return;
398 }
399 npc->jumpVel = 0.0f;
400 }
401}
402
403void N(FlyingAI_Init)(Npc* npc, Enemy* enemy, Evt* script, MobileAISettings* aiSettings) {
404 f32 posX, posY, posZ, depth;
405
406 script->functionTemp[0] = 0;
407 npc->duration = 0;
408
409 npc->flags &= ~NPC_FLAG_GRAVITY;
410 npc->flags |= NPC_FLAG_JUMPING;
411 if (enemy->territory->wander.isFlying) {
412 npc->flags |= NPC_FLAG_FLYING;
413 } else {
414 npc->flags &= ~NPC_FLAG_FLYING;
415 }
416
417 posX = npc->pos.x;
418 posY = npc->pos.y;
419 posZ = npc->pos.z;
420 depth = 1000.0f;
421 npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &depth);
422 enemy->varTable[2] = 0;
423 enemy->varTable[9] = 0;
424 enemy->varTable[3] = (depth * 100.0) + 0.5;
425 enemy->varTable[7] = (posY * 100.0) + 0.5;
426 script->functionTemp[1] = aiSettings->playerSearchInterval;
427 enemy->aiFlags |= AI_FLAG_SKIP_IDLE_ANIM_AFTER_FLEE;
428}
429
430API_CALLABLE(N(FlyingAI_Main)) {
431 Enemy* enemy = script->owner1.enemy;
432 Bytecode* args = script->ptrReadPos;
433 Npc* npc = get_npc_unsafe(enemy->npcID);
434 EnemyDetectVolume territory;
435 EnemyDetectVolume* territoryPtr = &territory;
436 MobileAISettings* aiSettings = (MobileAISettings*) evt_get_variable(script, *args);
437
438 territory.skipPlayerDetectChance = 0;
439 territory.shape = enemy->territory->wander.detectShape;
440 territory.pointX = enemy->territory->wander.detectPos.x;
441 territory.pointZ = enemy->territory->wander.detectPos.z;
442 territory.sizeX = enemy->territory->wander.detectSize.x;
443 territory.sizeZ = enemy->territory->wander.detectSize.z;
444 territory.halfHeight = 120.0f;
445 territory.detectFlags = 0;
446
447 if (isInitialCall) {
448 N(FlyingAI_Init)(npc, enemy, script, aiSettings);
449 }
450
451 npc->verticalRenderOffset = -2;
452
453 if (enemy->aiFlags & AI_FLAG_SUSPEND) {
454 if (enemy->aiSuspendTime != 0) {
455 return ApiStatus_BLOCK;
456 }
457 enemy->aiFlags &= ~AI_FLAG_SUSPEND;
458 }
459
460 switch (script->AI_TEMP_STATE) {
462 N(FlyingAI_WanderInit)(script, aiSettings, territoryPtr);
463 case AI_STATE_WANDER:
464 N(FlyingAI_Wander)(script, aiSettings, territoryPtr);
465 break;
467 N(FlyingAI_LoiterInit)(script, aiSettings, territoryPtr);
468 case AI_STATE_LOITER:
469 N(FlyingAI_Loiter)(script, aiSettings, territoryPtr);
470 break;
472 N(FlyingAI_JumpInit)(script, aiSettings, territoryPtr);
473 case AI_STATE_ALERT:
474 N(FlyingAI_Jump)(script, aiSettings, territoryPtr);
475 break;
477 N(FlyingAI_ChaseInit)(script, aiSettings, territoryPtr);
478 break;
479 case AI_STATE_CHASE:
480 N(FlyingAI_Chase)(script, aiSettings, territoryPtr);
481 break;
483 N(FlyingAI_LosePlayer)(script, aiSettings, territoryPtr);
484 break;
485 }
486
487 return ApiStatus_BLOCK;
488}
489
490#endif
void N FlyingAI_ChaseInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingAI_LoiterInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingAI_Loiter(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingAI_Jump(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingAI_Wander(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingAI_JumpInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingAI_Init(Npc *npc, Enemy *enemy, Evt *script, MobileAISettings *aiSettings)
void N FlyingAI_WanderInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingAI_Chase(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingAI_LosePlayer(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
s32 b32
Vec3s pos
Definition demo_api.c:17
#define npc_raycast_down_sides
#define sin_deg
#define rand_int
#define clamp_angle
#define atan2
@ EMOTE_EXCLAMATION
Definition enums.h:495
@ ENEMY_ANIM_INDEX_MELEE_PRE
Definition enums.h:3434
@ ENEMY_ANIM_INDEX_IDLE
Definition enums.h:3426
@ ENEMY_ANIM_INDEX_WALK
Definition enums.h:3427
@ ENEMY_ANIM_INDEX_MELEE_HIT
Definition enums.h:3435
@ AI_FLAG_SUSPEND
Definition enums.h:4571
@ AI_FLAG_SKIP_IDLE_ANIM_AFTER_FLEE
Definition enums.h:4573
@ AI_STATE_WANDER
Definition enums.h:4582
@ AI_STATE_LOITER
Definition enums.h:4588
@ AI_STATE_WANDER_INIT
Definition enums.h:4581
@ AI_STATE_LOITER_INIT
Definition enums.h:4587
@ AI_STATE_ALERT
Definition enums.h:4591
@ AI_STATE_CHASE_INIT
Definition enums.h:4592
@ AI_STATE_CHASE
Definition enums.h:4593
@ AI_STATE_LOSE_PLAYER
Definition enums.h:4594
@ AI_STATE_ALERT_INIT
Definition enums.h:4590
@ SOUND_AI_ALERT_A
Definition enums.h:1078
@ AI_ACTION_LOOK_AROUND_DURING_LOITER
Definition enums.h:4616
@ AI_ACTION_02
Definition enums.h:4613
@ AI_ACTION_JUMP_WHEN_SEE_PLAYER
Definition enums.h:4612
@ SOUND_PARAM_MORE_QUIET
Definition enums.h:1746
@ NPC_FLAG_FLYING
Definition enums.h:3001
@ NPC_FLAG_JUMPING
Definition enums.h:3009
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 fabsf(f32 f)
b32 is_point_outside_territory(s32 shape, f32 centerX, f32 centerZ, f32 pointX, f32 pointZ, f32 sizeX, f32 sizeZ)
Definition 23680.c:412
void ai_enemy_play_sound(Npc *npc, s32 arg1, s32 arg2)
Definition 23680.c:543
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
f32 get_clamped_angle_diff(f32, f32)
Definition 43F0.c:606
enum TerritoryShape shape
Definition npc.h:201
VecXZi detectSize
Definition npc.h:216
enum TerritoryShape detectShape
Definition npc.h:217
s32 basic_ai_check_player_dist(EnemyDetectVolume *arg0, Enemy *arg1, f32 arg2, f32 arg3, b8 arg4)
Definition 23680.c:429
s16 npcID
Definition npc.h:300
s32 * animList
Definition npc.h:341
VecXZi wanderSize
Definition npc.h:212
s8 aiSuspendTime
Definition npc.h:333
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
Vec3s unk_10
Definition npc.h:302
s8 hitboxIsActive
Definition npc.h:299
s16 actionFlags
Definition npc.h:156
s16 detectFlags
Definition npc.h:207
s32 moveSpeedOverride
Definition npc.h:213
NpcSettings * npcSettings
Definition npc.h:304
enum TerritoryShape wanderShape
Definition npc.h:214
u32 aiFlags
Definition npc.h:332
void npc_move_heading(Npc *npc, f32 speed, f32 yaw)
Definition npc.c:986
s32 skipPlayerDetectChance
Definition npc.h:200
EnemyTerritoryWander wander
Definition npc.h:232
EnemyTerritory * territory
Definition npc.h:342
Definition npc.h:294
f32 jumpScale
f32 jumpVel
s32 flags
AnimID curAnim
Vec3f moveToPos
s32 collisionChannel
s16 collisionHeight
s16 turnAroundYawAdjustment
s8 verticalRenderOffset
Vec3f pos
f32 moveSpeed
s16 duration
PlayerStatus * gPlayerStatusPtr