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

Go to the source code of this file.

Functions

void N AvoidPlayerAI_ChaseInit (Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
 
void N AvoidPlayerAI_Chase (Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
 
void N AvoidPlayerAI_LosePlayer (Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
 

Function Documentation

◆ AvoidPlayerAI_ChaseInit()

void N AvoidPlayerAI_ChaseInit ( Evt * script,
MobileAISettings * npcAISettings,
EnemyDetectVolume * territory )

Definition at line 5 of file AvoidPlayerAI.inc.c.

5 {
6 Enemy* enemy = script->owner1.enemy;
7 Npc* npc = get_npc_unsafe(enemy->npcID);
8
9 f32 deltaYaw;
10 f32 yawFwd;
11 f32 distFwd;
12 f32 distCW;
13 f32 distCCW;
14 f32 distToPlayer;
15 s32 detectedPlayer;
16
17 f32 posXFwd;
18 f32 posYFwd;
19 f32 posZFwd;
20 f32 posXCW;
21 f32 posYCW;
22 f32 posZCW;
23 f32 posXCCW;
24 f32 posYCCW;
25 f32 posZCCW;
26
27 npc->duration = npcAISettings->chaseUpdateInterval / 2 + rand_int(npcAISettings->chaseUpdateInterval / 2 + 1);
29 npc->moveSpeed = npcAISettings->chaseSpeed;
30 detectedPlayer = FALSE;
31
32 yawFwd = clamp_angle(atan2(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x,
33 gPlayerStatusPtr->pos.z) + 180.0f);
34 deltaYaw = get_clamped_angle_diff(npc->yaw, yawFwd);
35 if (npcAISettings->chaseTurnRate < fabsf(deltaYaw)) {
36 yawFwd = npc->yaw;
37 if (deltaYaw < 0.0f) {
38 yawFwd += -npcAISettings->chaseTurnRate;
39 } else {
40 yawFwd += npcAISettings->chaseTurnRate;
41 }
42 }
43
44 npc->yaw = clamp_angle(yawFwd);
45
46 posXFwd = npc->pos.x;
47 posYFwd = npc->pos.y;
48 posZFwd = npc->pos.z;
49
50 yawFwd = clamp_angle(atan2(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z) + 180.0f);
51 distFwd = 0.0f;
52 distCW = 0.0f;
53 distCCW = 0.0f;
54
56 &posXFwd, &posYFwd, &posZFwd, npc->moveSpeed * 4.5,
57 yawFwd, npc->collisionHeight, npc->collisionDiameter)) {
58 distFwd = dist2D(npc->pos.x, npc->pos.z, posXFwd, posZFwd);
59
60 // check 'whisker' 35 degrees CW
61 posXCW = npc->pos.x;
62 posYCW = npc->pos.y;
63 posZCW = npc->pos.z;
65 &posXCW, &posYCW, &posZCW, npc->moveSpeed * 4.5,
66 clamp_angle(yawFwd + 35.0f), npc->collisionHeight, npc->collisionDiameter)) {
67 distCW = dist2D(npc->pos.x, npc->pos.z, posXCW, posZCW);
68 }
69
70 // check 'whisker' 35 degrees CCW
71 posXCCW = npc->pos.x;
72 posYCCW = npc->pos.y;
73 posZCCW = npc->pos.z;
75 &posXCCW, &posYCCW, &posZCCW, npc->moveSpeed * 4.5,
76 clamp_angle(yawFwd - 35.0f), npc->collisionHeight, npc->collisionDiameter)) {
77 distCCW = dist2D(npc->pos.x, npc->pos.z, posXCCW, posZCCW);
78 }
79
80 // unused
81 distToPlayer = dist2D(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z);
82
83 if ((distFwd < npc->moveSpeed * 1.5) && (distCW < npc->moveSpeed * 1.5) && (distCCW < npc->moveSpeed * 1.5) &&
84 (basic_ai_check_player_dist(territory, enemy, npcAISettings->alertRadius, npcAISettings->alertOffsetDist, 0))) {
85 detectedPlayer = TRUE;
86 }
87
88 if (!detectedPlayer) {
89 if ((distCW < distFwd) && (distCCW < distCW)) {
90 yawFwd = atan2(npc->pos.x, npc->pos.z, posXFwd, posZFwd);
91 } else if ((distCW < distFwd) && (distCW < distCCW)) {
92 yawFwd = atan2(npc->pos.x, npc->pos.z, posXFwd, posZFwd);
93 } else if ((distFwd < distCW) && (distCCW < distFwd)) {
94 yawFwd = atan2(npc->pos.x, npc->pos.z, posXCW, posZCW);
95 } else if ((distCCW < distCW) && (distFwd < distCCW)) {
96 yawFwd = atan2(npc->pos.x, npc->pos.z, posXCW, posZCW);
97 } else if ((distFwd < distCCW) && (distCW < distFwd)) {
98 yawFwd = atan2(npc->pos.x, npc->pos.z, posXCCW, posZCCW);
99 } else if ((distCW < distCCW) && (distFwd < distCW)) {
100 yawFwd = atan2(npc->pos.x, npc->pos.z, posXCCW, posZCCW);
101 }
102
103 deltaYaw = get_clamped_angle_diff(npc->yaw, yawFwd);
104 if (npcAISettings->chaseTurnRate < fabsf(deltaYaw)) {
105 yawFwd = npc->yaw;
106 if (deltaYaw < 0.0f) {
107 yawFwd += -npcAISettings->chaseTurnRate;
108 } else {
109 yawFwd += npcAISettings->chaseTurnRate;
110 }
111 }
112 npc->yaw = clamp_angle(yawFwd);
113 }
114 }
115 if (detectedPlayer) {
116 npc->duration = 10;
118 }
119 script->AI_TEMP_STATE = AI_STATE_CHASE;
120}
union Evt::@8 owner1
Initially -1.
#define rand_int
#define clamp_angle
#define atan2
@ ENEMY_ANIM_INDEX_MELEE_PRE
Definition enums.h:3434
@ ENEMY_ANIM_INDEX_CHASE
Definition enums.h:3429
@ AI_STATE_CHASE
Definition enums.h:4593
f32 fabsf(f32 f)
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
b32 npc_test_move_simple_without_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
f32 get_clamped_angle_diff(f32, f32)
Definition 43F0.c:606
f32 chaseSpeed
Definition npc.h:99
s32 chaseTurnRate
Definition npc.h:100
s32 chaseUpdateInterval
Definition npc.h:101
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
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
f32 alertOffsetDist
Definition npc.h:97
f32 alertRadius
Definition npc.h:96
Definition npc.h:294
s16 collisionDiameter
AnimID curAnim
s32 collisionChannel
s16 collisionHeight
Vec3f pos
f32 moveSpeed
s16 duration
PlayerStatus * gPlayerStatusPtr

◆ AvoidPlayerAI_Chase()

void N AvoidPlayerAI_Chase ( Evt * script,
MobileAISettings * npcAISettings,
EnemyDetectVolume * territory )

Definition at line 122 of file AvoidPlayerAI.inc.c.

122 {
123 Enemy* enemy = script->owner1.enemy;
124 Npc* npc = get_npc_unsafe(enemy->npcID);
125 EffectInstance* emoteTemp;
126
127 if (!basic_ai_check_player_dist(territory, enemy, npcAISettings->chaseRadius, npcAISettings->chaseOffsetDist, 1)) {
128 fx_emote(EMOTE_QUESTION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, -20.0f, 15, &emoteTemp);
130 npc->duration = 25;
131 script->AI_TEMP_STATE = AI_STATE_LOSE_PLAYER;
132 } else {
133 if (npc->curAnim != enemy->animList[ENEMY_ANIM_INDEX_MELEE_PRE]) {
134 if (npc->moveSpeed < 4.0) {
136 } else {
138 }
139 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
140 }
141 if (npc->duration > 0) {
142 npc->duration--;
143 return;
144 }
145 script->AI_TEMP_STATE = AI_STATE_CHASE_INIT;
146 }
147}
@ EMOTE_QUESTION
Definition enums.h:497
@ ENEMY_ANIM_INDEX_IDLE
Definition enums.h:3426
@ AI_STATE_CHASE_INIT
Definition enums.h:4592
@ AI_STATE_LOSE_PLAYER
Definition enums.h:4594
@ SURFACE_INTERACT_RUN
Definition enums.h:4685
@ SURFACE_INTERACT_WALK
Definition enums.h:4684
void npc_surface_spawn_fx(Npc *npc, SurfaceInteractMode mode)
Definition surfaces.c:394
f32 chaseRadius
Definition npc.h:102
void npc_move_heading(Npc *npc, f32 speed, f32 yaw)
Definition npc.c:986
f32 chaseOffsetDist
Definition npc.h:103

◆ AvoidPlayerAI_LosePlayer()

void N AvoidPlayerAI_LosePlayer ( Evt * script,
MobileAISettings * npcAISettings,
EnemyDetectVolume * territory )

Definition at line 149 of file AvoidPlayerAI.inc.c.

149 {
150 Enemy* enemy = script->owner1.enemy;
151 Npc* npc = get_npc_unsafe(enemy->npcID);
152
153 npc->duration--;
154 if (npc->duration == 0) {
155 script->AI_TEMP_STATE = AI_STATE_WANDER_INIT;
156 }
157}
@ AI_STATE_WANDER_INIT
Definition enums.h:4581