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

Go to the source code of this file.

Macros

#define AI_SENTINEL_FIRST_NPC   0
 
#define AI_SENTINEL_LAST_NPC   0
 
#define SENTINEL_AI_FLAG_CHASING   0x100
 
#define SENTINEL_AI_FLAG_PLAYING_SOUND   0x1000
 
#define SENTINEL_AI_DESCEND_RATE   1.8
 

Enumerations

enum  AiStateSentinel {
  AI_STATE_SENTINEL_WANDER_INIT = 0 , AI_STATE_SENTINEL_WANDER = 1 , AI_STATE_SENTINEL_LOITER_INIT = 2 , AI_STATE_SENTINEL_LOITER = 3 ,
  AI_STATE_SENTINEL_CHASE_INIT = 12 , AI_STATE_SENTINEL_CHASE = 13 , AI_STATE_SENTINEL_DESCEND_INIT = 14 , AI_STATE_SENTINEL_DESCEND = 15 ,
  AI_STATE_SENTINEL_LOSE_PLAYER_INIT = 16 , AI_STATE_SENTINEL_LOSE_PLAYER = 17 , AI_STATE_SENTINEL_POST_LOSE_PLAYER = 18 , AI_STATE_SENTINEL_GRAB_PLAYER = 20 ,
  AI_STATE_SENTINEL_RETURN_HOME_INIT = 30 , AI_STATE_SENTINEL_RETURN_HOME = 31 , AI_STATE_SENTINEL_CAUGHT_PLAYER = 100
}
 

Functions

void N SentinelAI_ChaseInit (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_Chase (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_DescendInit (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_Descend (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_LosePlayerInit (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_LosePlayer (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_PostLosePlayer (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_GrabPlayer (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_ReturnHomeInit (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 
void N SentinelAI_ReturnHome (Evt *script, MobileAISettings *aiSettings, EnemyDetectVolume *territory)
 

Macro Definition Documentation

◆ AI_SENTINEL_FIRST_NPC

#define AI_SENTINEL_FIRST_NPC   0

Definition at line 9 of file SentinelAI.inc.c.

Referenced by SentinelAI_DescendInit().

◆ AI_SENTINEL_LAST_NPC

#define AI_SENTINEL_LAST_NPC   0

Definition at line 13 of file SentinelAI.inc.c.

Referenced by SentinelAI_DescendInit().

◆ SENTINEL_AI_FLAG_CHASING

#define SENTINEL_AI_FLAG_CHASING   0x100

Definition at line 37 of file SentinelAI.inc.c.

Referenced by SentinelAI_DescendInit().

◆ SENTINEL_AI_FLAG_PLAYING_SOUND

#define SENTINEL_AI_FLAG_PLAYING_SOUND   0x1000

Definition at line 38 of file SentinelAI.inc.c.

Referenced by SentinelAI_DescendInit(), and SentinelAI_LosePlayerInit().

◆ SENTINEL_AI_DESCEND_RATE

#define SENTINEL_AI_DESCEND_RATE   1.8

Definition at line 40 of file SentinelAI.inc.c.

Referenced by SentinelAI_Descend().

Enumeration Type Documentation

◆ AiStateSentinel

Enumerator
AI_STATE_SENTINEL_WANDER_INIT 
AI_STATE_SENTINEL_WANDER 
AI_STATE_SENTINEL_LOITER_INIT 
AI_STATE_SENTINEL_LOITER 
AI_STATE_SENTINEL_CHASE_INIT 
AI_STATE_SENTINEL_CHASE 
AI_STATE_SENTINEL_DESCEND_INIT 
AI_STATE_SENTINEL_DESCEND 
AI_STATE_SENTINEL_LOSE_PLAYER_INIT 
AI_STATE_SENTINEL_LOSE_PLAYER 
AI_STATE_SENTINEL_POST_LOSE_PLAYER 
AI_STATE_SENTINEL_GRAB_PLAYER 
AI_STATE_SENTINEL_RETURN_HOME_INIT 
AI_STATE_SENTINEL_RETURN_HOME 
AI_STATE_SENTINEL_CAUGHT_PLAYER 

Definition at line 19 of file SentinelAI.inc.c.

19 {
35};
@ AI_STATE_SENTINEL_LOITER
@ AI_STATE_SENTINEL_DESCEND
@ AI_STATE_SENTINEL_LOSE_PLAYER_INIT
@ AI_STATE_SENTINEL_CHASE_INIT
@ AI_STATE_SENTINEL_CHASE
@ AI_STATE_SENTINEL_WANDER
@ AI_STATE_SENTINEL_GRAB_PLAYER
@ AI_STATE_SENTINEL_LOITER_INIT
@ AI_STATE_SENTINEL_DESCEND_INIT
@ AI_STATE_SENTINEL_POST_LOSE_PLAYER
@ AI_STATE_SENTINEL_RETURN_HOME_INIT
@ AI_STATE_SENTINEL_RETURN_HOME
@ AI_STATE_SENTINEL_LOSE_PLAYER
@ AI_STATE_SENTINEL_CAUGHT_PLAYER
@ AI_STATE_SENTINEL_WANDER_INIT

Function Documentation

◆ SentinelAI_ChaseInit()

void N SentinelAI_ChaseInit ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 42 of file SentinelAI.inc.c.

42 {
43 Enemy* enemy = script->owner1.enemy;
44 Npc* npc = get_npc_unsafe(enemy->npcID);
45 f32 deltaAngle;
46 f32 angle;
47
48 npc->duration--;
49 if (npc->duration <= 0) {
50 npc->flags &= ~NPC_FLAG_FLIP_INSTANTLY;
51 npc->duration = aiSettings->chaseUpdateInterval / 2 + rand_int(aiSettings->chaseUpdateInterval / 2 + 1);
53 npc->moveSpeed = aiSettings->chaseSpeed;
54 angle = atan2(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z);
55 deltaAngle = get_clamped_angle_diff(npc->yaw, angle);
56 if (aiSettings->chaseTurnRate < fabsf(deltaAngle)) {
57 angle = npc->yaw;
58 if (deltaAngle < 0.0f) {
59 angle += -aiSettings->chaseTurnRate;
60 } else {
61 angle += aiSettings->chaseTurnRate;
62 }
63 }
64 npc->yaw = clamp_angle(angle);
65 script->AI_TEMP_STATE = AI_STATE_SENTINEL_CHASE;
66 }
67}
union Evt::@8 owner1
Initially -1.
#define rand_int
#define clamp_angle
#define atan2
@ ENEMY_ANIM_INDEX_MELEE_PRE
Definition enums.h:3434
f32 fabsf(f32 f)
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
s16 npcID
Definition npc.h:300
s32 * animList
Definition npc.h:341
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
Definition npc.h:294
s32 flags
AnimID curAnim
Vec3f pos
f32 moveSpeed
s16 duration
PlayerStatus * gPlayerStatusPtr

◆ SentinelAI_Chase()

void N SentinelAI_Chase ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 69 of file SentinelAI.inc.c.

69 {
70 Enemy* enemy = script->owner1.enemy;
71 Npc* npc = get_npc_unsafe(enemy->npcID);
72
73 if (basic_ai_check_player_dist(territory, enemy, aiSettings->chaseRadius, aiSettings->chaseOffsetDist, 1)) {
74 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
75 if (dist2D(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x,
76 gPlayerStatusPtr->pos.z) <= (npc->moveSpeed * 2.5)) {
77 npc->duration = 0;
78 script->AI_TEMP_STATE = AI_STATE_SENTINEL_DESCEND_INIT;
79 } else {
80 npc->duration--;
81 if (npc->duration <= 0) {
83 script->AI_TEMP_STATE = AI_STATE_SENTINEL_CHASE_INIT;
84 }
85 }
86 } else {
87 script->AI_TEMP_STATE = AI_STATE_SENTINEL_LOSE_PLAYER_INIT;
88 }
89}
@ NPC_FLAG_FLIP_INSTANTLY
Definition enums.h:3019
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
s32 basic_ai_check_player_dist(EnemyDetectVolume *arg0, Enemy *arg1, f32 arg2, f32 arg3, b8 arg4)
Definition 23680.c:429
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

◆ SentinelAI_DescendInit()

void N SentinelAI_DescendInit ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 91 of file SentinelAI.inc.c.

91 {
92 Enemy* enemy = script->owner1.enemy;
93 Npc* npc = get_npc_unsafe(enemy->npcID);
94 s32 i;
95
97 if (i != npc->npcID && (get_enemy(i)->varTable[0] & SENTINEL_AI_FLAG_CHASING)) {
98 return;
99 }
100 }
101
102 enemy->varTable[0] |= SENTINEL_AI_FLAG_CHASING;
103 npc->pos.x = gPlayerStatusPtr->pos.x;
104 npc->pos.z = gPlayerStatusPtr->pos.z;
105 if (!(enemy->varTable[0] & SENTINEL_AI_FLAG_PLAYING_SOUND)) {
106 enemy->varTable[0] |= SENTINEL_AI_FLAG_PLAYING_SOUND;
107 }
109 npc->duration = 0;
110 script->AI_TEMP_STATE = AI_STATE_SENTINEL_DESCEND;
111}
#define SENTINEL_AI_FLAG_CHASING
#define AI_SENTINEL_FIRST_NPC
#define SENTINEL_AI_FLAG_PLAYING_SOUND
#define AI_SENTINEL_LAST_NPC
#define sfx_play_sound_at_position
@ SOUND_LOOP_SENTINEL_ALARM
Definition enums.h:1598
@ SOUND_SPACE_FULL
Definition enums.h:1739
Enemy * get_enemy(s32 npcID)
Looks for an enemy matching the specified npcID.
Definition npc.c:2540

◆ SentinelAI_Descend()

void N SentinelAI_Descend ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )
Bug
need to use real sound id, not environmental sound id

Definition at line 113 of file SentinelAI.inc.c.

113 {
114 Enemy* enemy = script->owner1.enemy;
115 Npc* npc = get_npc_unsafe(enemy->npcID);
116 f32 posX, posY, posZ, hitDepth;
117 s32 color;
118
121 if (!basic_ai_check_player_dist(territory, enemy, aiSettings->chaseRadius, aiSettings->chaseOffsetDist, 1)) {
122 enemy->varTable[0] &= ~SENTINEL_AI_FLAG_CHASING;
123 npc->rot.y = 0.0f;
124 npc->flags &= ~NPC_FLAG_FLIP_INSTANTLY;
125 script->AI_TEMP_STATE = AI_STATE_SENTINEL_LOSE_PLAYER_INIT;
126 } else {
127 npc->pos.x = gPlayerStatusPtr->pos.x;
128 npc->pos.z = gPlayerStatusPtr->pos.z + 2.0f;
129 npc->rot.y += 25.0f;
130 if (npc->rot.y > 360.0) {
131 npc->rot.y -= 360.0;
132 }
133 color = 255.0f - (cosine((s32)npc->rot.y % 180) * 56.0f);
134 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_COLOR, color, color, color, 255, 0);
135
136 posX = gPlayerStatusPtr->pos.x;
137 posY = gPlayerStatusPtr->pos.y;
138 posZ = gPlayerStatusPtr->pos.z;
139 hitDepth = 1000.0f;
140 npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &hitDepth);
141 if (fabsf(npc->pos.y - posY) > 24.0) {
143 } else {
144 npc->rot.y = 0.0f;
145 npc->flags &= ~NPC_FLAG_FLIP_INSTANTLY;
149 npc->duration = 0;
150 script->AI_TEMP_STATE = AI_STATE_SENTINEL_GRAB_PLAYER;
151 } else {
152 script->AI_TEMP_STATE = AI_STATE_SENTINEL_LOSE_PLAYER_INIT;
153 }
154 }
155 }
156}
#define SENTINEL_AI_DESCEND_RATE
#define npc_raycast_down_sides
@ IMGFX_SET_COLOR
Definition enums.h:5123
@ PARTNER_BOW
Definition enums.h:2894
void partner_disable_input(void)
Definition partners.c:2489
s32 disable_player_input(void)
Definition 77480.c:990
f32 cosine(s16 arg0)
Definition 43F0.c:354
s32 sfx_adjust_env_sound_pos(s32 soundID, s32 sourceFlags, f32 x, f32 y, f32 z)
Definition sfx.c:431
void set_npc_imgfx_all(s32 spriteIdx, ImgFXType imgfxType, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5)
Definition sprite.c:1254
s32 spriteInstanceID
s32 collisionChannel
Vec3f rot
PartnerStatus gPartnerStatus
Definition partners.c:42

◆ SentinelAI_LosePlayerInit()

void N SentinelAI_LosePlayerInit ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 158 of file SentinelAI.inc.c.

158 {
159 Enemy* enemy = script->owner1.enemy;
160 Npc* npc = get_npc_unsafe(enemy->npcID);
161
162 enemy->varTable[0] &= ~SENTINEL_AI_FLAG_CHASING;
163 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_CLEAR, 0, 0, 0, 0, 0);
164 if (enemy->varTable[0] & SENTINEL_AI_FLAG_PLAYING_SOUND) {
166 enemy->varTable[0] &= ~SENTINEL_AI_FLAG_PLAYING_SOUND;
167 }
169 npc->duration = 20;
170 script->AI_TEMP_STATE = AI_STATE_SENTINEL_LOSE_PLAYER;
171}
@ IMGFX_CLEAR
Definition enums.h:5117
@ ENEMY_ANIM_INDEX_MELEE_HIT
Definition enums.h:3435
void sfx_stop_sound(s32 soundID)
Definition sfx.c:507

◆ SentinelAI_LosePlayer()

void N SentinelAI_LosePlayer ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 173 of file SentinelAI.inc.c.

173 {
174 Enemy* enemy = script->owner1.enemy;
175 Npc* npc = get_npc_unsafe(enemy->npcID);
176 f32 posX, posY, posZ, posW;
177 f32 idleHeight = (f32)enemy->varTable[3] / 100.0;
178 EffectInstance* emoteTemp;
179
180 npc->pos.y += 2.5;
181 posX = npc->pos.x;
182 posY = npc->pos.y;
183 posZ = npc->pos.z;
184 posW = 1000.0f;
185 npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &posW);
186 if (!(npc->pos.y < posY + idleHeight)) {
187 npc->yaw = atan2(npc->pos.x, npc->pos.z, enemy->territory->wander.centerPos.x, enemy->territory->wander.centerPos.z);
188 npc->pos.y = posY + idleHeight;
189 fx_emote(EMOTE_QUESTION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, -20.0f, 10, &emoteTemp);
190 npc->duration = 10;
191 script->AI_TEMP_STATE = AI_STATE_SENTINEL_POST_LOSE_PLAYER;
192 }
193}
@ EMOTE_QUESTION
Definition enums.h:497

◆ SentinelAI_PostLosePlayer()

void N SentinelAI_PostLosePlayer ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 195 of file SentinelAI.inc.c.

195 {
196 Enemy* enemy = script->owner1.enemy;
197 Npc* npc = get_npc_unsafe(enemy->npcID);
198
199 npc->duration--;
200 if (npc->duration <= 0) {
201 script->AI_TEMP_STATE = AI_STATE_SENTINEL_RETURN_HOME_INIT;
202 }
203}

◆ SentinelAI_GrabPlayer()

void N SentinelAI_GrabPlayer ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 205 of file SentinelAI.inc.c.

205 {
206 Enemy* enemy = script->owner1.enemy;
207 Npc* npc = get_npc_unsafe(enemy->npcID);
208
209 npc->duration++;
210 if (npc->duration >= 3) {
212 npc->duration = 0;
213 script->AI_TEMP_STATE = AI_STATE_SENTINEL_CAUGHT_PLAYER;
214 } else {
217 script->AI_TEMP_STATE = AI_STATE_SENTINEL_LOSE_PLAYER_INIT;
218 }
219 }
220}
s32 enable_player_input(void)
Definition 77480.c:998
void partner_enable_input(void)
Definition partners.c:2480

◆ SentinelAI_ReturnHomeInit()

void N SentinelAI_ReturnHomeInit ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 222 of file SentinelAI.inc.c.

222 {
223 Enemy* enemy = script->owner1.enemy;
224 Npc* npc = get_npc_unsafe(enemy->npcID);
225
226 enemy->varTable[0] &= ~SENTINEL_AI_FLAG_CHASING;
227 npc->flags &= ~NPC_FLAG_FLIP_INSTANTLY;
228 npc->moveSpeed = 2.0 * aiSettings->moveSpeed;
229 enemy->varTable[2] = 0;
230 enemy->varTable[4] = npc->pos.y * 100.0;
231 script->functionTemp[1] = 30;
232}
f32 moveSpeed
Definition npc.h:93

◆ SentinelAI_ReturnHome()

void N SentinelAI_ReturnHome ( Evt * script,
MobileAISettings * aiSettings,
EnemyDetectVolume * territory )

Definition at line 234 of file SentinelAI.inc.c.

234 {
235 Enemy* enemy = script->owner1.enemy;
236 Npc* npc = get_npc_unsafe(enemy->npcID);
237 f32 posX = npc->pos.x;
238 f32 posY = npc->pos.y;
239 f32 posZ = npc->pos.z;
240 f32 hitDepth = 1000.0f;
241 f32 idleHeight = (f32)enemy->varTable[3] / 100.0;
242 f32 temp_f24 = idleHeight + (f32)((f32)enemy->varTable[7] / 100.0);
243 f32 undulateAmplitude = (f32)enemy->varTable[1] / 100.0;
244 f32 undulateAmount = sin_deg(enemy->varTable[2]);
245 EffectInstance* emoteTemp;
246
247 if (npc_raycast_down_sides(npc->collisionChannel, &posX, &posY, &posZ, &hitDepth)) {
248 npc->pos.y = posY + idleHeight + (undulateAmount * undulateAmplitude);
249 } else {
250 npc->pos.y = temp_f24 + (undulateAmount * undulateAmplitude);
251 }
252
253 enemy->varTable[2] = clamp_angle(enemy->varTable[2] + 12);
254 if (script->functionTemp[1] <= 0) {
255 script->functionTemp[1] = aiSettings->playerSearchInterval;
256 if (basic_ai_check_player_dist(territory, enemy, aiSettings->alertRadius * 0.5, aiSettings->alertOffsetDist * 0.5, 0)) {
257 fx_emote(EMOTE_EXCLAMATION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, -20.0f, 12, &emoteTemp);
259 npc->moveToPos.y = npc->pos.y;
260 script->AI_TEMP_STATE = AI_STATE_SENTINEL_CHASE_INIT;
261 return;
262 }
263 }
264
265 script->functionTemp[1]--;
266 if (npc->turnAroundYawAdjustment == 0) {
267 npc->yaw = atan2(npc->pos.x, npc->pos.z, enemy->territory->wander.centerPos.x, enemy->territory->wander.centerPos.z);
268 npc_move_heading(npc, npc->moveSpeed, npc->yaw);
269 hitDepth = dist2D(npc->pos.x, npc->pos.z, enemy->territory->wander.centerPos.x, enemy->territory->wander.centerPos.z);
270 if (hitDepth <= (2.0f * npc->moveSpeed)) {
271 script->functionTemp[1] = (rand_int(1000) % 3) + 2;
272 script->AI_TEMP_STATE = AI_STATE_SENTINEL_LOITER_INIT;
273 }
274 }
275}
#define sin_deg
@ EMOTE_EXCLAMATION
Definition enums.h:495
@ SOUND_AI_ALERT_A
Definition enums.h:1078
@ SOUND_PARAM_MORE_QUIET
Definition enums.h:1746
void ai_enemy_play_sound(Npc *npc, s32 arg1, s32 arg2)
Definition 23680.c:543
f32 alertOffsetDist
Definition npc.h:97
s32 playerSearchInterval
Definition npc.h:98
f32 alertRadius
Definition npc.h:96