Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
FlyingNoAttackAI.inc.c
Go to the documentation of this file.
1#include "common.h"
2#include "npc.h"
3#include "effects.h"
4
5// This AI is used by:
6// - Lava Bubble
7// - Ruff Puff
8// - Ember
9
10void N(FlyingNoAttackAI_12)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
11 Enemy* enemy = script->owner1.enemy;
12 Npc* npc = get_npc_unsafe(enemy->npcID);
13 f32 tempAngle;
14 f32 angleDiff;
15
16 npc->duration = (aiSettings->chaseUpdateInterval / 2) + rand_int(aiSettings->chaseUpdateInterval / 2 + 1);
18 npc->moveSpeed = aiSettings->chaseSpeed;
19
20 tempAngle = atan2(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z);
21 angleDiff = get_clamped_angle_diff(npc->yaw, tempAngle);
22
23 if (aiSettings->chaseTurnRate < fabsf(angleDiff)) {
24 tempAngle = npc->yaw;
25
26 if (angleDiff < 0.0f) {
27 tempAngle += -aiSettings->chaseTurnRate;
28 } else {
29 tempAngle += aiSettings->chaseTurnRate;
30 }
31 }
32
33 npc->yaw = clamp_angle(tempAngle);
34 script->functionTemp[0] = 13;
35}
36
37void N(FlyingNoAttackAI_13)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
38 Enemy* enemy = script->owner1.enemy;
39 Npc* npc = get_npc_unsafe(enemy->npcID);
40 f32 x, y, z, w;
41 EffectInstance* var;
42 s32 flag;
43 f32 temp_f6;
44
45 if (basic_ai_check_player_dist(territory, enemy, aiSettings->chaseRadius, aiSettings->chaseOffsetDist, 1) == 0) {
46 fx_emote(EMOTE_QUESTION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, -20.0f, 0xF, &var);
48 npc->duration = 30;
49 script->functionTemp[0] = 20;
50 enemy->varTable[9] = 30;
51 return;
52 }
53
54 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
55 flag = 0;
56 if (!(npc->flags & NPC_FLAG_FLYING)) {
57 x = npc->pos.x;
58 y = npc->pos.y + npc->collisionHeight;
59 z = npc->pos.z;
60 w = npc->collisionHeight + 3.0;
61 if ((npc_raycast_down_sides(npc->collisionChannel, &x, &y, &z, &w) != 0) && (w < npc->collisionHeight)) {
62 flag = 1;
63 }
64 }
65
66 if (flag) {
67 npc->pos.y = y + 1.0;
68 } else {
69 temp_f6 = npc->pos.y - (gPlayerStatusPtr->pos.y + 6.0);
70 if ((temp_f6 < 0.0) || (temp_f6 > 4.0)) {
71 temp_f6 = -temp_f6;
72 npc->pos.y += temp_f6 * 0.06;
73 }
74 }
75 if (npc->duration > 0) {
76 npc->duration--;
77 return;
78 }
79 script->functionTemp[0] = 12;
80}
81
82void N(FlyingNoAttackAI_20)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
83 Enemy* enemy = script->owner1.enemy;
84 Npc* npc = get_npc_unsafe(enemy->npcID);
85
86 npc->duration--;
87 if (npc->duration <= 0) {
88 enemy->varTable[2] = 0;
89 npc->duration = 0;
90 script->functionTemp[0] = 0;
91 }
92}
93
94API_CALLABLE(N(FlyingNoAttackAI_Main)) {
95 Enemy* enemy = script->owner1.enemy;
96 Bytecode* args = script->ptrReadPos;
97 Npc* npc = get_npc_unsafe(enemy->npcID);
98 EnemyDetectVolume territory;
99 EnemyDetectVolume* territoryPtr = &territory;
100 MobileAISettings* aiSettings = (MobileAISettings*) evt_get_variable(script, *args);
101
102 territory.skipPlayerDetectChance = 0;
103 territory.shape = enemy->territory->wander.detectShape;
104 territory.pointX = enemy->territory->wander.detectPos.x;
105 territory.pointZ = enemy->territory->wander.detectPos.z;
106 territory.sizeX = enemy->territory->wander.detectSize.x;
107 territory.sizeZ = enemy->territory->wander.detectSize.z;
108 territory.halfHeight = 120.0f;
109 territory.detectFlags = 0;
110
111 if (isInitialCall) {
112 N(FlyingAI_Init)(npc, enemy, script, aiSettings);
113 script->functionTemp[0] = 0;
114 }
115 npc->verticalRenderOffset = -2;
116
117 if (enemy->aiFlags & AI_FLAG_SUSPEND) {
118 if (enemy->aiSuspendTime != 0) {
119 return ApiStatus_BLOCK;
120 }
121 enemy->aiFlags &= ~AI_FLAG_SUSPEND;
122 }
123
124 switch (script->functionTemp[0]) {
125 case 0:
126 N(FlyingAI_WanderInit)(script, aiSettings, territoryPtr);
127 case 1:
128 N(FlyingAI_Wander)(script, aiSettings, territoryPtr);
129 break;
130 case 2:
131 N(FlyingAI_LoiterInit)(script, aiSettings, territoryPtr);
132 case 3:
133 N(FlyingAI_Loiter)(script, aiSettings, territoryPtr);
134 break;
135 case 10:
136 N(FlyingAI_JumpInit)(script, aiSettings, territoryPtr);
137 case 11:
138 N(FlyingAI_Jump)(script, aiSettings, territoryPtr);
139 break;
140 case 12:
141 N(FlyingNoAttackAI_12)(script, aiSettings, territoryPtr);
142 case 13:
143 N(FlyingNoAttackAI_13)(script, aiSettings, territoryPtr);
144 break;
145 case 20:
146 N(FlyingNoAttackAI_20)(script, aiSettings, territoryPtr);
147 break;
148 }
149
150 return ApiStatus_BLOCK;
151}
152
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 FlyingNoAttackAI_13(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingNoAttackAI_20(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N FlyingNoAttackAI_12(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
#define npc_raycast_down_sides
#define rand_int
#define clamp_angle
#define atan2
@ EMOTE_QUESTION
Definition enums.h:497
@ ENEMY_ANIM_INDEX_IDLE
Definition enums.h:3426
@ ENEMY_ANIM_INDEX_CHASE
Definition enums.h:3429
@ AI_FLAG_SUSPEND
Definition enums.h:4571
@ NPC_FLAG_FLYING
Definition enums.h:3001
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)
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
s8 aiSuspendTime
Definition npc.h:333
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
s16 detectFlags
Definition npc.h:207
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
s32 flags
AnimID curAnim
s32 collisionChannel
s16 collisionHeight
s8 verticalRenderOffset
Vec3f pos
f32 moveSpeed
s16 duration
PlayerStatus * gPlayerStatusPtr