Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
ClubbaNappingAI.inc.c
Go to the documentation of this file.
1#include "common.h"
2#include "world/partners.h"
3
4// prerequisites
6
15
16void N(ClubbaNappingAI_Init)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
17 Enemy* enemy = script->owner1.enemy;
18 Npc* npc = get_npc_unsafe(enemy->npcID);
19
20 if (npc->duration > 0) {
21 npc->duration--;
22 }
23
24 if (npc->duration == 1) {
25 npc->curAnim = enemy->animList[12];
26 } else if (npc->duration <= 0) {
27 npc->curAnim = enemy->animList[10];
28 npc->duration = 0;
29 script->AI_TEMP_STATE = AI_STATE_NAPPING_CLUBBA_SLEEP;
30 }
31}
32
33void N(ClubbaNappingAI_Sleep)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
34 Enemy* enemy = script->owner1.enemy;
35 Npc* npc = get_npc_unsafe(enemy->npcID);
36 s32 shouldWakeUp = FALSE;
37 EffectInstance* emoteTemp;
38 f32 posX, posZ;
39
40 if (basic_ai_check_player_dist(territory, enemy, 80.0f, 0.0f, 0)) {
51 shouldWakeUp = TRUE;
52 }
53
56 shouldWakeUp = TRUE;
57 }
58 }
59 }
60
63 posX = npc->pos.x;
64 posZ = npc->pos.z;
65 add_vec2D_polar(&posX, &posZ, 0.0f, npc->yaw);
66 if (dist2D(posX, posZ, wPartnerNpc->pos.x, wPartnerNpc->pos.z) <= 80.0f) {
67 shouldWakeUp = TRUE;
68 }
69 }
70
71 if (shouldWakeUp) {
73 npc->curAnim = enemy->animList[11];
74 npc->duration = 10;
75 fx_emote(EMOTE_EXCLAMATION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, -20.0f, 15, &emoteTemp);
77 script->AI_TEMP_STATE = AI_STATE_NAPPING_CLUBBA_WAKE_UP;
78 }
79
80 npc->duration++;
81 if (npc->duration == 27) {
83 } else if (npc->duration == 57) {
85 } else if (npc->duration == 59) {
86 npc->curAnim = enemy->animList[12];
87 } else if (npc->duration == 60) {
88 npc->curAnim = enemy->animList[10];
89 npc->duration = 0;
90 }
91}
92
93void N(ClubbaNappingAI_WakeUp)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
94 Enemy* enemy = script->owner1.enemy;
95 Npc* npc = get_npc_unsafe(enemy->npcID);
96
97 npc->duration--;
98 if (npc->duration <= 0) {
99 npc->duration = 1;
100 enemy->AI_VAR_NEXT_STATE = AI_RETURN_HOME_INIT;
101 script->AI_TEMP_STATE = AI_STATE_NAPPING_CLUBBA_LOITER_INIT;
102 }
103}
104
105void N(ClubbaNappingAI_LoiterInit)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
106 Enemy* enemy = script->owner1.enemy;
107 Npc* npc = get_npc_unsafe(enemy->npcID);
108
109 npc->yaw = clamp_angle((npc->yaw + rand_int(180)) - 90.0f);
111 script->functionTemp[1] = (rand_int(1000) % 2) + 2; // chose random number 2-3
112 script->AI_TEMP_STATE = AI_STATE_NAPPING_CLUBBA_LOITER;
113}
114
115void N(ClubbaNappingAI_Loiter)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
116 Enemy* enemy = script->owner1.enemy;
117 Npc* npc = get_npc_unsafe(enemy->npcID);
118 s32 nextState;
119
120 // try to catch sight of player
121 if (basic_ai_check_player_dist(territory, enemy, aiSettings->chaseRadius, aiSettings->chaseOffsetDist, 0)) {
122 npc->yaw = atan2(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z);
123 script->AI_TEMP_STATE = AI_STATE_CHASE_INIT;
124 return;
125 }
126
127 npc->duration--;
128 if (npc->duration <= 0) {
129 // try to turn around and check the other direction
130 script->functionTemp[1]--;
131 if (script->functionTemp[1] > 0) {
132 npc->yaw = clamp_angle(npc->yaw + 180.0f);
133 npc->duration = aiSettings->waitTime / 2 + rand_int(aiSettings->waitTime / 2 + 1);
134 return;
135 }
136
137 // didnt see player, continue to next state
138 nextState = enemy->AI_VAR_NEXT_STATE;
139 if (nextState == AI_RETURN_HOME_INIT) {
140 npc->duration = 20;
141 script->AI_TEMP_STATE = nextState;
142 } else if (nextState == AI_STATE_NAPPING_CLUBBA_50) {
143 npc->duration = 25;
144 script->AI_TEMP_STATE = nextState;
145 }
146 }
147}
148
149void N(ClubbaNappingAI_ReturnHomeInit)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
150 Enemy* enemy = script->owner1.enemy;
151 Npc* npc = get_npc_unsafe(enemy->npcID);
152
153 npc->duration--;
154 if (npc->duration <= 0) {
156 if (enemy->territory->wander.moveSpeedOverride < 0) {
157 npc->moveSpeed = aiSettings->moveSpeed;
158 } else {
159 npc->moveSpeed = enemy->territory->wander.moveSpeedOverride / 32767.0;
160 }
161 script->AI_TEMP_STATE = AI_RETURN_HOME;
162 }
163}
164
165void N(ClubbaNappingAI_ReturnHome)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
166 Enemy* enemy = script->owner1.enemy;
167 Npc* npc = get_npc_unsafe(enemy->npcID);
168 f32 currentYaw;
169
170 if (basic_ai_check_player_dist(territory, enemy, aiSettings->chaseRadius, aiSettings->chaseOffsetDist, 0)) {
171 npc->yaw = atan2(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z);
172 script->AI_TEMP_STATE = AI_STATE_CHASE_INIT;
173 } else if (dist2D(npc->pos.x, npc->pos.z, enemy->territory->wander.centerPos.x,
174 enemy->territory->wander.centerPos.z) <= npc->moveSpeed) {
176 npc->duration = 15;
177 enemy->AI_VAR_NEXT_STATE = AI_STATE_NAPPING_CLUBBA_50;
178 script->AI_TEMP_STATE = AI_STATE_NAPPING_CLUBBA_LOITER_INIT;
179 } else if (npc->turnAroundYawAdjustment == 0) {
180 currentYaw = npc->yaw;
181 ai_check_fwd_collisions(npc, 5.0f, &currentYaw, 0, 0, 0);
182 npc->yaw = currentYaw;
183 npc->yaw = atan2(npc->pos.x, npc->pos.z, enemy->territory->wander.centerPos.x, enemy->territory->wander.centerPos.z);
184 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
185 }
186}
187
188void N(ClubbaNappingAI_FallAsleep)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
189 Enemy* enemy = script->owner1.enemy;
190 Npc* npc = get_npc_unsafe(enemy->npcID);
191
192 if (npc->turnAroundYawAdjustment == 0) {
193 npc->duration--;
194 if (npc->duration <= 0) {
195 npc->duration = 0;
196 script->AI_TEMP_STATE = AI_STATE_NAPPING_CLUBBA_INIT;
197 }
198 }
199}
200
201API_CALLABLE(N(ClubbaNappingAI_Main)) {
202 Enemy* enemy = script->owner1.enemy;
203 Npc* npc = get_npc_unsafe(enemy->npcID);
204 Bytecode* args = script->ptrReadPos;
205 EnemyDetectVolume territory;
206 EnemyDetectVolume* territoryPtr = &territory;
207 MobileAISettings* npcAISettings = (MobileAISettings*)evt_get_variable(script, *args++);
208
209 territory.skipPlayerDetectChance = 0;
210 territory.shape = enemy->territory->wander.detectShape;
211 territory.pointX = enemy->territory->wander.detectPos.x;
212 territory.pointZ = enemy->territory->wander.detectPos.z;
213 territory.sizeX = enemy->territory->wander.detectSize.x;
214 territory.sizeZ = enemy->territory->wander.detectSize.z;
215 territory.halfHeight = 40.0f;
216 territory.detectFlags = 0;
217
218 if (isInitialCall || (enemy->aiFlags & AI_FLAG_SUSPEND)) {
219 script->AI_TEMP_STATE = AI_STATE_NAPPING_CLUBBA_INIT;
220 npc->duration = 30;
221 npc->curAnim = enemy->animList[10];
222 npc->flags &= ~NPC_FLAG_JUMPING;
223 enemy->AI_VAR_ATTACK_STATE = MELEE_HITBOX_STATE_NONE;
224 if (!enemy->territory->wander.isFlying) {
225 npc->flags = (npc->flags | NPC_FLAG_GRAVITY) & ~NPC_FLAG_FLYING;
226 } else {
227 npc->flags = (npc->flags & ~NPC_FLAG_GRAVITY) | NPC_FLAG_FLYING;
228 }
229 if (enemy->aiFlags & AI_FLAG_SUSPEND) {
230 script->AI_TEMP_STATE = AI_STATE_SUSPEND;
231 script->AI_TEMP_STATE_AFTER_SUSPEND = AI_RETURN_HOME_INIT;
233 }
234 enemy->aiFlags &= ~AI_FLAG_SUSPEND;
235 }
236
237 if (script->AI_TEMP_STATE >= AI_STATE_ALERT_INIT
238 && script->AI_TEMP_STATE < AI_STATE_MELEE_HITBOX_INIT
239 && enemy->AI_VAR_ATTACK_STATE == MELEE_HITBOX_STATE_NONE
240 && N(MeleeHitbox_CanSeePlayer)(script)) {
241 script->AI_TEMP_STATE = AI_STATE_MELEE_HITBOX_INIT;
242 }
243
244 switch (script->AI_TEMP_STATE) {
246 N(ClubbaNappingAI_Init)(script, npcAISettings, territoryPtr);
247 break;
249 N(ClubbaNappingAI_Sleep)(script, npcAISettings, territoryPtr);
250 break;
252 N(ClubbaNappingAI_WakeUp)(script, npcAISettings, territoryPtr);
253 break;
255 N(ClubbaNappingAI_LoiterInit)(script, npcAISettings, territoryPtr);
256 break;
258 N(ClubbaNappingAI_Loiter)(script, npcAISettings, territoryPtr);
259 break;
261 basic_ai_chase_init(script, npcAISettings, territoryPtr);
262 if (script->AI_TEMP_STATE != AI_STATE_CHASE) {
263 break;
264 }
265 case AI_STATE_CHASE:
266 basic_ai_chase(script, npcAISettings, territoryPtr);
267 break;
269 // LOSE PLAYER
270 basic_ai_lose_player(script, npcAISettings, territoryPtr);
271 npc->duration = 15;
272 enemy->AI_VAR_NEXT_STATE = AI_RETURN_HOME_INIT;
273 script->AI_TEMP_STATE = AI_STATE_NAPPING_CLUBBA_LOITER_INIT;
274 break;
275 case AI_STATE_MELEE_HITBOX_INIT: // pre swing
276 N(MeleeHitbox_30)(script);
277 if (script->AI_TEMP_STATE != AI_STATE_MELEE_HITBOX_PRE) {
278 break;
279 }
280 case AI_STATE_MELEE_HITBOX_PRE: // raise club
281 N(MeleeHitbox_31)(script);
282 if (script->AI_TEMP_STATE != AI_STATE_MELEE_HITBOX_ACTIVE) {
283 break;
284 }
285 case AI_STATE_MELEE_HITBOX_ACTIVE: // swing club
286 N(MeleeHitbox_32)(script);
287 break;
289 N(MeleeHitbox_33)(script);
290 break;
292 // START RETURN HOME
293 N(ClubbaNappingAI_ReturnHomeInit)(script, npcAISettings, territoryPtr);
294 if (script->AI_TEMP_STATE != AI_RETURN_HOME) {
295 break;
296 }
297 case AI_RETURN_HOME:
298 // RETURN HOME
299 N(ClubbaNappingAI_ReturnHome)(script, npcAISettings, territoryPtr);
300 break;
302 // WAIT TO NAP
303 N(ClubbaNappingAI_FallAsleep)(script, npcAISettings, territoryPtr);
304 break;
305 case AI_STATE_SUSPEND:
306 basic_ai_suspend(script);
307 }
308
309 return ApiStatus_BLOCK;
310}
void N ClubbaNappingAI_Sleep(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N ClubbaNappingAI_FallAsleep(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N ClubbaNappingAI_Init(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N ClubbaNappingAI_ReturnHomeInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N ClubbaNappingAI_LoiterInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N ClubbaNappingAI_ReturnHome(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N ClubbaNappingAI_Loiter(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N ClubbaNappingAI_WakeUp(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
AiStateNappingClubba
@ AI_STATE_NAPPING_CLUBBA_LOITER_INIT
@ AI_STATE_NAPPING_CLUBBA_WAKE_UP
@ AI_STATE_NAPPING_CLUBBA_INIT
@ AI_STATE_NAPPING_CLUBBA_SLEEP
@ AI_STATE_NAPPING_CLUBBA_LOITER
@ AI_STATE_NAPPING_CLUBBA_50
void N MeleeHitbox_31(Evt *script)
void N MeleeHitbox_32(Evt *script)
s32 N MeleeHitbox_CanSeePlayer(Evt *script)
void N MeleeHitbox_33(Evt *script)
void N MeleeHitbox_30(Evt *script)
#define rand_int
#define clamp_angle
#define atan2
@ EMOTE_EXCLAMATION
Definition enums.h:495
@ ENEMY_ANIM_INDEX_IDLE
Definition enums.h:3426
@ ENEMY_ANIM_INDEX_WALK
Definition enums.h:3427
@ AI_FLAG_SUSPEND
Definition enums.h:4571
@ PARTNER_ACTION_BOMBETTE_2
Definition enums.h:2937
@ PARTNER_ACTION_NONE
Definition enums.h:2932
@ AI_STATE_SUSPEND
Definition enums.h:4598
@ AI_STATE_MELEE_HITBOX_INIT
Definition enums.h:4600
@ AI_STATE_MELEE_HITBOX_ACTIVE
Definition enums.h:4602
@ AI_STATE_CHASE_INIT
Definition enums.h:4592
@ AI_STATE_CHASE
Definition enums.h:4593
@ AI_STATE_MELEE_HITBOX_MISS
Definition enums.h:4603
@ AI_STATE_LOSE_PLAYER
Definition enums.h:4594
@ AI_RETURN_HOME_INIT
Definition enums.h:4596
@ AI_RETURN_HOME
Definition enums.h:4597
@ AI_STATE_MELEE_HITBOX_PRE
Definition enums.h:4601
@ AI_STATE_ALERT_INIT
Definition enums.h:4590
@ MELEE_HITBOX_STATE_NONE
Definition enums.h:4643
@ SOUND_SEQ_SNORE_INHALE
Definition enums.h:1711
@ SOUND_SEQ_SNORE_EXHALE
Definition enums.h:1712
@ SOUND_AI_ALERT_A
Definition enums.h:1078
@ SOUND_SEQ_SNAP_AWAKE
Definition enums.h:1713
@ PARTNER_BOMBETTE
Definition enums.h:2888
@ PARTNER_KOOPER
Definition enums.h:2887
@ PARTNER_GOOMBARIO
Definition enums.h:2886
@ ACTION_STATE_JUMP
Definition enums.h:2430
@ ACTION_STATE_STEP_DOWN_LAND
Definition enums.h:2438
@ ACTION_STATE_SPIN_POUND
Definition enums.h:2442
@ ACTION_STATE_TORNADO_POUND
Definition enums.h:2444
@ ACTION_STATE_INVALID_25
Definition enums.h:2465
@ ACTION_STATE_LAND
Definition enums.h:2437
@ ACTION_STATE_13
Definition enums.h:2447
@ ACTION_STATE_HAMMER
Definition enums.h:2446
@ ACTION_STATE_SPIN
Definition enums.h:2454
@ ACTION_STATE_RUN
Definition enums.h:2428
@ SOUND_PARAM_MORE_QUIET
Definition enums.h:1746
@ NPC_FLAG_FLYING
Definition enums.h:3001
@ NPC_FLAG_GRAVITY
Definition enums.h:3007
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
void basic_ai_chase_init(Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
Definition 23680.c:769
void basic_ai_lose_player(Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
Definition 23680.c:847
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
void basic_ai_chase(Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
Definition 23680.c:804
void add_vec2D_polar(f32 *x, f32 *y, f32 r, f32 theta)
Definition 43F0.c:685
s32 ai_check_fwd_collisions(Npc *npc, f32 arg1, f32 *arg2, f32 *arg3, f32 *arg4, f32 *arg5)
Definition 25AF0.c:22
void basic_ai_suspend(Evt *script)
Definition 25AF0.c:13
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
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
s16 detectFlags
Definition npc.h:207
s32 moveSpeedOverride
Definition npc.h:213
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
Npc * wPartnerNpc
Definition partners.c:43
s32 flags
AnimID curAnim
s16 collisionHeight
s16 turnAroundYawAdjustment
Vec3f pos
f32 moveSpeed
s16 duration
PlayerStatus * gPlayerStatusPtr
PartnerStatus gPartnerStatus
Definition partners.c:42
PlayerData gPlayerData
Definition 77480.c:40