Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
SpearGuyAI.inc.c
Go to the documentation of this file.
1#include "common.h"
2#include "npc.h"
3#include "effects.h"
4#include "sprite/npc/SpearGuy.h"
5
6void N(SpearGuyAI_LoiterInit)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
7 Enemy* enemy = script->owner1.enemy;
8 Npc* npc = get_npc_unsafe(enemy->npcID);
9
10 npc->duration = 0;
11 set_npc_yaw(npc, 270.0f);
12 enemy->varTable[0] = 0;
13 script->AI_TEMP_STATE = AI_STATE_LOITER;
14}
15
16void N(SpearGuyAI_Loiter)(Evt* script, MobileAISettings* aiSettings, EnemyDetectVolume* territory) {
17 Enemy* enemy = script->owner1.enemy;
18 Npc* npc = get_npc_unsafe(enemy->npcID);
19 s32 d100;
20
21 if (enemy->varTable[0] == 0) {
22 if (rand_int(100) >= 50) {
23 enemy->varTable[0] = 3;
24 } else {
25 enemy->varTable[0] = 1;
26 }
27 set_npc_yaw(npc, 270.0f);
28 }
29
30 switch (enemy->varTable[0]) {
31 case 1:
32 enemy->varTable[0] = 2;
33 enemy->varTable[1] = 0;
34 npc->curAnim = ANIM_SpearGuy_Anim0F;
35 case 2:
36 enemy->varTable[1]++;
37 if (enemy->varTable[1] > 50) {
38 enemy->varTable[0] = 5;
39 }
40 break;
41 case 3:
42 enemy->varTable[0] = 4;
43 enemy->varTable[1] = 0;
44 npc->curAnim = ANIM_SpearGuy_Anim10;
45 case 4:
46 enemy->varTable[1]++;
47 if (enemy->varTable[1] == 25) {
48 npc->yaw = 90.0f;
49 }
50 if (enemy->varTable[1] > 60) {
51 enemy->varTable[0] = 5;
52 }
53 break;
54 case 5:
55 enemy->varTable[0] = 6;
56 enemy->varTable[1] = 0;
57 npc->curAnim = ANIM_SpearGuy_Anim03;
58 fx_sweat(0, npc->pos.x, npc->pos.y, npc->pos.z, npc->collisionHeight, 0, 10);
59 case 6:
60 enemy->varTable[1]++;
61 if (enemy->varTable[1] > 10) {
62 d100 = rand_int(100);
63
64 if (d100 < 90) {
65 enemy->varTable[0] = 7;
66 } else if (d100 >= 95) {
67 enemy->varTable[0] = 3;
68 } else {
69 enemy->varTable[0] = 1;
70 }
71 }
72 break;
73 }
74
75 if (enemy->varTable[0] == 7) {
76 script->AI_TEMP_STATE = AI_STATE_WANDER_INIT;
77 }
78}
79
80// prerequisites
82
83API_CALLABLE(N(SpearGuyAI_Main)) {
84 Enemy* enemy = script->owner1.enemy;
85 Npc *npc = get_npc_unsafe(enemy->npcID);
86 Bytecode* args = script->ptrReadPos;
87 EnemyDetectVolume territory;
88 EnemyDetectVolume* territoryPtr = &territory;
89 MobileAISettings* npcAISettings = (MobileAISettings*)evt_get_variable(script, *args++);
90
91 territory.skipPlayerDetectChance = 0;
92 territory.shape = enemy->territory->wander.detectShape;
93 territory.pointX = enemy->territory->wander.detectPos.x;
94 territory.pointZ = enemy->territory->wander.detectPos.z;
95 territory.sizeX = enemy->territory->wander.detectSize.x;
96 territory.sizeZ = enemy->territory->wander.detectSize.z;
97 territory.halfHeight = 65.0f;
98 territory.detectFlags = 0;
99
100 if (isInitialCall || (enemy->aiFlags & AI_FLAG_SUSPEND)) {
101 script->AI_TEMP_STATE = AI_STATE_WANDER_INIT;
102 npc->duration = 0;
104
105 npc->flags &= ~NPC_FLAG_JUMPING;
106 if (!enemy->territory->wander.isFlying) {
107 npc->flags |= NPC_FLAG_GRAVITY;
108 npc->flags &= ~NPC_FLAG_FLYING;
109 } else {
110 npc->flags &= ~NPC_FLAG_GRAVITY;
111 npc->flags |= NPC_FLAG_FLYING;
112 }
113
114 if (enemy->aiFlags & AI_FLAG_SUSPEND) {
115 script->AI_TEMP_STATE = AI_STATE_SUSPEND;
116 script->AI_TEMP_STATE_AFTER_SUSPEND = AI_STATE_WANDER_INIT;
117 enemy->aiFlags &= ~AI_FLAG_SUSPEND;
118 }
119 enemy->varTable[0] = 0;
120 }
121
122 if ((script->AI_TEMP_STATE < AI_STATE_MELEE_HITBOX_INIT) && (enemy->varTable[0] == 0) && N(MeleeHitbox_CanSeePlayer)(script)) {
123 script->AI_TEMP_STATE = AI_STATE_MELEE_HITBOX_INIT;
124 }
125
126 switch (script->AI_TEMP_STATE) {
128 basic_ai_wander_init(script, npcAISettings, territoryPtr);
129 case AI_STATE_WANDER:
130 basic_ai_wander(script, npcAISettings, territoryPtr);
131 break;
132
134 N(SpearGuyAI_LoiterInit)(script, npcAISettings, territoryPtr);
135 case AI_STATE_LOITER:
136 N(SpearGuyAI_Loiter)(script, npcAISettings, territoryPtr);
137 break;
138
140 basic_ai_found_player_jump_init(script, npcAISettings, territoryPtr);
141 case AI_STATE_ALERT:
142 basic_ai_found_player_jump(script, npcAISettings, territoryPtr);
143 break;
144
146 basic_ai_chase_init(script, npcAISettings, territoryPtr);
147 case AI_STATE_CHASE:
148 basic_ai_chase(script, npcAISettings, territoryPtr);
149 break;
150
152 basic_ai_lose_player(script, npcAISettings, territoryPtr);
153 break;
154
156 N(MeleeHitbox_30)(script);
158 N(MeleeHitbox_31)(script);
159 if (script->AI_TEMP_STATE != AI_STATE_MELEE_HITBOX_ACTIVE) {
160 break;
161 }
163 N(MeleeHitbox_32)(script);
164 if (script->AI_TEMP_STATE != AI_STATE_MELEE_HITBOX_MISS) {
165 break;
166 }
168 N(MeleeHitbox_33)(script);
169 break;
170
171 case AI_STATE_SUSPEND:
172 basic_ai_suspend(script);
173 }
174
175 return ApiStatus_BLOCK;
176}
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)
void N SpearGuyAI_LoiterInit(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
void N SpearGuyAI_Loiter(Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
#define rand_int
@ ENEMY_ANIM_INDEX_IDLE
Definition enums.h:3426
@ AI_FLAG_SUSPEND
Definition enums.h:4571
@ AI_STATE_WANDER
Definition enums.h:4582
@ AI_STATE_LOITER
Definition enums.h:4588
@ AI_STATE_SUSPEND
Definition enums.h:4598
@ AI_STATE_MELEE_HITBOX_INIT
Definition enums.h:4600
@ AI_STATE_WANDER_INIT
Definition enums.h:4581
@ AI_STATE_MELEE_HITBOX_ACTIVE
Definition enums.h:4602
@ 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_MELEE_HITBOX_MISS
Definition enums.h:4603
@ AI_STATE_LOSE_PLAYER
Definition enums.h:4594
@ AI_STATE_MELEE_HITBOX_PRE
Definition enums.h:4601
@ AI_STATE_ALERT_INIT
Definition enums.h:4590
@ 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 basic_ai_wander(Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
Definition 23680.c:588
void basic_ai_chase(Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
Definition 23680.c:804
void basic_ai_found_player_jump_init(Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
Definition 23680.c:735
void basic_ai_wander_init(Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
Definition 23680.c:567
void basic_ai_found_player_jump(Evt *script, MobileAISettings *npcAISettings, EnemyDetectVolume *territory)
Definition 23680.c:748
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
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
u32 aiFlags
Definition npc.h:332
void set_npc_yaw(Npc *npc, f32 yaw)
Definition npc.c:1246
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
s16 collisionHeight
Vec3f pos
s16 duration