Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
SwooperAI.inc.c
Go to the documentation of this file.
1#include "common.h"
2#include "npc.h"
3
4API_CALLABLE(N(SwooperAI_Main)) {
5 EnemyDetectVolume detectVolume;
6 PlayerStatus* playerStatus = &gPlayerStatus;
7 EnemyDetectVolume* detectVolumePtr = &detectVolume;
8 Enemy* enemy = script->owner1.enemy;
9 Npc* npc = get_npc_unsafe(enemy->npcID);
10 Bytecode* args = script->ptrReadPos;
11 MobileAISettings* aiSettings = (MobileAISettings*)evt_get_variable(script, *args++);
12 f32 x, y, z, hitDepth;
13 f32 y2;
14
15 detectVolumePtr->skipPlayerDetectChance = 0;
16 detectVolumePtr->shape = enemy->territory->wander.detectShape;
17 detectVolumePtr->pointX = enemy->territory->wander.detectPos.x;
18 detectVolumePtr->pointZ = enemy->territory->wander.detectPos.z;
19 detectVolumePtr->sizeX = enemy->territory->wander.detectSize.x;
20 detectVolumePtr->sizeZ = enemy->territory->wander.detectSize.z;
21 detectVolumePtr->halfHeight = 500.0f;
22 detectVolumePtr->detectFlags = 0;
23
24 if (isInitialCall) {
25 script->functionTemp[0] = 0;
26 npc->duration = 0;
28 hitDepth = 1000.0f;
29 x = npc->pos.x;
30 y = npc->pos.y;
31 z = npc->pos.z;
32 npc_raycast_down_sides(npc->collisionChannel, &x, &y, &z, &hitDepth);
33 enemy->varTable[1] = y;
34 }
35
36 if (enemy->aiFlags & AI_FLAG_SUSPEND) {
37 if (enemy->aiSuspendTime != 0) {
38 return ApiStatus_BLOCK;
39 }
40 enemy->aiFlags &= ~AI_FLAG_SUSPEND;
41 }
42
43 switch (script->functionTemp[0]) {
44 case 0:
45 npc->curAnim = enemy->animList[0];
48 script->functionTemp[1] = 0;
49 script->functionTemp[0] = 1;
50 case 1:
51 if (aiSettings->playerSearchInterval >= 0) {
52 if (script->functionTemp[1] <= 0) {
53 script->functionTemp[1] = aiSettings->playerSearchInterval;
54 if (basic_ai_check_player_dist(detectVolumePtr, enemy, aiSettings->alertRadius, aiSettings->alertOffsetDist, 0) != 0) {
56 script->functionTemp[0] = 10;
57 }
58 }
59 script->functionTemp[1]--;
60 }
61 if (script->functionTemp[0] != 10) {
62 break;
63 }
64 case 10:
65 npc->curAnim = enemy->animList[3];
66 npc->planarFlyDist = atan2(npc->pos.x, npc->pos.z, playerStatus->pos.x, playerStatus->pos.z);
67 npc->jumpScale = 1.3f;
68 npc->jumpVel = 0.0f;
69 npc->moveSpeed = aiSettings->moveSpeed;
70 x = npc->pos.x;
71 y = npc->pos.y;
72 z = npc->pos.z;
73 hitDepth = 1000.0f;
74 if (npc_raycast_down_sides(npc->collisionChannel, &x, &y, &z, &hitDepth) != 0) {
75 y = enemy->varTable[1];
76 npc->moveToPos.y = y + ((npc->pos.y - y) * 0.7);
77 } else {
78 npc->moveToPos.y = playerStatus->pos.y + ((npc->pos.y - playerStatus->pos.y) * 0.7);
79 }
80 npc->moveToPos.z = npc->pos.y;
81 script->functionTemp[0] = 11;
82 case 11:
83 if (npc->moveSpeed > 0.0) {
84 x = npc->pos.x;
85 y = npc->pos.y;
86 z = npc->pos.z;
88 npc->moveSpeed = 0.0f;
89 }
90 npc->yaw = atan2(npc->pos.x, npc->pos.z, playerStatus->pos.x, playerStatus->pos.z);
91 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
92 }
93
94 npc->jumpVel -= npc->jumpScale;
95 npc->pos.y += npc->jumpVel;
96 if (npc->pos.y < npc->moveToPos.y) {
97 npc->pos.y = npc->moveToPos.y;
98 script->functionTemp[0] = 12;
99 } else {
100 break;
101 }
102 case 12:
103 npc->planarFlyDist = dist2D(npc->pos.x, npc->pos.z, playerStatus->pos.x, playerStatus->pos.z);
104 if (npc->planarFlyDist < 60.0f) {
105 npc->planarFlyDist = 60.0f;
106 }
107
108 y = enemy->varTable[1];
109 y2 = (y + 10.0) - npc->pos.y;
110
111 npc->moveSpeed = aiSettings->chaseSpeed;
112 npc->duration = npc->planarFlyDist / npc->moveSpeed;
113 if (npc->duration == 0) {
114 npc->duration = 1;
115 }
116 npc->jumpScale = -fabsf(-(2.0f * ((-npc->jumpVel * npc->duration) + y2)) / SQ(npc->duration));
117 npc->verticalRenderOffset = 0;
118 npc->flags &= ~NPC_FLAG_UPSIDE_DOWN;
119 enemy->varTable[0] = 5;
120 npc->duration = 0;
121 script->functionTemp[0] = 13;
122 case 13:
123 npc->jumpVel -= npc->jumpScale;
124 if (npc->jumpVel < 0.0f) {
125 x = npc->pos.x;
126 y = npc->pos.y;
127 z = npc->pos.z;
128 hitDepth = -npc->jumpVel;
129 if (npc_raycast_down_sides(npc->collisionChannel, &x, &y, &z, &hitDepth) != 0) {
130 npc->jumpVel = 0.0f;
131 }
132 }
133
134 npc->pos.y += npc->jumpVel;
135 if (npc->moveSpeed > 0.0) {
136 x = npc->pos.x;
137 y = npc->pos.y;
138 z = npc->pos.z;
139 if (npc_test_move_simple_with_slipping(npc->collisionChannel, &x, &y, &z, npc->moveSpeed, npc->yaw,
140 npc->collisionHeight, npc->collisionDiameter) != 0)
141 {
142 npc->moveSpeed = 0.0f;
143 } else if (npc->jumpVel < -2.5) {
144 npc->duration++;
145 if (npc->duration >= aiSettings->chaseUpdateInterval) {
146 f32 yaw = atan2(npc->pos.x, npc->pos.z, playerStatus->pos.x, playerStatus->pos.z);
147 f32 angleDiff = get_clamped_angle_diff(npc->yaw, yaw);
148
149 if (aiSettings->chaseTurnRate < fabsf(angleDiff)) {
150 yaw = npc->yaw;
151 if (angleDiff < 0.0f) {
152 yaw += -aiSettings->chaseTurnRate;
153 } else {
154 yaw += aiSettings->chaseTurnRate;
155 }
156 }
157 npc->yaw = clamp_angle(yaw);
158 npc->duration = 0;
159 }
160 }
161 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
162 }
163 enemy->varTable[0]--;
164 if (enemy->varTable[0] <= 0) {
165 enemy->varTable[0] = 5;
166 }
167
168 if (npc->pos.y > npc->moveToPos.z) {
169 npc->pos.y = npc->moveToPos.z;
170 script->functionTemp[0] = 14;
171 } else {
172 break;
173 }
174 case 14:
175 npc->curAnim = enemy->animList[8];
178 npc->duration = 15;
179 script->functionTemp[0] = 15;
180 case 15:
181 npc->duration--;
182 if (npc->duration <= 0) {
183 script->functionTemp[0] = 0;
184 }
185 }
186 return ApiStatus_BLOCK;
187}
#define npc_raycast_down_sides
#define clamp_angle
#define atan2
@ AI_FLAG_SUSPEND
Definition enums.h:4571
@ AI_FLAG_SKIP_IDLE_ANIM_AFTER_FLEE
Definition enums.h:4573
@ SOUND_AI_ALERT_A
Definition enums.h:1078
@ SOUND_PARAM_MORE_QUIET
Definition enums.h:1746
@ NPC_FLAG_UPSIDE_DOWN
Definition enums.h:3005
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)
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
b32 npc_test_move_simple_with_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
enum TerritoryShape shape
Definition npc.h:201
s32 chaseTurnRate
Definition npc.h:100
s32 chaseUpdateInterval
Definition npc.h:101
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
f32 moveSpeed
Definition npc.h:93
s8 aiSuspendTime
Definition npc.h:333
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
s16 detectFlags
Definition npc.h:207
f32 alertOffsetDist
Definition npc.h:97
s32 playerSearchInterval
Definition npc.h:98
f32 alertRadius
Definition npc.h:96
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
#define SQ(x)
Definition macros.h:166
s16 collisionDiameter
f32 jumpScale
f32 jumpVel
s32 flags
AnimID curAnim
Vec3f moveToPos
f32 planarFlyDist
s32 collisionChannel
s16 collisionHeight
s8 verticalRenderOffset
Vec3f pos
f32 moveSpeed
s16 duration
PlayerStatus gPlayerStatus
Definition 77480.c:39