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

Go to the source code of this file.

Macros

#define PAL_ANIM_END   0xFF
 
#define RGBA_BUF_SIZE   20
 

Enumerations

enum  PalSwapState { PAL_SWAP_HOLD_A = 0 , PAL_SWAP_A_TO_B = 1 , PAL_SWAP_HOLD_B = 2 , PAL_SWAP_B_TO_A = 3 }
 
enum  { WATT_DEFAULT = 0 , WATT_BRIGHTEST = 1 , WATT_BRIGHTER = 2 }
 

Functions

void STUB_npc_callback (Npc *npc)
 The default Npc::onUpdate and Npc::onRender callback.
 
void mtx_ident_mirror_y (Matrix4f mtx)
 
void clear_npcs (void)
 
void init_npc_list (void)
 Points the current NPC list to the world or battle lists depending on game state.
 
s32 create_npc_impl (NpcBlueprint *blueprint, AnimID *animList, s32 isPeachNpc)
 
s32 create_basic_npc (NpcBlueprint *blueprint)
 
s32 create_standard_npc (NpcBlueprint *blueprint, AnimID *animList)
 
s32 create_peach_npc (NpcBlueprint *blueprint)
 
void free_npc_by_index (s32 listIndex)
 
void free_npc (Npc *npc)
 
Npcget_npc_by_index (s32 listIndex)
 
void npc_do_world_collision (Npc *npc)
 
void npc_do_other_npc_collision (Npc *npc)
 
s32 npc_do_player_collision (Npc *npc)
 
void npc_try_apply_gravity (Npc *npc)
 
s32 npc_try_snap_to_ground (Npc *npc, f32 velocity)
 
void update_npcs (void)
 Updates all NPCs.
 
f32 npc_get_render_yaw (Npc *npc)
 
void appendGfx_npc (void *data)
 
void render_npcs (void)
 Renders all NPCs.
 
void npc_move_heading (Npc *npc, f32 speed, f32 yaw)
 
Npcget_npc_unsafe (s32 npcID)
 
Npcget_npc_safe (s32 npcID)
 
void enable_npc_shadow (Npc *npc)
 
void disable_npc_shadow (Npc *npc)
 
void set_npc_sprite (Npc *npc, s32 anim, AnimID *extraAnimList)
 
void enable_npc_blur (Npc *npc)
 
void disable_npc_blur (Npc *npc)
 
void update_npc_blur (Npc *npc)
 
void appendGfx_npc_blur (void *data)
 
void npc_enable_collisions (void)
 
void npc_disable_collisions (void)
 
void func_8003B1A8 (void)
 
void npc_reload_all (void)
 
void set_npc_yaw (Npc *npc, f32 yaw)
 
void npc_set_palswap_mode_A (Npc *npc, s32 mode)
 
void npc_set_palswap_mode_B (Npc *npc, s32 mode)
 
void npc_revert_palswap_mode (Npc *npc)
 
void npc_set_palswap_1 (Npc *npc, s32 palIndexA, s32 palIndexB, s32 timeHoldA, s32 timeAB)
 
void npc_set_palswap_2 (Npc *npc, s32 timeHoldB, s32 timeBA, s32 palIndexC, s32 palIndexD)
 
void npc_draw_with_palswap (Npc *npc, s32 yaw, Matrix4f mtx)
 
void npc_render_without_adjusted_palettes (Npc *npc, s32 arg1, Matrix4f mtx)
 
s32 npc_render_with_watt_idle_palettes (Npc *npc, s32 arg1, Matrix4f mtx)
 
u16 npc_blend_palette_colors (u16 colorA, u16 colorB, s32 lerpAlpha)
 
s32 npc_render_with_single_pal_blending (Npc *npc, s32 yaw, b32 hasDifferentIntervals, Matrix4f mtx)
 
s32 npc_render_with_double_pal_blending (Npc *npc, s32 yaw, Matrix4f mtx)
 
void npc_set_decoration (Npc *npc, s32 idx, s32 decorationType)
 
void npc_remove_decoration (Npc *npc, s32 idx)
 
s32 npc_update_decorations (Npc *npc)
 
void npc_reset_current_decoration (Npc *npc, s32 idx)
 
void npc_update_decoration_none (Npc *npc, s32 idx)
 
void npc_remove_decoration_none (Npc *npc, s32 idx)
 
void npc_update_decoration_bowser_aura (Npc *npc, s32 idx)
 
void npc_remove_decoration_bowser_aura (Npc *npc, s32 idx)
 
void npc_update_decoration_sweat (Npc *npc, s32 idx)
 
void npc_remove_decoration_sweat (Npc *npc, s32 idx)
 
void npc_update_decoration_seeing_stars (Npc *npc, s32 idx)
 
void npc_remove_decoration_seeing_stars (Npc *npc, s32 idx)
 
void npc_update_decoration_glow_in_front (Npc *npc, s32 idx)
 
void npc_remove_decoration_glow_in_front (Npc *npc, s32 idx)
 
void npc_update_decoration_glow_behind (Npc *npc, s32 idx)
 
void npc_remove_decoration_glow_behind (Npc *npc, s32 idx)
 
void npc_update_decoration_charged (Npc *npc, s32 idx)
 
void npc_remove_decoration_charged (Npc *npc, s32 idx)
 
Npcnpc_find_closest (f32 x, f32 y, f32 z, f32 radius)
 Finds the closest NPC to a given point within a radius.
 
Npcnpc_find_closest_simple (f32 x, f32 y, f32 z, f32 radius)
 Finds the closest simple-hitbox NPC to a given point within a radius.
 
s32 npc_find_standing_on_entity (s32 entityIndex)
 
s32 npc_get_collider_below (Npc *npc)
 
void npc_imgfx_update (Npc *npc)
 
void npc_set_imgfx_params (Npc *npc, s32 imgfxType, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6)
 
void COPY_set_defeated (s32 mapID, s32 encounterID)
 Duplicate of set_defeated().
 
void init_encounter_status (void)
 
void clear_encounter_status (void)
 
void func_8003E50C (void)
 
void func_8003E514 (s8 arg0)
 
void update_encounters (void)
 
void draw_encounter_ui (void)
 
void draw_first_strike_ui (void)
 
void npc_render_worker_do_nothing (void)
 
void make_npcs (s32 flags, s32 mapID, s32 *npcGroupList)
 
s32 kill_encounter (Enemy *enemy)
 
void kill_enemy (Enemy *enemy)
 
s32 bind_enemy_ai (Enemy *enemy, EvtScript *aiScriptBytecode)
 Binds the specified ai script to the specified enemy.
 
s32 bind_enemy_aux (Enemy *enemy, EvtScript *auxScriptBytecode)
 Binds the specified auxillary script to the specified enemy.
 
s32 bind_enemy_interact (Enemy *enemy, EvtScript *interactScriptBytecode)
 Binds the specified interact script to the specified enemy.
 
void bind_npc_ai (s32 npcID, EvtScript *npcAiBytecode)
 Binds the specified ai script to the npc matching the specified npcId.
 
void bind_npc_aux (s32 npcID, EvtScript *npcAuxBytecode)
 Binds the specified auxillary script to the npc matching the specified npcId.
 
void bind_npc_interact (s32 npcID, EvtScript *npcInteractBytecode)
 Binds the specified interact script to the npc matching the specified npcId.
 
Enemyget_enemy (s32 npcID)
 Looks for an enemy matching the specified npcID.
 
Enemyget_enemy_safe (s32 npcID)
 Same as get_enemy(), with the exception of always returning a value if an enemy is not found.
 

Variables

s16 gNpcCount
 
u8 wWattIdlePalettesAnim []
 

Macro Definition Documentation

◆ PAL_ANIM_END

#define PAL_ANIM_END   0xFF

Definition at line 16 of file npc.c.

◆ RGBA_BUF_SIZE

#define RGBA_BUF_SIZE   20

Enumeration Type Documentation

◆ PalSwapState

Enumerator
PAL_SWAP_HOLD_A 
PAL_SWAP_A_TO_B 
PAL_SWAP_HOLD_B 
PAL_SWAP_B_TO_A 

Definition at line 18 of file npc.c.

18 {
23};
@ PAL_SWAP_HOLD_A
Definition npc.c:19
@ PAL_SWAP_HOLD_B
Definition npc.c:21
@ PAL_SWAP_B_TO_A
Definition npc.c:22
@ PAL_SWAP_A_TO_B
Definition npc.c:20

◆ anonymous enum

anonymous enum
Enumerator
WATT_DEFAULT 
WATT_BRIGHTEST 
WATT_BRIGHTER 

Definition at line 26 of file npc.c.

26 {
27 WATT_DEFAULT = 0,
29 WATT_BRIGHTER = 2,
30};
@ WATT_BRIGHTER
Definition npc.c:29
@ WATT_DEFAULT
Definition npc.c:27
@ WATT_BRIGHTEST
Definition npc.c:28

Function Documentation

◆ STUB_npc_callback()

void STUB_npc_callback ( Npc * npc)

The default Npc::onUpdate and Npc::onRender callback.

Definition at line 49 of file npc.c.

49 {
50}

Referenced by create_npc_impl().

◆ mtx_ident_mirror_y()

void mtx_ident_mirror_y ( Matrix4f mtx)

Definition at line 52 of file npc.c.

52 {
53 guMtxIdentF(mtx);
54 mtx[0][0] = 1.0f;
55 mtx[1][1] = -1.0f;
56 mtx[2][2] = 1.0f;
57 mtx[3][3] = 1.0f;
58}

Referenced by appendGfx_npc().

◆ clear_npcs()

void clear_npcs ( void )

Definition at line 60 of file npc.c.

60 {
61 s32 i;
62
64 gCurrentNpcListPtr = &gWorldNpcList;
65 } else {
66 gCurrentNpcListPtr = &gBattleNpcList;
67 }
68
69 for (i = 0; i < MAX_NPCS; i++) {
70 (*gCurrentNpcListPtr)[i] = NULL;
71 }
72
73 gNpcCount = 0;
74 gNpcPlayerCollisionsEnabled = TRUE;
75}
@ CONTEXT_WORLD
Definition enums.h:3528
s16 gNpcCount
Definition npc.c:10
#define MAX_NPCS
Definition macros.h:91
GameStatus * gGameStatusPtr
Definition main_loop.c:32

Referenced by load_demo_battle(), load_engine_data(), load_map_by_IDs(), state_init_logos(), state_init_title_screen(), state_step_battle(), state_step_demo(), state_step_intro(), state_step_pause(), state_step_startup(), and state_step_title_screen().

◆ init_npc_list()

void init_npc_list ( void )

Points the current NPC list to the world or battle lists depending on game state.

Definition at line 77 of file npc.c.

77 {
79 gCurrentNpcListPtr = &gWorldNpcList;
80 } else {
81 gCurrentNpcListPtr = &gBattleNpcList;
82 }
83
84 gNpcCount = 0;
85 gNpcPlayerCollisionsEnabled = TRUE;
86}

Referenced by state_step_end_battle(), and state_step_unpause().

◆ create_npc_impl()

s32 create_npc_impl ( NpcBlueprint * blueprint,
AnimID * animList,
s32 isPeachNpc )

Definition at line 88 of file npc.c.

88 {
89 Npc* npc;
90 s32 i;
91 s32 j;
92
93 for (i = 0; i < MAX_NPCS; i++) {
94 if ((*gCurrentNpcListPtr)[i] == NULL) {
95 break;
96 }
97 }
98 ASSERT(i < MAX_NPCS);
99
100 (*gCurrentNpcListPtr)[i] = npc = heap_malloc(sizeof(*npc));
101 gNpcCount++;
102 ASSERT(npc != NULL);
103
105 if (isPeachNpc) {
107 }
108
109 npc->collisionDiameter = 32;
110 npc->collisionHeight = 64;
111 npc->renderMode = 13;
112 npc->blur.any = NULL;
113 npc->yaw = 0.0f;
114 npc->jumpVel = 0.0f;
115 npc->pos.x = 0.0f;
116 npc->pos.y = 0.0f;
117 npc->pos.z = 0.0f;
118 npc->colliderPos.x = 0.0f;
119 npc->colliderPos.y = 0.0f;
120 npc->colliderPos.z = 0.0f;
121 npc->rotPivotOffsetY = 0.0f;
122 npc->rot.x = 0.0f;
123 npc->rot.y = 0.0f;
124 npc->rot.z = 0.0f;
125 npc->homePos.x = 0.0f;
126 npc->homePos.y = 0.0f;
127 npc->homePos.z = 0.0f;
128 npc->unk_96 = 0; // TODO: fix
129 npc->verticalRenderOffset = 0;
130 npc->alpha = 255;
131 npc->hideAlpha = 255;
132 npc->jumpScale = 1.0f;
133 npc->moveSpeed = 4.0f;
134 npc->scale.x = 1.0f;
135 npc->scale.y = 1.0f;
136 npc->scale.z = 1.0f;
137 npc->curAnim = blueprint->initialAnim;
138 npc->animationSpeed = 1.0f;
139 npc->renderYaw = 0.0f;
140 npc->imgfxType = IMGFX_CLEAR;
141 npc->imgfxFlags = 0;
143 npc->isFacingAway = FALSE;
144 npc->yawCamOffset = 0;
146 npc->curFloor = NO_COLLIDER;
147 npc->curWall = NO_COLLIDER;
150 npc->screenSpaceOffset2D[0] = 0.0f;
151 npc->screenSpaceOffset2D[1] = 0.0f;
152 npc->verticalStretch = 1.0f;
153
154 for (j = 0; j < ARRAY_COUNT(npc->decorations); j++) {
155 npc->decorations[j] = 0;
156 npc->decorationType[j] = 0;
157 }
158
159 npc->onUpdate = blueprint->onUpdate;
160 if (npc->onUpdate == NULL) {
162 }
163
164 npc->onRender = blueprint->onRender;
165 if (npc->onRender == NULL) {
167 }
168 if (!isPeachNpc) {
169 npc->extraAnimList = animList;
170 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE)) {
171 if (!(npc->flags & NPC_FLAG_PARTNER)) {
172 npc->spriteInstanceID = spr_load_npc_sprite(npc->curAnim, animList);
173 } else {
175 }
176 } else {
178 }
179 }
180
182 npc->shadowScale = 1.0f;
183
186 }
187 return i;
188}
#define ASSERT(condition)
@ IMGFX_CLEAR
Definition enums.h:5116
@ NPC_PAL_ADJUST_NONE
Definition enums.h:1928
@ SHADOW_VARYING_CIRCLE
Definition enums.h:2535
@ COLLIDER_FLAG_IGNORE_NPC
Definition enums.h:4696
@ NPC_FLAG_HAS_NO_SPRITE
Definition enums.h:3022
@ NPC_FLAG_HAS_SHADOW
Definition enums.h:3002
@ NPC_FLAG_ENABLED
Definition enums.h:2998
@ NPC_FLAG_TOUCHES_GROUND
Definition enums.h:3020
@ NPC_FLAG_DIRTY_SHADOW
Definition enums.h:3014
@ NPC_FLAG_PARTNER
Definition enums.h:3024
@ NPC_FLAG_INVISIBLE
Definition enums.h:2999
@ NPC_FLAG_NO_ANIMS_LOADED
Definition enums.h:3028
s32 create_shadow_type(s32 type, f32 x, f32 y, f32 z)
Definition entity.c:1528
void * heap_malloc(s32 size)
Definition heap.c:34
void STUB_npc_callback(Npc *npc)
The default Npc::onUpdate and Npc::onRender callback.
Definition npc.c:49
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define BATTLE_NPC_ID_BIT
Definition macros.h:149
#define NO_COLLIDER
Definition macros.h:160
s32 spr_load_npc_sprite(s32 animID, u32 *extraAnimList)
Definition sprite.c:1025
@ SPRITE_ID_TAIL_ALLOCATE
Definition sprite.h:14
void(* onRender)(struct Npc *)
Definition npc.h:89
void(* onUpdate)(struct Npc *)
Definition npc.h:88
s32 initialAnim
Definition npc.h:87
s32 flags
Definition npc.h:86
struct EffectInstance * decorations[2]
s16 collisionDiameter
void(* onUpdate)(struct Npc *)
Run before anything else for this NPC in update_npcs()
f32 jumpScale
Vec3f scale
f32 jumpVel
f32 animationSpeed
s8 renderMode
s16 unk_96
s16 imgfxType
s32 flags
f32 renderYaw
s8 decorationType[2]
s32 spriteInstanceID
AnimID curAnim
s8 palSwapType
f32 shadowScale
u8 hideAlpha
Used when hiding NPCs; Multiplied with Npc::alpha.
f32 screenSpaceOffset2D[2]
s32 collisionChannel
b16 isFacingAway
Vec3f colliderPos
s16 collisionHeight
s16 turnAroundYawAdjustment
Vec3f rot
s8 verticalRenderOffset
s16 yawCamOffset
u16 imgfxFlags
s8 palSwapPrevType
Vec3f pos
f32 verticalStretch
AnimID * extraAnimList
s16 curFloor
f32 rotPivotOffsetY
f32 moveSpeed
Vec3s homePos
union Npc::@0 blur
s16 curWall
s32 shadowIndex
void(* onRender)(struct Npc *)
Run after the display list for this NPC is built.

Referenced by create_basic_npc(), create_peach_npc(), and create_standard_npc().

◆ create_basic_npc()

s32 create_basic_npc ( NpcBlueprint * blueprint)

Definition at line 190 of file npc.c.

190 {
191 return create_npc_impl(blueprint, NULL, FALSE);
192}
s32 create_npc_impl(NpcBlueprint *blueprint, AnimID *animList, s32 isPeachNpc)
Definition npc.c:88

Referenced by create_partner_npc().

◆ create_standard_npc()

s32 create_standard_npc ( NpcBlueprint * blueprint,
AnimID * animList )

Definition at line 194 of file npc.c.

194 {
195 return create_npc_impl(blueprint, animList, FALSE);
196}

Referenced by create_encounters(), and peach_make_disguise_npc().

◆ create_peach_npc()

s32 create_peach_npc ( NpcBlueprint * blueprint)

Definition at line 198 of file npc.c.

198 {
199 return create_npc_impl(blueprint, NULL, TRUE);
200}

Referenced by create_encounters().

◆ free_npc_by_index()

void free_npc_by_index ( s32 listIndex)

Definition at line 202 of file npc.c.

202 {
203 Npc* npc;
204 s32 i;
205
206 listIndex &= ~BATTLE_NPC_ID_BIT;
207
208 npc = (*gCurrentNpcListPtr)[listIndex];
209 if (npc != NULL) {
210 if (npc->flags) {
211 if (npc->blur.any != NULL) {
212 heap_free(npc->blur.any);
213 npc->blur.any = NULL;
214 }
215
216 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
218 }
219
221
222 for (i = 0; i < MAX_NPC_DECORATIONS; i++) {
223 npc_remove_decoration(npc, i);
224 }
225
226 if (npc->flags & NPC_FLAG_MOTION_BLUR) {
227 disable_npc_blur(npc);
228 }
229
230 heap_free((*gCurrentNpcListPtr)[listIndex]);
231 (*gCurrentNpcListPtr)[listIndex] = NULL;
232 gNpcCount--;
233 }
234 }
235}
#define MAX_NPC_DECORATIONS
@ NPC_FLAG_MOTION_BLUR
Definition enums.h:3018
s32 heap_free(void *ptr)
Definition heap.c:42
void delete_shadow(s32)
Definition entity.c:626
void disable_npc_blur(Npc *npc)
Definition npc.c:1087
void npc_remove_decoration(Npc *npc, s32 idx)
Definition npc.c:1740
s32 spr_free_sprite(s32 spriteInstanceID)
Definition sprite.c:1177

Referenced by action_update_parasol(), partner_free_npc(), and peach_force_disguise_action().

◆ free_npc()

void free_npc ( Npc * npc)

Definition at line 237 of file npc.c.

237 {
238 s32 i;
239
240 if (npc->blur.any != NULL) {
241 heap_free(npc->blur.any);
242 npc->blur.any = NULL;
243 }
244
245 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
247 }
248
250
251 for (i = 0; i < MAX_NPC_DECORATIONS; i++) {
252 npc_remove_decoration(npc, i);
253 }
254
255 if (npc->flags & NPC_FLAG_MOTION_BLUR) {
256 disable_npc_blur(npc);
257 }
258
259 heap_free(npc);
260
261 for (i = 0; i < MAX_NPCS; i++) {
262 if ((*gCurrentNpcListPtr)[i] == npc) {
263 break;
264 }
265 }
266
267 (*gCurrentNpcListPtr)[i] = NULL;
268 gNpcCount--;
269}

Referenced by kill_enemy().

◆ get_npc_by_index()

Npc * get_npc_by_index ( s32 listIndex)

◆ npc_do_world_collision()

void npc_do_world_collision ( Npc * npc)

Definition at line 278 of file npc.c.

278 {
279 f32 testAngle;
280 s32 hit;
281 f32 testX;
282 f32 testY;
283 f32 testZ;
284
287 } else if (
288 (npc->pos.x != npc->colliderPos.x)
289 || (npc->pos.y != npc->colliderPos.y)
290 || (npc->pos.z != npc->colliderPos.z)
292 ) {
293 npc->flags &= ~NPC_FLAG_WORLD_COLLISION_DIRTY;
294 testAngle = clamp_angle(npc->yaw);
295 testX = npc->pos.x;
296 testY = npc->pos.y;
297 testZ = npc->pos.z;
298
299 if (!(npc->flags & NPC_FLAG_PARTNER)) {
300 hit = npc_test_move_simple_with_slipping(npc->collisionChannel, &testX, &testY, &testZ, 0, testAngle, npc->collisionHeight, npc->collisionDiameter);
301 } else {
302 hit = npc_test_move_complex_with_slipping(npc->collisionChannel, &testX, &testY, &testZ, 0, testAngle, npc->collisionHeight, npc->collisionDiameter);
303 }
304
305 if (hit) {
308 npc->pos.x = testX;
309 npc->pos.z = testZ;
310 } else {
312 }
313
314 testAngle = clamp_angle(npc->yaw + 45.0f);
315 testX = npc->pos.x;
316 testY = npc->pos.y;
317 testZ = npc->pos.z;
318
319 if (!(npc->flags & NPC_FLAG_PARTNER)) {
320 hit = npc_test_move_simple_with_slipping(npc->collisionChannel, &testX, &testY, &testZ, 0, testAngle, npc->collisionHeight, npc->collisionDiameter);
321 } else {
322 hit = npc_test_move_taller_with_slipping(npc->collisionChannel, &testX, &testY, &testZ, 0, testAngle, npc->collisionHeight, npc->collisionDiameter);
323 }
324
325 if (hit) {
327 npc->pos.x = testX;
328 npc->pos.z = testZ;
329 } else {
330 npc->flags &= ~NPC_FLAG_COLLDING_WITH_WORLD;
331 }
332
333 testAngle = clamp_angle(npc->yaw - 45.0f);
334 testX = npc->pos.x;
335 testY = npc->pos.y;
336 testZ = npc->pos.z;
337 if (!(npc->flags & NPC_FLAG_PARTNER)) {
338 hit = npc_test_move_simple_with_slipping(npc->collisionChannel, &testX, &testY, &testZ, 0, testAngle, npc->collisionHeight, npc->collisionDiameter);
339 } else {
340 hit = npc_test_move_taller_with_slipping(npc->collisionChannel, &testX, &testY, &testZ, 0, testAngle, npc->collisionHeight, npc->collisionDiameter);
341 }
342
343 if (hit != 0) {
345 npc->pos.x = testX;
346 npc->pos.z = testZ;
347 } else {
348 npc->flags &= ~NPC_FLAG_COLLDING_WITH_WORLD;
349 }
350
351 if (npc->flags & NPC_FLAG_PARTNER) {
352 testAngle = clamp_angle(npc->yaw + 45.0f + 180.0f);
353 testX = npc->pos.x;
354 testY = npc->pos.y;
355 testZ = npc->pos.z;
356 if (npc_test_move_simple_with_slipping(npc->collisionChannel, &testX, &testY, &testZ, 0, testAngle, npc->collisionHeight,
357 npc->collisionDiameter) != 0) {
359 npc->pos.x = testX;
360 npc->pos.z = testZ;
361 } else {
362 npc->flags &= ~NPC_FLAG_COLLDING_WITH_WORLD;
363 }
364
365 testAngle = clamp_angle((npc->yaw - 45.0f) + 180.0f);
366 testX = npc->pos.x;
367 testY = npc->pos.y;
368 testZ = npc->pos.z;
369 if (npc_test_move_simple_with_slipping(npc->collisionChannel, &testX, &testY, &testZ, 0, testAngle, npc->collisionHeight,
370 npc->collisionDiameter) != 0) {
372 npc->pos.x = testX;
373 npc->pos.z = testZ;
374 return;
375 }
376 npc->flags &= ~NPC_FLAG_COLLDING_WITH_WORLD;
377 }
378 }
379}
#define clamp_angle
@ NPC_FLAG_WORLD_COLLISION_DIRTY
Definition enums.h:3025
@ NPC_FLAG_IGNORE_WORLD_COLLISION
Definition enums.h:3004
@ NPC_FLAG_COLLDING_FORWARD_WITH_WORLD
Definition enums.h:3012
@ NPC_FLAG_COLLDING_WITH_WORLD
Definition enums.h:3011
s32 npc_test_move_complex_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
b32 npc_test_move_simple_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
b32 npc_test_move_taller_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
s32 NpcHitQueryColliderID

Referenced by partner_get_out(), partner_move_to_goal(), and update_npcs().

◆ npc_do_other_npc_collision()

void npc_do_other_npc_collision ( Npc * npc)

Definition at line 381 of file npc.c.

381 {
382 Npc* otherNpc;
383 f32 angle;
384 f32 thisX, thisY, thisZ;
385 f32 thisBuf;
386 f32 otherX, otherZ;
387 f32 otherBuf;
388 f32 xDiff, zDiff;
389 f32 dist;
390 s32 collision;
391 s32 i;
392
394 npc->flags &= ~NPC_FLAG_COLLIDING_WITH_NPC;
395 thisBuf = npc->collisionDiameter * 0.5f;
396 thisX = npc->pos.x;
397 thisY = npc->pos.y;
398 thisZ = npc->pos.z;
399
400 for (i = 0; i < MAX_NPCS; i++) {
401 otherNpc = get_npc_by_index(i);
402 if (otherNpc != NULL && npc != otherNpc) {
403 if (otherNpc->flags != 0 && !(otherNpc->flags & (NPC_FLAG_SUSPENDED | NPC_FLAG_IGNORE_PLAYER_COLLISION))) {
404 if (!(otherNpc->pos.y + otherNpc->collisionHeight < thisY) &&
405 !(thisY + npc->collisionHeight < otherNpc->pos.y))
406 {
407 otherX = otherNpc->pos.x;
408 xDiff = otherX - thisX;
409 otherZ = otherNpc->pos.z;
410 zDiff = otherZ - thisZ;
411 otherBuf = otherNpc->collisionDiameter * 0.5f;
412 dist = sqrtf(SQ(xDiff) + SQ(zDiff));
413
414 if (!(thisBuf + otherBuf <= dist)) {
415 collision = FALSE;
416 if (npc->flags & NPC_FLAG_PARTNER) {
418 } else if (!(otherNpc->flags & NPC_FLAG_PARTNER) ||
420 {
421 collision = TRUE;
422 }
423
424 if (collision) {
425 angle = DEG_TO_RAD(atan2(otherX, otherZ, thisX, thisZ));
426 dist = (thisBuf + otherBuf) - dist;
427 xDiff = dist * sin_rad(angle);
428 zDiff = -dist * cos_rad(angle);
429 thisX += xDiff * 0.1f;
430 thisZ += zDiff * 0.1f;
431 }
433 }
434 }
435 }
436 }
437 }
438 npc->pos.x = thisX;
439 npc->pos.z = thisZ;
440 }
441}
#define sqrtf
#define atan2
@ PARTNER_ACTION_NONE
Definition enums.h:2932
@ NPC_FLAG_SUSPENDED
Definition enums.h:3029
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:3006
@ NPC_FLAG_COLLIDING_WITH_NPC
Definition enums.h:3023
f32 cos_rad(f32 x)
Definition 43F0.c:716
f32 sin_rad(f32 x)
Definition 43F0.c:712
Npc * get_npc_by_index(s32 listIndex)
Definition npc.c:271
#define DEG_TO_RAD(deg)
Definition macros.h:138
#define SQ(x)
Definition macros.h:170
PartnerStatus gPartnerStatus
Definition partners.c:42

Referenced by update_npcs().

◆ npc_do_player_collision()

s32 npc_do_player_collision ( Npc * npc)
Returns
TRUE if a collision occurred

Definition at line 443 of file npc.c.

443 {
444 PlayerStatus* playerStatus = &gPlayerStatus;
445 f32 playerX, playerZ;
446 f32 playerYaw, yaw;
447 f32 npcX, npcZ;
448 f32 dist, colDist, distToNpc;
449 f32 npcColRadius, playerColRadius;
450 f32 deltaX, deltaZ;
451
453 return FALSE;
454 }
455
456 if (npc->flags & NPC_FLAG_PARTNER) {
457 return FALSE;
458 }
459
460 if (!gNpcPlayerCollisionsEnabled) {
461 return FALSE;
462 }
463
464 if (playerStatus->pos.y + playerStatus->colliderHeight < npc->pos.y) {
465 return FALSE;
466 }
467
468 if (npc->pos.y + npc->collisionHeight < playerStatus->pos.y) {
469 return FALSE;
470 }
471
472 playerX = playerStatus->pos.x;
473 playerZ = playerStatus->pos.z;
474
475 npcColRadius = npc->collisionDiameter / 2;
476 playerColRadius = playerStatus->colliderDiameter / 2;
477
478 npcX = npc->pos.x;
479 npcZ = npc->pos.z;
480
481 deltaX = playerX - npcX;
482 deltaZ = playerZ - npcZ;
483
484 distToNpc = sqrtf(SQ(deltaX) + SQ(deltaZ));
485 colDist = npcColRadius + playerColRadius;
486 if (colDist < distToNpc) {
487 return FALSE;
488 }
489
490 playerStatus->animFlags |= PA_FLAG_NPC_COLLIDED;
491
492 npcX = npc->colliderPos.x;
493 npcZ = npc->colliderPos.z;
494
495 deltaX = playerX - npcX;
496 deltaZ = playerZ - npcZ;
497
498 dist = sqrtf(SQ(deltaX) + SQ(deltaZ));
499 yaw = atan2(playerX, playerZ, npcX, npcZ);
500
501 playerYaw = playerStatus->targetYaw;
502 dist = colDist - dist;
503 deltaX = dist * sin_rad(DEG_TO_RAD(yaw));
504 deltaZ = -dist * cos_rad(DEG_TO_RAD(yaw));
505
506 if (playerStatus->animFlags & PA_FLAG_RIDING_PARTNER) {
507 if (fabsf(get_clamped_angle_diff(yaw, playerYaw)) < 45.0f) {
508 playerStatus->pos.x -= deltaX;
509 playerStatus->pos.z -= deltaZ;
510 wPartnerNpc->pos.x -= deltaX;
511 wPartnerNpc->pos.z -= deltaZ;
512 } else {
513 playerStatus->pos.x -= deltaX * 0.5f;
514 playerStatus->pos.z -= deltaZ * 0.5f;
515 wPartnerNpc->pos.x -= deltaX * 0.5f;
516 wPartnerNpc->pos.z -= deltaZ * 0.5f;
517 }
518 } else {
519 if (playerStatus->flags & (PS_FLAG_JUMPING | PS_FLAG_FALLING)) {
520 playerStatus->pos.x -= deltaX * 0.4f;
521 playerStatus->pos.z -= deltaZ * 0.4f;
522 } else {
523 dist = get_clamped_angle_diff(yaw, playerYaw); // required to match
524 if (fabsf(dist) < 45.0f) {
525 playerStatus->pos.x -= deltaX;
526 playerStatus->pos.z -= deltaZ;
527 } else {
528 playerStatus->pos.x -= deltaX * 0.5f;
529 playerStatus->pos.z -= deltaZ * 0.5f;
530 }
531 }
532 }
533 npc->pos.x = npc->colliderPos.x;
534 npc->pos.y = npc->colliderPos.y;
535 npc->pos.z = npc->colliderPos.z;
536 return TRUE;
537}
@ PS_FLAG_FALLING
Definition enums.h:3036
@ PS_FLAG_JUMPING
Definition enums.h:3035
@ PA_FLAG_NPC_COLLIDED
Definition enums.h:3106
@ PA_FLAG_RIDING_PARTNER
Definition enums.h:3116
f32 fabsf(f32 f)
f32 get_clamped_angle_diff(f32, f32)
Definition 43F0.c:605
Npc * wPartnerNpc
Definition partners.c:43
PlayerStatus gPlayerStatus
Definition 77480.c:39

Referenced by update_npcs().

◆ npc_try_apply_gravity()

void npc_try_apply_gravity ( Npc * npc)

Definition at line 541 of file npc.c.

541 {
542 f32 x, y, z, testLength;
543 f32 length;
544 s32 hitID;
545
546 if (!(npc->flags & NPC_FLAG_GRAVITY)) {
547 return;
548 }
549
550 if (npc->flags & NPC_FLAG_JUMPING) {
551 npc->flags &= ~NPC_FLAG_GROUNDED;
552 return;
553 }
554
555 npc->jumpScale = 1.0f;
556 npc->jumpVel -= npc->jumpScale;
557 npc->pos.y += npc->jumpVel;
558
559 x = npc->pos.x;
560 y = npc->pos.y + 13;
561 z = npc->pos.z;
562 testLength = length = fabsf(npc->jumpVel) + 16;
563
564 if (!(npc->flags & NPC_FLAG_PARTNER)) {
565 hitID = npc_raycast_down_sides(npc->collisionChannel, &x, &y, &z, &length);
566 } else {
567 hitID = npc_raycast_down_around(npc->collisionChannel, &x, &y, &z, &length, npc->yaw, npc->collisionDiameter);
568 }
569
570 if (hitID && length <= testLength) {
571 npc->jumpVel = 0.0f;
572 npc->flags |= NPC_FLAG_GROUNDED;
573 npc->pos.y = y;
575 } else {
576 npc->flags &= ~NPC_FLAG_GROUNDED;
577 }
578}
#define npc_raycast_down_sides
@ NPC_FLAG_JUMPING
Definition enums.h:3009
@ NPC_FLAG_GRAVITY
Definition enums.h:3007
@ NPC_FLAG_GROUNDED
Definition enums.h:3010
b32 npc_raycast_down_around(s32, f32 *, f32 *, f32 *, f32 *, f32, f32)

Referenced by update_npcs().

◆ npc_try_snap_to_ground()

s32 npc_try_snap_to_ground ( Npc * npc,
f32 velocity )

Definition at line 581 of file npc.c.

581 {
582 f32 x, y, z, testLength;
583 f32 length;
584 s32 hitID;
585
586 if (npc->flags & (NPC_FLAG_GRAVITY | NPC_FLAG_FLYING)) {
587 return FALSE;
588 }
589
590 if (npc->flags & NPC_FLAG_JUMPING) {
591 npc->flags &= ~NPC_FLAG_GROUNDED;
592 return FALSE;
593 }
594
595 length = testLength = fabsf(velocity) + 16;
596 x = npc->pos.x;
597 y = npc->pos.y + 13;
598 z = npc->pos.z;
599
600 if (!(npc->flags & NPC_FLAG_PARTNER)) {
601 hitID = npc_raycast_down_sides(npc->collisionChannel, &x, &y, &z, &length);
602 } else {
603 hitID = npc_raycast_down_around(npc->collisionChannel, &x, &y, &z, &length, npc->yaw, npc->collisionDiameter);
604 }
605
606 if (hitID != 0 && length <= testLength) {
607 npc->pos.y = y;
609 npc->flags |= NPC_FLAG_GROUNDED;
610 return TRUE;
611 }
612
613 npc->flags &= ~NPC_FLAG_GROUNDED;
614 return FALSE;
615}
@ NPC_FLAG_FLYING
Definition enums.h:3001

Referenced by partner_get_out(), and update_npcs().

◆ update_npcs()

void update_npcs ( void )

Updates all NPCs.

Definition at line 617 of file npc.c.

617 {
618 PlayerStatus* playerStatus = &gPlayerStatus;
619 f32 x, y, z;
620 f32 hitYaw, hitPitch, hitLength;
621
622 playerStatus->animFlags &= ~PA_FLAG_NPC_COLLIDED;
624 s32 i;
625
626 for (i = 0; i < MAX_NPCS; i++) {
627 Npc* npc = (*gCurrentNpcListPtr)[i];
628
629 if (npc != NULL) {
630 if (npc->flags != 0) {
633 continue;
634 }
635
636 npc->onUpdate(npc);
639 } else {
640 npc->collisionChannel &= ~COLLISION_IGNORE_ENTITIES;
641 }
642
643 npc->curFloor = NO_COLLIDER;
644 npc->curWall = NO_COLLIDER;
646
649 npc_try_snap_to_ground(npc, 0.0f);
652
653 if (npc->flags & NPC_FLAG_MOTION_BLUR) {
654 update_npc_blur(npc);
655 }
656
657 if ((npc->pos.y < -2000.0f) && !(npc->flags & NPC_FLAG_PARTNER)) {
658 npc->pos.y = playerStatus->pos.y;
659 npc->jumpVel = 0.0f;
660 npc->moveSpeed = 0.0f;
661 npc->jumpScale = 0.0f;
662 npc->flags &= ~NPC_FLAG_JUMPING;
663 }
664
665 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
666 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE)) {
667 if (npc->curAnim != 0) {
668 if (npc->spriteInstanceID >= 0) {
670 }
671 }
672 }
673 } else {
675 }
676
677 if (npc->flags & NPC_FLAG_HAS_SHADOW) {
678 Shadow* shadow = get_shadow_by_index(npc->shadowIndex);
679 EntityModel* entityModel = get_entity_model(shadow->entityModelID);
680
681 entityModel->flags &= ~ENTITY_MODEL_FLAG_REFLECT;
682 if (npc->flags & NPC_FLAG_REFLECT_WALL) {
683 entityModel->flags |= ENTITY_MODEL_FLAG_REFLECT;
684 }
685
686 x = npc->pos.x;
687 y = npc->pos.y;
688 z = npc->pos.z;
689 if (!(npc->flags & NPC_FLAG_NO_SHADOW_RAYCAST)) {
690 if ( x != npc->colliderPos.x
691 || y != npc->colliderPos.y
692 || z != npc->colliderPos.z
693 || (npc->flags & NPC_FLAG_DIRTY_SHADOW)
694 ) {
695 x = npc->pos.x;
696 y = npc->pos.y + (npc->collisionHeight / 2);
697 z = npc->pos.z;
698 hitLength = 1000.0f;
699 entity_raycast_down(&x, &y, &z, &hitYaw, &hitPitch, &hitLength);
700 set_npc_shadow_scale(shadow, hitLength, npc->collisionDiameter);
701 shadow->pos.x = x;
702 shadow->pos.y = y;
703 shadow->pos.z = z;
704 shadow->rot.x = hitYaw;
705 shadow->rot.y = npc->renderYaw;
706 shadow->rot.z = hitPitch;
707 shadow->scale.x *= npc->shadowScale;
708 npc->flags &= ~NPC_FLAG_DIRTY_SHADOW;
709 }
710 } else {
712 shadow->pos.x = npc->pos.x;
713 shadow->pos.z = npc->pos.z;
714 } else {
715 shadow->pos.x = npc->pos.x;
716 shadow->pos.y = npc->pos.y;
717 shadow->pos.z = npc->pos.z;
718 }
719 }
720 }
721
722 npc->colliderPos.x = npc->pos.x;
723 npc->colliderPos.y = npc->pos.y;
724 npc->colliderPos.z = npc->pos.z;
726
727 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
728 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE)) {
729 if (npc->spriteInstanceID < 0) {
730 npc->spriteInstanceID++;
731 if (npc->spriteInstanceID == -1) {
733 ASSERT(npc->spriteInstanceID >= 0);
735 }
736 }
737 }
738 }
739 }
740 }
741 }
742 }
743}
s16 entityModelID
Vec3f scale
EntityModel * get_entity_model(s32 idx)
@ ENTITY_MODEL_FLAG_REFLECT
Definition enums.h:5018
@ COLLISION_IGNORE_ENTITIES
Definition enums.h:4697
@ GLOBAL_OVERRIDES_800
Definition enums.h:4329
@ GLOBAL_OVERRIDES_400
Definition enums.h:4328
@ NPC_FLAG_IGNORE_ENTITY_COLLISION
Definition enums.h:3013
@ NPC_FLAG_REFLECT_WALL
Definition enums.h:3015
@ NPC_FLAG_INACTIVE
Definition enums.h:3000
@ NPC_FLAG_NO_SHADOW_RAYCAST
Definition enums.h:3003
@ NPC_FLAG_DONT_UPDATE_SHADOW_Y
Definition enums.h:3008
b32 entity_raycast_down(f32 *, f32 *, f32 *, f32 *, f32 *, f32 *)
Mostly used for shadows.
Definition entity.c:1637
Shadow * get_shadow_by_index(s32 index)
Definition entity.c:534
void set_npc_shadow_scale(Shadow *shadow, f32 height, f32 npcRadius)
Definition entity.c:1687
s32 npc_try_snap_to_ground(Npc *npc, f32 velocity)
Definition npc.c:581
void npc_do_other_npc_collision(Npc *npc)
Definition npc.c:381
void npc_try_apply_gravity(Npc *npc)
Definition npc.c:541
s32 npc_update_decorations(Npc *npc)
Definition npc.c:1767
void npc_do_world_collision(Npc *npc)
Definition npc.c:278
s32 npc_do_player_collision(Npc *npc)
Definition npc.c:443
void update_npc_blur(Npc *npc)
Definition npc.c:1096
s32 spr_update_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale)
Definition sprite.c:1071
s32 spr_update_player_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale)
Definition sprite.c:823
@ PLAYER_SPRITE_AUX1
Definition sprite.h:27
s32 flags
Definition entity.h:448
s32 gOverrideFlags
Definition main_loop.c:11

Referenced by state_step_battle(), state_step_change_map(), state_step_enter_world(), state_step_game_over(), state_step_intro(), state_step_logos(), state_step_pause(), state_step_title_screen(), state_step_unpause(), and state_step_world().

◆ npc_get_render_yaw()

f32 npc_get_render_yaw ( Npc * npc)

Definition at line 745 of file npc.c.

745 {
746 Camera* camera = &gCameras[gCurrentCamID];
747 f32 cameraYaw;
748 f32 camRelativeYaw;
749 f32 yaw;
750 s32 direction;
751
753 cameraYaw = camera->curYaw;
754 camRelativeYaw = get_clamped_angle_diff(cameraYaw, npc->yaw);
755
756 if (camRelativeYaw < -5.0f && camRelativeYaw > -175.0f) {
757 direction = 0;
758 camRelativeYaw = 0.0f;
759 } else if (camRelativeYaw > 5.0f && camRelativeYaw < 175.0f) {
760 direction = 1;
761 camRelativeYaw = 180.0f;
762 } else {
763 // direction is close to flipping, use saved value
764 direction = 2;
765 camRelativeYaw = npc->yawCamOffset;
766 }
767
768 npc->yawCamOffset = yaw = clamp_angle(camRelativeYaw);
769
771 if (npc->isFacingAway != direction && direction != 2) {
772 npc->isFacingAway = direction;
773
774 if (npc->isFacingAway) {
775 npc->turnAroundYawAdjustment = 180;
776 } else {
777 npc->turnAroundYawAdjustment = -180;
778 }
779
780 if (fabsf(get_clamped_angle_diff(cameraYaw, npc->yaw)) >= 90.0f) {
782 }
783 }
784
785 if (npc->turnAroundYawAdjustment != 0) {
786 if (npc->turnAroundYawAdjustment < 0) {
787 npc->turnAroundYawAdjustment += 20;
788 }
789 if (npc->turnAroundYawAdjustment > 0) {
790 npc->turnAroundYawAdjustment -= 20;
791 }
792 }
793
794 if (npc->flags & NPC_FLAG_FLIP_INSTANTLY) {
796 }
797
798 npc->renderYaw = clamp_angle(clamp_angle(npc->turnAroundYawAdjustment + yaw) - cameraYaw);
799 yaw = npc->renderYaw;
800 } else {
801 yaw = npc->renderYaw;
802 }
803 } else {
804 yaw = npc->renderYaw;
805 }
806 return yaw;
807}
@ GLOBAL_OVERRIDES_PREV_400
Definition enums.h:4332
@ GLOBAL_OVERRIDES_PREV_800
Definition enums.h:4333
@ NPC_FLAG_FLIP_INSTANTLY
Definition enums.h:3019
@ NPC_FLAG_IGNORE_CAMERA_FOR_YAW
Definition enums.h:3016
Camera gCameras[4]
Definition cam_main.c:17
s16 gCurrentCamID
Definition cam_main.c:13

Referenced by appendGfx_npc().

◆ appendGfx_npc()

void appendGfx_npc ( void * data)

Definition at line 809 of file npc.c.

809 {
810 Npc* npc = data;
811 Matrix4f mtx1, mtx2;
812 f32 renderYaw = npc_get_render_yaw(npc);
813
814 guTranslateF(mtx1, npc->pos.x, npc->pos.y + npc->verticalRenderOffset, npc->pos.z);
815 if (npc->flags & NPC_FLAG_UPSIDE_DOWN) {
816 mtx_ident_mirror_y(mtx2);
817 guMtxCatF(mtx2, mtx1, mtx1);
818 }
819
820 if (npc->rotPivotOffsetY != 0.0f) {
821 guTranslateF(mtx2, 0.0f, npc->rotPivotOffsetY, 0.0f);
822 guMtxCatF(mtx2, mtx1, mtx1);
823 }
824
825 if (npc->rot.y != 0.0f) {
826 guRotateF(mtx2, npc->rot.y, 0.0f, 1.0f, 0.0f);
827 guMtxCatF(mtx2, mtx1, mtx1);
828 }
829
830 if (npc->rot.x != 0.0f) {
831 guRotateF(mtx2, npc->rot.x, 1.0f, 0.0f, 0.0f);
832 guMtxCatF(mtx2, mtx1, mtx1);
833 }
834
835 if (npc->rot.z != 0.0f) {
836 guRotateF(mtx2, npc->rot.z, 0.0f, 0.0f, 1.0f);
837 guMtxCatF(mtx2, mtx1, mtx1);
838 }
839
840 if (npc->rotPivotOffsetY != 0.0f) {
841 guTranslateF(mtx2, 0.0f, -npc->rotPivotOffsetY, 0.0f);
842 guMtxCatF(mtx2, mtx1, mtx1);
843 }
844
845 if ((npc->screenSpaceOffset2D[0] != 0.0f) || (npc->screenSpaceOffset2D[1] != 0.0f)) {
846 guTranslateF(mtx1, npc->screenSpaceOffset2D[0], npc->screenSpaceOffset2D[1], 0.0f);
847 guMtxCatF(mtx2, mtx1, mtx1);
848 }
849
850 if (npc->scale.x * SPRITE_WORLD_SCALE_D != 1.0f
851 || (npc->scale.y * npc->verticalStretch) * SPRITE_WORLD_SCALE_D != 1.0f
852 || npc->scale.z * SPRITE_WORLD_SCALE_D != 1.0f
853 ) {
856 guMtxCatF(mtx2, mtx1, mtx1);
857 }
858
859 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
860 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE) && (npc->curAnim != 0) && (npc->spriteInstanceID >= 0)) {
861 npc_draw_with_palswap(npc, renderYaw, mtx1);
863 }
864 } else {
865 npc_draw_with_palswap(npc, renderYaw, mtx1);
867 }
868
869 if (npc->flags & NPC_FLAG_REFLECT_WALL) {
870 guTranslateF(mtx1, npc->pos.x, npc->pos.y + npc->verticalRenderOffset, -npc->pos.z);
871 if (npc->flags & NPC_FLAG_UPSIDE_DOWN) {
872 mtx_ident_mirror_y(mtx2);
873 guMtxCatF(mtx2, mtx1, mtx1);
874 }
875 if ((npc->rot.y != 0.0f) || (npc->rot.x != 0.0f) || (npc->rot.z != 0.0f)) {
876 guRotateRPYF(mtx2, npc->rot.x, npc->rot.y, npc->rot.z);
877 guMtxCatF(mtx2, mtx1, mtx1);
878 }
879
880 if (npc->scale.x * SPRITE_WORLD_SCALE_D != 1.0f
881 || (npc->scale.y * npc->verticalStretch) * SPRITE_WORLD_SCALE_D != 1.0f
882 || npc->scale.z * SPRITE_WORLD_SCALE_D != 1.0f
883 ) {
884 guScaleF(mtx2,
888 guMtxCatF(mtx2, mtx1, mtx1);
889
890 }
891
892 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
893 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE) && (npc->curAnim != 0)) {
894 spr_draw_npc_sprite(npc->spriteInstanceID, renderYaw, 0, 0, mtx1);
895 }
896 } else {
898 }
899 }
900
901 if (npc->flags & NPC_FLAG_REFLECT_FLOOR) {
902 guTranslateF(mtx1, npc->pos.x, -(npc->pos.y + npc->verticalRenderOffset), npc->pos.z);
903 mtx_ident_mirror_y(mtx2);
904 guMtxCatF(mtx2, mtx1, mtx1);
905
906 if (npc->rot.y != 0.0f || npc->rot.x != 0.0f || npc->rot.z != 0.0f) {
907 guRotateRPYF(mtx2, npc->rot.x, npc->rot.y, npc->rot.z);
908 guMtxCatF(mtx2, mtx1, mtx1);
909 }
910
911 if (npc->scale.x * SPRITE_WORLD_SCALE_D != 1.0f
912 || (npc->scale.y * npc->verticalStretch) * SPRITE_WORLD_SCALE_D != 1.0f
913 || npc->scale.z * SPRITE_WORLD_SCALE_D != 1.0f
914 ) {
915 guScaleF(mtx2,
919 guMtxCatF(mtx2, mtx1, mtx1);
920 }
921 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
922 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE) && (npc->curAnim != 0)) {
923 spr_draw_npc_sprite(npc->spriteInstanceID, renderYaw, 0, 0, mtx1);
924 }
925 } else {
927 }
928 }
929 npc->onRender(npc);
930}
f32 Matrix4f[4][4]
#define guRotateF
#define guTranslateF
#define guMtxCatF
#define guScaleF
@ NPC_FLAG_UPSIDE_DOWN
Definition enums.h:3005
@ NPC_FLAG_REFLECT_FLOOR
Definition enums.h:3017
void npc_draw_with_palswap(Npc *npc, s32 yaw, Matrix4f mtx)
Definition npc.c:1300
void mtx_ident_mirror_y(Matrix4f mtx)
Definition npc.c:52
f32 npc_get_render_yaw(Npc *npc)
Definition npc.c:745
#define SPRITE_WORLD_SCALE_D
Definition macros.h:144
s32 spr_draw_npc_sprite(s32 spriteInstanceID, s32 yaw, s32 arg2, PAL_PTR *paletteList, Matrix4f mtx)
Definition sprite.c:1105
s32 spr_get_notify_value(s32 spriteIndex)
Definition sprite.c:1173
s32 func_802DDEC4(s32 spriteIdx)
Definition sprite.c:964
s32 spr_draw_player_sprite(s32 spriteInstanceID, s32 yaw, s32 alphaIn, PAL_PTR *paletteList, Matrix4f mtx)
Definition sprite.c:872
@ DRAW_SPRITE_OVERRIDE_YAW
Definition sprite.h:21
s32 animNotifyValue

Referenced by render_npcs().

◆ render_npcs()

void render_npcs ( void )

Renders all NPCs.

Definition at line 932 of file npc.c.

932 {
933 Npc* npc;
934 RenderTask renderTask;
935 RenderTask* renderTaskPtr = &renderTask;
937 f32 x, y, z, s;
938 f32 renderDist;
939 s32 i;
940
941 for (i = 0; i < MAX_NPCS; i++) {
942 Npc* npc = (*gCurrentNpcListPtr)[i];
943 if ((npc != NULL)
944 && (npc->flags != 0)
946 ) {
947 transform_point(cam->mtxPerspective, npc->pos.x, npc->pos.y, npc->pos.z, 1.0f, &x, &y, &z, &s);
948 if (!(s < 0.01) || !(s > -0.01)) {
949 renderDist = ((z * 5000.0f) / s) + 5000.0f;
950 if (renderDist < 0.0f) {
951 renderDist = 0.0f;
952 } else if (renderDist > 10000.0f) {
953 renderDist = 10000.0f;
954 }
955
956 renderTaskPtr->dist = -renderDist;
957 renderTaskPtr->appendGfxArg = npc;
958 renderTaskPtr->appendGfx = appendGfx_npc;
959 renderTaskPtr->renderMode = npc->renderMode;
960
961 if (npc->flags & NPC_FLAG_HIDING) {
962 u8 r, g, b, a;
963 mdl_get_shroud_tint_params(&r, &g, &b, &a);
964 npc->hideAlpha = 255 - a;
965 } else {
966 npc->hideAlpha = 255;
967 }
968
969 if (npc->hideAlpha != 0) {
970 queue_render_task(renderTaskPtr);
971 }
972
973 if (npc->flags & NPC_FLAG_MOTION_BLUR) {
974 renderTaskPtr->dist = -renderDist;
975 renderTaskPtr->appendGfx = appendGfx_npc_blur;
976 renderTaskPtr->appendGfxArg = npc;
978 queue_render_task(renderTaskPtr);
979 }
980 }
981 }
982 }
983}
#define transform_point
#define queue_render_task
#define mdl_get_shroud_tint_params
@ RENDER_MODE_SURFACE_XLU_LAYER1
Definition enums.h:3282
@ NPC_FLAG_HIDING
Definition enums.h:3021
void appendGfx_npc_blur(void *data)
Definition npc.c:1112
void appendGfx_npc(void *data)
Definition npc.c:809
Matrix4f mtxPerspective
void * appendGfxArg
void(* appendGfx)(void *)

Referenced by render_frame().

◆ npc_move_heading()

◆ get_npc_unsafe()

Npc * get_npc_unsafe ( s32 npcID)

Definition at line 994 of file npc.c.

994 {
995 s32 i;
996 Npc* npc;
997
998 for (i = 0; i < MAX_NPCS; i++) {
999 npc = (*gCurrentNpcListPtr)[i];
1000 if (npc != NULL && npc->flags != 0 && npc->npcID == npcID) {
1001 break;
1002 }
1003 }
1004 ASSERT(i < MAX_NPCS);
1005
1006 return npc;
1007}

Referenced by ai_check_player_dist(), ai_suspend_for_time(), ai_try_set_state(), AvoidPlayerAI_Chase(), AvoidPlayerAI_ChaseInit(), AvoidPlayerAI_LosePlayer(), basic_ai_chase(), basic_ai_chase_init(), basic_ai_check_player_dist(), basic_ai_found_player_jump(), basic_ai_found_player_jump_init(), basic_ai_loiter(), basic_ai_loiter_init(), basic_ai_lose_player(), basic_ai_suspend(), basic_ai_wander(), basic_ai_wander_init(), BooPatrolAI_Loiter(), BooPatrolAI_Move(), can_dismount(), check_conversation_trigger(), CleftAI_Ambush(), CleftAI_CanSeePlayer(), CleftAI_Disguise(), CleftAI_DisguiseInit(), CleftAI_FindPlayer(), CleftAI_FindPlayerInit(), CleftAI_Hiding(), CleftAI_HidingInit(), CleftAI_LosePlayer(), CleftAI_PostDisguise(), CleftAI_PreAmbush(), CleftAI_ReturnHome(), CleftAI_RevUp(), CleftAI_RevUpInit(), CleftAI_Tackle(), ClubbaNappingAI_FallAsleep(), ClubbaNappingAI_Init(), ClubbaNappingAI_Loiter(), ClubbaNappingAI_LoiterInit(), ClubbaNappingAI_ReturnHome(), ClubbaNappingAI_ReturnHomeInit(), ClubbaNappingAI_Sleep(), ClubbaNappingAI_WakeUp(), draw_encounters_pre_battle(), FlyingAI_Chase(), FlyingAI_ChaseInit(), FlyingAI_Jump(), FlyingAI_JumpInit(), FlyingAI_Loiter(), FlyingAI_LoiterInit(), FlyingAI_LosePlayer(), FlyingAI_Wander(), FlyingAI_WanderInit(), FlyingMagikoopaAI_10(), FlyingMagikoopaAI_11(), FlyingMagikoopaAI_15(), FlyingMagikoopaAI_16(), FlyingMagikoopaAI_17(), FlyingMagikoopaAI_20(), FlyingMagikoopaAI_21(), FlyingMagikoopaAI_22(), FlyingMagikoopaAI_23(), FlyingMagikoopaAI_24(), FlyingMagikoopaAI_50(), FlyingNoAttackAI_12(), FlyingNoAttackAI_13(), FlyingNoAttackAI_20(), func_80048F0C(), get_npc_pos(), GrooveGuyAI_02(), GrooveGuyAI_03(), GuardAI_Alert(), GuardAI_AlertInit(), GuardAI_Chase(), GuardAI_ChaseInit(), GuardAI_Idle(), GuardAI_IdleInit(), GuardAI_LosePlayer(), GuardAI_ReturnHome(), GuardAI_ReturnHomeInit(), HoppingAI_Chase(), HoppingAI_ChaseInit(), HoppingAI_Hop(), HoppingAI_HopInit(), HoppingAI_Loiter(), HoppingAI_LoiterInit(), HoppingAI_LosePlayer(), kill_enemy(), LakituAI_Loiter(), LakituAI_Wander(), MagikoopaAI_00(), MagikoopaAI_01(), MagikoopaAI_05(), MagikoopaAI_06(), MagikoopaAI_10(), MagikoopaAI_11(), MagikoopaAI_20(), MagikoopaAI_21(), MagikoopaAI_22(), MagikoopaAI_23(), MagikoopaAI_24(), MagikoopaAI_CanShootSpell(), MeleeHitbox_30(), MeleeHitbox_31(), MeleeHitbox_32(), MeleeHitbox_33(), MeleeHitbox_CanSeePlayer(), ParatroopaAI_Dive(), ParatroopaAI_Overshoot(), ParatroopaAI_Reset(), ParatroopaAI_Windup(), PatrolAI_Chase(), PatrolAI_ChaseInit(), PatrolAI_Jump(), PatrolAI_JumpInit(), PatrolAI_Loiter(), PatrolAI_LoiterInit(), PatrolAI_LosePlayer(), PatrolAI_Move(), PatrolAI_MoveInit(), PatrolAI_PostLoiter(), PatrolNoAttackAI_15(), PiranhaPlantAI_00(), PiranhaPlantAI_01(), PiranhaPlantAI_10(), PiranhaPlantAI_11(), PiranhaPlantAI_12(), PiranhaPlantAI_13(), PiranhaPlantAI_LosePlayer(), ProjectileHitbox_30(), ProjectileHitbox_31(), ProjectileHitbox_32(), ProjectileHitbox_33(), ProjectileHitbox_GetUsableProjectileID(), reset_outta_sight_alpha_on_menu_close(), SentinelAI_Chase(), SentinelAI_ChaseInit(), SentinelAI_Descend(), SentinelAI_DescendInit(), SentinelAI_GrabPlayer(), SentinelAI_LosePlayer(), SentinelAI_LosePlayerInit(), SentinelAI_PostLosePlayer(), SentinelAI_ReturnHome(), SentinelAI_ReturnHomeInit(), set_script_owner_npc_anim(), set_script_owner_npc_col_height(), ShyGuyPatrolAI_14(), ShyGuyPatrolAI_15(), ShyGuyPatrolAI_16(), ShyGuyPatrolAI_17(), ShyGuyWanderAI_14(), ShyGuyWanderAI_15(), ShyGuyWanderAI_16(), ShyGuyWanderAI_17(), spawn_drops(), SpearGuyAI_Loiter(), SpearGuyAI_LoiterInit(), StoneChompAI_ChaseInit(), StoneChompAI_HopInit(), sync_player_position(), UnkDistFunc(), UnkNpcAIFunc12(), UnkNpcAIFunc48(), update_encounters_neutral(), update_encounters_post_battle(), and update_player().

◆ get_npc_safe()

Npc * get_npc_safe ( s32 npcID)
Returns
NULL if not found

Definition at line 1009 of file npc.c.

1009 {
1010 s32 i;
1011 Npc* npc;
1012
1013 for (i = 0; i < MAX_NPCS; i++) {
1014 npc = (*gCurrentNpcListPtr)[i];
1015 if (npc != NULL && npc->flags != 0 && npc->npcID == npcID) {
1016 break;
1017 }
1018 }
1019 if (i >= MAX_NPCS) {
1020 return NULL;
1021 }
1022
1023 return npc;
1024}

Referenced by resolve_npc(), sfx_play_sound_at_npc(), and unkVtxFunc001().

◆ enable_npc_shadow()

void enable_npc_shadow ( Npc * npc)

Definition at line 1026 of file npc.c.

1026 {
1027 Shadow* shadow;
1028
1029 if (!(npc->flags & NPC_FLAG_HAS_SHADOW)) {
1030 shadow = get_shadow_by_index(npc->shadowIndex);
1031 shadow->flags &= ~ENTITY_FLAG_HIDDEN;
1033 }
1034}

Referenced by CleftAI_PreAmbush(), and MagikoopaAI_11().

◆ disable_npc_shadow()

void disable_npc_shadow ( Npc * npc)

Definition at line 1036 of file npc.c.

1036 {
1037 Shadow* shadow;
1038
1039 if (npc->flags & NPC_FLAG_HAS_SHADOW) {
1040 shadow = get_shadow_by_index(npc->shadowIndex);
1041 shadow->flags |= ENTITY_FLAG_HIDDEN;
1042 npc->flags &= ~NPC_FLAG_HAS_SHADOW;
1043 npc->flags &= ~NPC_FLAG_DIRTY_SHADOW;
1044 }
1045}
@ ENTITY_FLAG_HIDDEN
Definition enums.h:2613

Referenced by action_update_use_tweester(), CleftAI_HidingInit(), MagikoopaAI_01(), and peach_make_disguise_npc().

◆ set_npc_sprite()

void set_npc_sprite ( Npc * npc,
s32 anim,
AnimID * extraAnimList )

Definition at line 1047 of file npc.c.

1047 {
1049
1050 npc->extraAnimList = extraAnimList;
1051
1052 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE)) {
1053 npc->spriteInstanceID = spr_load_npc_sprite(anim, extraAnimList);
1054 ASSERT(npc->spriteInstanceID >= 0);
1055 }
1056
1057 npc->curAnim = anim;
1058
1059 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1060 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE)) {
1062 }
1063 }
1064}

◆ enable_npc_blur()

void enable_npc_blur ( Npc * npc)

Definition at line 1066 of file npc.c.

1066 {
1067 if (!(npc->flags & NPC_FLAG_MOTION_BLUR)) {
1068 NpcMotionBlur* motionBlur;
1069 s32 i;
1070
1072
1073 motionBlur = heap_malloc(sizeof(*motionBlur));
1074 npc->blur.motion = motionBlur;
1075 ASSERT(motionBlur != NULL);
1076 motionBlur->unused = 0;
1077 motionBlur->index = 0;
1078
1079 for (i = 0; i < ARRAY_COUNT(motionBlur->posX); i++) {
1080 motionBlur->posX[i] = npc->pos.x;
1081 motionBlur->posY[i] = npc->pos.y;
1082 motionBlur->posZ[i] = npc->pos.z;
1083 }
1084 }
1085}
s8 index
Current blur ring buffer index.
Ring buffer of an NPC's position over the past 20 frames.

Referenced by partner_put_away().

◆ disable_npc_blur()

void disable_npc_blur ( Npc * npc)

Definition at line 1087 of file npc.c.

1087 {
1088 if (npc->flags & NPC_FLAG_MOTION_BLUR) {
1089 npc->flags &= ~NPC_FLAG_MOTION_BLUR;
1090
1091 heap_free(npc->blur.motion);
1092 npc->blur.motion = NULL;
1093 }
1094}

Referenced by free_npc(), free_npc_by_index(), partner_put_away(), pre_battle(), pre_battle(), and pre_battle().

◆ update_npc_blur()

void update_npc_blur ( Npc * npc)

Definition at line 1096 of file npc.c.

1096 {
1097 NpcMotionBlur* motionBlur = npc->blur.motion;
1098 s32 index = motionBlur->index;
1099
1100 motionBlur->posX[index] = npc->pos.x;
1101 motionBlur->posY[index] = npc->pos.y;
1102 motionBlur->posZ[index] = npc->pos.z;
1103
1104 index++;
1105 if (index >= 20) {
1106 index = 0;
1107 }
1108
1109 motionBlur->index = index;
1110}

Referenced by update_npcs().

◆ appendGfx_npc_blur()

void appendGfx_npc_blur ( void * data)

Definition at line 1112 of file npc.c.

1112 {
1113 Npc* npc = (Npc*) data;
1114 Matrix4f mtx, tempMtx;
1115 f32 x, y, z;
1116 f32 yaw;
1117 s32 strideIdx;
1118 s32 drawIdx;
1119 s32 bufPos;
1120 NpcMotionBlur* blur;
1121
1122 strideIdx = 0;
1123 drawIdx = 0;
1124 blur = npc->blur.motion;
1125 bufPos = blur->index;
1126
1127 while (TRUE) {
1128 bufPos--;
1129 strideIdx++;
1130
1131 if (bufPos < 0) {
1132 bufPos = NPC_BLUR_FRAMES - 1;
1133 }
1134
1135 if (bufPos == blur->index) {
1136 break;
1137 }
1138
1139 // only draw every third blur frame
1140 if (strideIdx < 3) {
1141 continue;
1142 }
1143
1144 strideIdx = 0;
1145 drawIdx++;
1146
1147 // draw three blur samples
1148 if (drawIdx > 3) {
1149 break;
1150 }
1151
1152 x = blur->posX[bufPos];
1153 y = blur->posY[bufPos];
1154 z = blur->posZ[bufPos];
1155 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_ALPHA, 255, 255, 255, 120 - (drawIdx * 20), 0);
1156 yaw = npc->renderYaw;
1157 guTranslateF(mtx, x, y, z);
1158
1159 if (npc->rot.y != 0.0f) {
1160 guRotateF(tempMtx, npc->rot.y, 0.0f, 1.0f, 0.0f);
1161 guMtxCatF(tempMtx, mtx, mtx);
1162 }
1163 if (npc->rot.x != 0.0f) {
1164 guRotateF(tempMtx, npc->rot.y, 0.0f, 1.0f, 0.0f);
1165 guMtxCatF(tempMtx, mtx, mtx);
1166 }
1167 if (npc->rot.z != 0.0f) {
1168 guRotateF(tempMtx, npc->rot.y, 0.0f, 1.0f, 0.0f);
1169 guMtxCatF(tempMtx, mtx, mtx);
1170 }
1171
1172 if ((npc->scale.x * SPRITE_WORLD_SCALE_D) != 1.0
1173 || ((npc->scale.y * npc->verticalStretch) * SPRITE_WORLD_SCALE_D) != 1.0
1174 || (npc->scale.z * SPRITE_WORLD_SCALE_D) != 1.0
1175 ) {
1176 guScaleF(
1177 tempMtx,
1181 );
1182 guMtxCatF(tempMtx, mtx, mtx);
1183 }
1184
1185 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1186 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE)) {
1187 spr_draw_npc_sprite(npc->spriteInstanceID, yaw, 0, 0, mtx);
1188 }
1189 } else {
1191 }
1192 }
1193 npc_imgfx_update(npc);
1194}
#define NPC_BLUR_FRAMES
@ IMGFX_SET_ALPHA
Definition enums.h:5123
void npc_imgfx_update(Npc *npc)
Definition npc.c:2092
void set_npc_imgfx_all(s32 spriteIdx, ImgFXType imgfxType, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5)
Definition sprite.c:1253

Referenced by render_npcs().

◆ npc_enable_collisions()

void npc_enable_collisions ( void )

Definition at line 1196 of file npc.c.

1196 {
1197 gNpcPlayerCollisionsEnabled = TRUE;
1198}

◆ npc_disable_collisions()

void npc_disable_collisions ( void )

Definition at line 1200 of file npc.c.

1200 {
1201 gNpcPlayerCollisionsEnabled = FALSE;
1202}

◆ func_8003B1A8()

void func_8003B1A8 ( void )

Definition at line 1204 of file npc.c.

1204 {
1205}

Referenced by state_step_battle(), and state_step_pause().

◆ npc_reload_all()

void npc_reload_all ( void )

Definition at line 1207 of file npc.c.

1207 {
1208 s32 i;
1209 s32 j;
1210
1211 for (i = 0; i < MAX_NPCS; i++) {
1212 Npc* npc = (*gCurrentNpcListPtr)[i];
1213 if (npc != NULL) {
1214 if (npc->flags && !(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1215 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE)) {
1216 if (!(npc->flags & NPC_FLAG_PARTNER)) {
1218 } else {
1220 }
1221 }
1222 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1223 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE) && (npc->palSwapType != NPC_PAL_ADJUST_NONE)) {
1225 npc->originalPalettesCount = 0;
1226 while (npc->originalPalettesList[npc->originalPalettesCount] != (PAL_PTR) -1) {
1227 npc->originalPalettesCount++;
1228 }
1230 }
1231 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1232 if (!(npc->flags & NPC_FLAG_HAS_NO_SPRITE)) {
1233 for (j = 0; j < MAX_NPC_DECORATIONS; j++) {
1235 }
1236 npc_imgfx_update(npc);
1237 }
1238 }
1239 }
1240 }
1241 }
1242 }
1243}
#define PAL_PTR
void npc_reset_current_decoration(Npc *npc, s32 idx)
Definition npc.c:1797
s32 spr_get_npc_color_variations(s32 npcSpriteID)
Definition sprite.c:1326
PAL_PTR * spr_get_npc_palettes(s32 npcSpriteID)
Definition sprite.c:1316
s8 originalPalettesCount
u16 ** originalPalettesList
s8 spriteColorVariations

Referenced by state_step_end_battle(), and state_step_unpause().

◆ set_npc_yaw()

void set_npc_yaw ( Npc * npc,
f32 yaw )

Definition at line 1245 of file npc.c.

1245 {
1246 npc->yaw = yaw;
1247
1248 if (get_clamped_angle_diff(gCameras[gCurrentCameraID].curYaw, yaw) >= 0.0f) {
1249 npc->yawCamOffset = 180;
1250 npc->isFacingAway = TRUE;
1251 } else {
1252 npc->yawCamOffset = 0;
1253 npc->isFacingAway = FALSE;
1254 }
1255}
s32 gCurrentCameraID
Definition cam_math.c:4

Referenced by create_encounters(), GrooveGuyAI_02(), GrooveGuyAI_03(), peach_make_disguise_npc(), SpearGuyAI_Loiter(), and SpearGuyAI_LoiterInit().

◆ npc_set_palswap_mode_A()

void npc_set_palswap_mode_A ( Npc * npc,
s32 mode )

Definition at line 1257 of file npc.c.

1257 {
1258 if (npc->palSwapType != mode) {
1259 npc->palSwapPrevType = npc->palSwapType;
1260 npc->palSwapType = mode;
1262 npc->resetPalAdjust = 1;
1263 }
1264}
s8 palAnimState
s8 resetPalAdjust

◆ npc_set_palswap_mode_B()

void npc_set_palswap_mode_B ( Npc * npc,
s32 mode )

Definition at line 1266 of file npc.c.

1266 {
1267 if (npc->palSwapType != mode) {
1268 npc->palSwapPrevType = npc->palSwapType;
1269 npc->palSwapType = mode;
1271 npc->resetPalAdjust = -1;
1272 }
1273}

◆ npc_revert_palswap_mode()

void npc_revert_palswap_mode ( Npc * npc)

Definition at line 1275 of file npc.c.

1275 {
1278 return;
1279 }
1280 npc->palSwapType = npc->palSwapPrevType;
1283 npc->resetPalAdjust = 1;
1284}

◆ npc_set_palswap_1()

void npc_set_palswap_1 ( Npc * npc,
s32 palIndexA,
s32 palIndexB,
s32 timeHoldA,
s32 timeAB )

Definition at line 1286 of file npc.c.

1286 {
1287 npc->blendPalA = palIndexA;
1288 npc->blendPalB = palIndexB;
1289 npc->palswapTimeHoldA = timeHoldA;
1290 npc->palswapTimeAtoB = timeAB;
1291}
s16 blendPalB
s16 palswapTimeAtoB
s16 blendPalA
u16 palswapTimeHoldA

◆ npc_set_palswap_2()

void npc_set_palswap_2 ( Npc * npc,
s32 timeHoldB,
s32 timeBA,
s32 palIndexC,
s32 palIndexD )

Definition at line 1293 of file npc.c.

1293 {
1294 npc->palswapTimeHoldB = timeHoldB;
1295 npc->palswapTimeBtoA = timeBA;
1296 npc->blendPalC = palIndexC;
1297 npc->blendPalD = palIndexD;
1298}
s16 palswapTimeBtoA
s16 blendPalC
s16 blendPalD
s16 palswapTimeHoldB

◆ npc_draw_with_palswap()

void npc_draw_with_palswap ( Npc * npc,
s32 yaw,
Matrix4f mtx )

Definition at line 1300 of file npc.c.

1300 {
1301 switch (npc->palSwapType) {
1304 break;
1307 break;
1309 npc_render_with_single_pal_blending(npc, yaw, FALSE, mtx);
1310 break;
1312 npc_render_with_single_pal_blending(npc, yaw, TRUE, mtx);
1313 break;
1316 break;
1317 }
1318}
@ NPC_PAL_ADJUST_BLEND_DOUBLE_PALETTES
Definition enums.h:1932
@ NPC_PAL_ADJUST_BLEND_PALETTES_UNIFORM_INTERVALS
Definition enums.h:1930
@ NPC_PAL_ADJUST_BLEND_PALETTES_VARYING_INTERVALS
Definition enums.h:1931
@ NPC_PAL_ADJUST_WATT_IDLE
Definition enums.h:1929
void npc_render_without_adjusted_palettes(Npc *npc, s32 arg1, Matrix4f mtx)
Definition npc.c:1320
s32 npc_render_with_single_pal_blending(Npc *npc, s32 yaw, b32 hasDifferentIntervals, Matrix4f mtx)
Definition npc.c:1447
s32 npc_render_with_watt_idle_palettes(Npc *npc, s32 arg1, Matrix4f mtx)
Definition npc.c:1342
s32 npc_render_with_double_pal_blending(Npc *npc, s32 yaw, Matrix4f mtx)
Definition npc.c:1583

Referenced by appendGfx_npc().

◆ npc_render_without_adjusted_palettes()

void npc_render_without_adjusted_palettes ( Npc * npc,
s32 arg1,
Matrix4f mtx )

Definition at line 1320 of file npc.c.

1320 {
1321 if (npc->resetPalAdjust != 0) {
1322 npc->verticalStretch = 1.0f;
1323 npc->screenSpaceOffset2D[0] = 0.0f;
1324 npc->screenSpaceOffset2D[1] = 0.0f;
1325 npc->resetPalAdjust = 0;
1326 }
1327
1328 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1329 s32 alpha = (npc->alpha * npc->hideAlpha / 255);
1330 u32 mask;
1331 if (alpha < 255) {
1333 } else {
1334 mask = 0;
1335 }
1336 spr_draw_npc_sprite(npc->spriteInstanceID | mask, arg1, alpha, NULL, mtx);
1337 } else {
1339 }
1340}
@ DRAW_SPRITE_OVERRIDE_ALPHA
Definition sprite.h:22

Referenced by npc_draw_with_palswap().

◆ npc_render_with_watt_idle_palettes()

s32 npc_render_with_watt_idle_palettes ( Npc * npc,
s32 arg1,
Matrix4f mtx )

Definition at line 1342 of file npc.c.

1342 {
1343 s32 i, j;
1344 s32 brightness;
1345 PAL_PTR src;
1346 PAL_PTR dst;
1347
1348 if (npc->resetPalAdjust != 0) {
1350 npc->originalPalettesCount = 0;
1351 while ((s32)npc->originalPalettesList[npc->originalPalettesCount] != -1) {
1352 npc->originalPalettesCount++;
1353 }
1354
1356 for (i = 0; i < npc->originalPalettesCount; i++) {
1357 dst = npc->copiedPalettes[i];
1358 src = npc->originalPalettesList[i];
1359 if (src != NULL) {
1360 for (j = 0; j < SPR_PAL_SIZE; j++) {
1361 *dst++ = *src++;
1362 }
1363 }
1364 }
1365
1366 npc->palAnimState = -2;
1367 npc->palBlendAlpha = 0;
1368 npc->resetPalAdjust = 0;
1369 npc->nextPalTime = 0;
1370 }
1371
1372 if (npc->nextPalTime == 0) {
1373 npc->palAnimState += 2;
1374 brightness = wWattIdlePalettesAnim[npc->palAnimState];
1375 if (brightness == 255) {
1376 npc->palAnimState = 0;
1377 }
1378 npc->nextPalTime = wWattIdlePalettesAnim[npc->palAnimState + 1] / 2;
1379 }
1380
1381 brightness = wWattIdlePalettesAnim[npc->palAnimState];
1382 npc->nextPalTime--;
1383
1384 switch(brightness) {
1385 case WATT_DEFAULT:
1386 for (i = 0; i < npc->spriteColorVariations; i++) {
1387 dst = npc->copiedPalettes[i];
1388 src = npc->originalPalettesList[i];
1389 if (src != NULL) {
1390 for (j = 0; j < SPR_PAL_SIZE; j++) {
1391 *dst++ = *src++;
1392 }
1393 }
1394 }
1395 break;
1396 case WATT_BRIGHTEST:
1397 for (i = 0; i < npc->spriteColorVariations; i++) {
1398 // use watt's Brightest palettes
1399 dst = npc->copiedPalettes[i];
1400 src = npc->originalPalettesList[npc->spriteColorVariations * SPR_PAL_WorldWatt_Brightest + i];
1401 if (src != NULL) {
1402 for (j = 0; j < SPR_PAL_SIZE; j++) {
1403 *dst++ = *src++;
1404 }
1405 }
1406 }
1407 break;
1408 case WATT_BRIGHTER:
1409 for (i = 0; i < npc->spriteColorVariations; i++) {
1410 // use watt's Brighter palettes
1411 dst = npc->copiedPalettes[i];
1412 src = npc->originalPalettesList[npc->spriteColorVariations * SPR_PAL_WorldWatt_Brighter + i];
1413 if (src != NULL) {
1414 for (j = 0; j < SPR_PAL_SIZE; j++) {
1415 *dst++ = *src++;
1416 }
1417 }
1418 }
1419 break;
1420 }
1421
1422 for (i = 0; i < npc->originalPalettesCount; i++) {
1423 npc->adjustedPalettes[i] = npc->copiedPalettes[i];
1424 }
1425
1426 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1427 s32 alpha = npc->alpha * npc->hideAlpha / 255;
1428 u32 mask = 0;
1429 if (alpha < 255) {
1431 }
1433 spr_draw_npc_sprite(npc->spriteInstanceID | mask, arg1, alpha, npc->adjustedPalettes, mtx);
1434 }
1435 npc->palBlendAlpha--;
1436}
u8 wWattIdlePalettesAnim[]
Definition npc.c:32
#define SPR_PAL_SIZE
Definition macros.h:146
@ DRAW_SPRITE_OVERRIDE_PALETTES
Definition sprite.h:20
s16 nextPalTime
s16 palBlendAlpha
u16 * adjustedPalettes[16]
u16 copiedPalettes[16][16]

Referenced by npc_draw_with_palswap().

◆ npc_blend_palette_colors()

u16 npc_blend_palette_colors ( u16 colorA,
u16 colorB,
s32 lerpAlpha )

Definition at line 1438 of file npc.c.

1438 {
1439 u8 r = (UNPACK_PAL_R(colorA) * (255 - lerpAlpha) + UNPACK_PAL_R(colorB) * lerpAlpha) / 255;
1440 u8 g = (UNPACK_PAL_G(colorA) * (255 - lerpAlpha) + UNPACK_PAL_G(colorB) * lerpAlpha) / 255;
1441 u8 b = (UNPACK_PAL_B(colorA) * (255 - lerpAlpha) + UNPACK_PAL_B(colorB) * lerpAlpha) / 255;
1442 u8 a = UNPACK_PAL_A(colorB);
1443
1444 return PACK_PAL_RGBA(r, g, b, a);
1445}
#define UNPACK_PAL_B(color)
Definition macros.h:273
#define UNPACK_PAL_R(color)
Definition macros.h:271
#define UNPACK_PAL_A(color)
Definition macros.h:274
#define UNPACK_PAL_G(color)
Definition macros.h:272
#define PACK_PAL_RGBA(r, g, b, a)
Definition macros.h:276

Referenced by npc_render_with_double_pal_blending(), and npc_render_with_single_pal_blending().

◆ npc_render_with_single_pal_blending()

s32 npc_render_with_single_pal_blending ( Npc * npc,
s32 yaw,
b32 hasDifferentIntervals,
Matrix4f mtx )

Definition at line 1447 of file npc.c.

1447 {
1448 PAL_PTR color1;
1449 PAL_PTR color2;
1450 PAL_PTR outColor;
1451 s32 i, j;
1452 s32 blendAlpha;
1453
1454 // copy palettes from sprite data
1455 if (npc->resetPalAdjust != 0) {
1456 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1458 }
1459
1460 npc->originalPalettesCount = 0;
1461 while ((s32)npc->originalPalettesList[npc->originalPalettesCount] != -1) {
1462 npc->originalPalettesCount++;
1463 }
1464
1465 if (npc->resetPalAdjust == 1) {
1467 npc->palBlendAlpha = 0;
1468 } else {
1470 npc->palBlendAlpha = 255;
1471 }
1472
1473 for (i = 0; i < npc->originalPalettesCount; i++) {
1474 color1 = npc->copiedPalettes[i];
1475 color2 = npc->originalPalettesList[i];
1476 npc->adjustedPalettes[i] = color1;
1477 if (color2 != NULL) {
1478 for (j = 0; j < SPR_PAL_SIZE; j++) {
1479 *color1++ = *color2++;
1480 }
1481 }
1482 }
1483
1484 if (!hasDifferentIntervals) {
1487 npc->palswapTimeBtoA = npc->palswapTimeAtoB;
1488 npc->palswapTimeHoldA = 0;
1489 }
1490
1491 npc->nextPalTime = npc->palswapTimeHoldA;
1492 npc->palBlendAlpha = 0;
1494 npc->resetPalAdjust = 0;
1495 }
1496
1497 // blending from A -> B
1498 switch (npc->palAnimState) {
1499 case PAL_SWAP_HOLD_A:
1500 if (npc->nextPalTime != 0) {
1501 npc->nextPalTime--;
1502 break;
1503 } else {
1504 npc->palBlendAlpha = 0;
1506 }
1507 // fallthrough
1508 case PAL_SWAP_A_TO_B:
1509 npc->palBlendAlpha += 25600 / npc->palswapTimeAtoB;
1510 if (npc->palBlendAlpha > 25500) {
1511 npc->palBlendAlpha = 25500;
1512 }
1513 blendAlpha = npc->palBlendAlpha / 100;
1514 // blend two palettes
1515 outColor = npc->copiedPalettes[0];
1516 color2 = npc->originalPalettesList[npc->blendPalA];
1517 color1 = npc->originalPalettesList[npc->blendPalB];
1518 npc->adjustedPalettes[0] = outColor;
1519
1520 for (j = 0; j < SPR_PAL_SIZE; j++) {
1521 *outColor++ = npc_blend_palette_colors(*color2++, *color1++, blendAlpha);
1522 }
1523
1524 if (blendAlpha == 255) {
1526 npc->nextPalTime = npc->palswapTimeHoldB;
1527 }
1528 break;
1529 }
1530
1531 // blending from B -> A
1532 switch (npc->palAnimState) {
1533 case PAL_SWAP_HOLD_B:
1534 if (npc->nextPalTime != 0) {
1535 npc->nextPalTime--;
1536 break;
1537 } else {
1538 npc->palBlendAlpha = 0;
1540 }
1541 // fallthrough
1542 case PAL_SWAP_B_TO_A:
1543 npc->palBlendAlpha += 25600 / npc->palswapTimeBtoA;
1544 if (npc->palBlendAlpha > 25500) {
1545 npc->palBlendAlpha = 25500;
1546 }
1547 blendAlpha = npc->palBlendAlpha / 100;
1548 // blend two palettes
1549 outColor = npc->copiedPalettes[0];
1550 color2 = npc->originalPalettesList[npc->blendPalB];
1551 color1 = npc->originalPalettesList[npc->blendPalA];
1552 npc->adjustedPalettes[0] = outColor;
1553
1554 for (j = 0; j < SPR_PAL_SIZE; j++) {
1555 *outColor++ = npc_blend_palette_colors(*color2++, *color1++, blendAlpha);
1556 }
1557
1558 if (blendAlpha == 255) {
1560 npc->nextPalTime = npc->palswapTimeHoldA;
1561 }
1562 break;
1563 }
1564
1565 switch (npc->palAnimState) {
1566 case PAL_SWAP_HOLD_A:
1567 case PAL_SWAP_A_TO_B:
1568 case PAL_SWAP_HOLD_B:
1569 case PAL_SWAP_B_TO_A:
1570 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1571 u32 mask = 0;
1572 blendAlpha = npc->alpha * npc->hideAlpha / 255;
1573 if (blendAlpha < 255) {
1575 }
1577 spr_draw_npc_sprite(npc->spriteInstanceID | mask, yaw, blendAlpha, npc->adjustedPalettes, mtx);
1578 }
1579 break;
1580 }
1581}
u16 npc_blend_palette_colors(u16 colorA, u16 colorB, s32 lerpAlpha)
Definition npc.c:1438

Referenced by npc_draw_with_palswap().

◆ npc_render_with_double_pal_blending()

s32 npc_render_with_double_pal_blending ( Npc * npc,
s32 yaw,
Matrix4f mtx )
Bug
? should this be index 3?

Definition at line 1583 of file npc.c.

1583 {
1584 PAL_PTR color1;
1585 PAL_PTR color2;
1586 PAL_PTR outColor;
1587 s32 i, j;
1588 u8 blendAlpha;
1589
1590 // copy palettes from sprite data
1591 if (npc->resetPalAdjust != 0) {
1592 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1594 }
1595
1596 npc->originalPalettesCount = 0;
1597 while ((s32)npc->originalPalettesList[npc->originalPalettesCount] != -1) {
1598 npc->originalPalettesCount++;
1599 }
1600
1601 if (npc->resetPalAdjust == 1) {
1603 npc->palBlendAlpha = 0;
1604 } else {
1606 npc->palBlendAlpha = 255;
1607 }
1608
1609 for (i = 0; i < npc->originalPalettesCount; i++) {
1610 color1 = npc->copiedPalettes[i];
1611 color2 = npc->originalPalettesList[i];
1612 npc->adjustedPalettes[i] = color1;
1613 if (color2 != NULL) {
1614 for (j = 0; j < SPR_PAL_SIZE; j++) {
1615 *color1++ = *color2++;
1616 }
1617 }
1618 }
1619
1620 npc->nextPalTime = npc->palswapTimeHoldA;
1621 npc->palBlendAlpha = 0;
1623 npc->resetPalAdjust = 0;
1624 }
1625
1626 // blending from A -> B
1627 switch (npc->palAnimState) {
1628 case PAL_SWAP_HOLD_A:
1629 if (npc->nextPalTime != 0) {
1630 npc->nextPalTime--;
1631 break;
1632 }
1633 npc->palBlendAlpha = 0;
1635 // fallthrough
1636 case PAL_SWAP_A_TO_B:
1637 npc->palBlendAlpha += 25600 / npc->palswapTimeAtoB;
1638 if (npc->palBlendAlpha > 25500) {
1639 npc->palBlendAlpha = 25500;
1640 }
1641 blendAlpha = npc->palBlendAlpha / 100;
1642
1643 // blend first two palettes
1644 outColor = npc->copiedPalettes[0];
1645 color2 = npc->originalPalettesList[npc->blendPalA];
1646 color1 = npc->originalPalettesList[npc->blendPalB];
1647 npc->adjustedPalettes[0] = outColor;
1648
1649 for (j = 0; j < SPR_PAL_SIZE; j++) {
1650 *outColor++ = npc_blend_palette_colors(*color2++, *color1++, blendAlpha);
1651 }
1652
1653 // blend next palettes
1654 outColor = npc->copiedPalettes[3];
1655 color2 = npc->originalPalettesList[npc->blendPalC];
1656 color1 = npc->originalPalettesList[npc->blendPalD];
1657 npc->adjustedPalettes[3] = outColor;
1658
1659 for (j = 0; j < SPR_PAL_SIZE; j++) {
1660 *outColor++ = npc_blend_palette_colors(*color2++, *color1++, blendAlpha);
1661 }
1662
1663 if (blendAlpha == 255) {
1665 npc->nextPalTime = npc->palswapTimeHoldB;
1666 }
1667 break;
1668 }
1669
1670 // blending from B -> A
1671 switch (npc->palAnimState) {
1672 case PAL_SWAP_HOLD_B:
1673 if (npc->nextPalTime != 0) {
1674 npc->nextPalTime--;
1675 break;
1676 } else {
1677 npc->palBlendAlpha = 0;
1679 }
1680 // fallthrough
1681 case PAL_SWAP_B_TO_A:
1682 npc->palBlendAlpha += 25600 / npc->palswapTimeBtoA;
1683 if (npc->palBlendAlpha > 25500) {
1684 npc->palBlendAlpha = 25500;
1685 }
1686 blendAlpha = npc->palBlendAlpha / 100;
1687
1688 // blend first two palettes
1689 outColor = npc->copiedPalettes[0];
1690 color2 = npc->originalPalettesList[npc->blendPalB];
1691 color1 = npc->originalPalettesList[npc->blendPalA];
1692 npc->adjustedPalettes[0] = outColor;
1693
1694 for (j = 0; j < SPR_PAL_SIZE; j++) {
1695 *outColor++ = npc_blend_palette_colors(*color2++, *color1++, blendAlpha);
1696 }
1697
1698 // blend next palettes
1699 outColor = npc->copiedPalettes[1];
1700 color2 = npc->originalPalettesList[npc->blendPalD];
1701 color1 = npc->originalPalettesList[npc->blendPalC];
1702 npc->adjustedPalettes[3] = npc->copiedPalettes[3];
1703
1704 for (j = 0; j < SPR_PAL_SIZE; j++) {
1705 *outColor++ = npc_blend_palette_colors(*color2++, *color1++, blendAlpha);
1706 }
1707
1708 if (blendAlpha == 255) {
1710 npc->nextPalTime = npc->palswapTimeHoldA;
1711 }
1712 break;
1713 }
1714
1715 switch (npc->palAnimState) {
1716 case PAL_SWAP_HOLD_A:
1717 case PAL_SWAP_A_TO_B:
1718 case PAL_SWAP_HOLD_B:
1719 case PAL_SWAP_B_TO_A:
1720 if (!(npc->flags & NPC_FLAG_NO_ANIMS_LOADED)) {
1721 u32 mask = 0;
1722 blendAlpha = npc->alpha * npc->hideAlpha / 255;
1723 if (blendAlpha < 255) {
1725 }
1727 spr_draw_npc_sprite(npc->spriteInstanceID | mask, yaw, blendAlpha, npc->adjustedPalettes, mtx);
1728 }
1729 break;
1730 }
1731}

Referenced by npc_draw_with_palswap().

◆ npc_set_decoration()

void npc_set_decoration ( Npc * npc,
s32 idx,
s32 decorationType )

Definition at line 1733 of file npc.c.

1733 {
1734 npc_remove_decoration(npc, idx);
1735 npc->decorationType[idx] = decorationType;
1736 npc->changedDecoration[idx] = 1;
1737 npc->decorationInitialized[idx] = 0;
1738}
s8 changedDecoration[2]
s8 decorationInitialized[2]

◆ npc_remove_decoration()

void npc_remove_decoration ( Npc * npc,
s32 idx )

Definition at line 1740 of file npc.c.

1740 {
1741 switch (npc->decorationType[idx]) {
1744 break;
1747 break;
1750 break;
1753 break;
1756 break;
1759 break;
1762 break;
1763 }
1765}
@ NPC_DECORATION_WHITE_GLOW_BEHIND
Definition enums.h:1923
@ NPC_DECORATION_BOWSER_AURA
Definition enums.h:1919
@ NPC_DECORATION_CHARGED
Definition enums.h:1924
@ NPC_DECORATION_SWEAT
Definition enums.h:1920
@ NPC_DECORATION_NONE
Definition enums.h:1918
@ NPC_DECORATION_WHITE_GLOW_FRONT
Definition enums.h:1922
@ NPC_DECORATION_SEEING_STARS
Definition enums.h:1921
void npc_remove_decoration_glow_in_front(Npc *npc, s32 idx)
Definition npc.c:1905
void npc_remove_decoration_sweat(Npc *npc, s32 idx)
Definition npc.c:1863
void npc_remove_decoration_bowser_aura(Npc *npc, s32 idx)
Definition npc.c:1838
void npc_remove_decoration_none(Npc *npc, s32 idx)
Definition npc.c:1815
void npc_remove_decoration_glow_behind(Npc *npc, s32 idx)
Definition npc.c:1927
void npc_remove_decoration_charged(Npc *npc, s32 idx)
Definition npc.c:1965
void npc_remove_decoration_seeing_stars(Npc *npc, s32 idx)
Definition npc.c:1883

Referenced by free_npc(), free_npc_by_index(), and npc_set_decoration().

◆ npc_update_decorations()

s32 npc_update_decorations ( Npc * npc)

Definition at line 1767 of file npc.c.

1767 {
1768 s32 i;
1769
1770 for (i = 0; i < MAX_NPC_DECORATIONS; i++) {
1771 switch (npc->decorationType[i]) {
1774 break;
1777 break;
1780 break;
1783 break;
1786 break;
1789 break;
1792 break;
1793 }
1794 }
1795}
void npc_update_decoration_charged(Npc *npc, s32 idx)
Definition npc.c:1931
void npc_update_decoration_seeing_stars(Npc *npc, s32 idx)
Definition npc.c:1866
void npc_update_decoration_glow_in_front(Npc *npc, s32 idx)
Definition npc.c:1887
void npc_update_decoration_bowser_aura(Npc *npc, s32 idx)
Definition npc.c:1818
void npc_update_decoration_glow_behind(Npc *npc, s32 idx)
Definition npc.c:1909
void npc_update_decoration_sweat(Npc *npc, s32 idx)
Definition npc.c:1842
void npc_update_decoration_none(Npc *npc, s32 idx)
Definition npc.c:1812

Referenced by update_npcs().

◆ npc_reset_current_decoration()

void npc_reset_current_decoration ( Npc * npc,
s32 idx )

Definition at line 1797 of file npc.c.

1797 {
1798 switch (npc->decorationType[idx]) {
1805 break;
1807 npc->decorationInitialized[idx] = 0;
1808 break;
1809 }
1810}

Referenced by npc_reload_all().

◆ npc_update_decoration_none()

void npc_update_decoration_none ( Npc * npc,
s32 idx )

Definition at line 1812 of file npc.c.

1812 {
1813}

Referenced by npc_update_decorations().

◆ npc_remove_decoration_none()

void npc_remove_decoration_none ( Npc * npc,
s32 idx )

Definition at line 1815 of file npc.c.

1815 {
1816}

Referenced by npc_remove_decoration().

◆ npc_update_decoration_bowser_aura()

void npc_update_decoration_bowser_aura ( Npc * npc,
s32 idx )

Definition at line 1818 of file npc.c.

1818 {
1819 AuraFXData* data;
1820
1821 switch (npc->decorationInitialized[idx]) {
1822 case 0:
1823 fx_aura(FX_AURA_BLUE, npc->pos.x, npc->pos.y, npc->pos.z, 1.0f, &npc->decorations[idx]);
1824 npc->decorationInitialized[idx] = 1;
1825 // fallthrough
1826 case 1:
1827 data = npc->decorations[idx]->data.aura;
1828 data->posA.x = npc->pos.x;
1829 data->posA.y = npc->pos.y;
1830 data->posA.z = npc->pos.z;
1831 data->scale.x = (npc->scale.x * npc->collisionDiameter) * 0.01;
1832 data->scale.y = (npc->scale.y * npc->collisionHeight) * 0.01;
1833 data->renderYaw = npc->renderYaw;
1834 break;
1835 }
1836}
f32 renderYaw
Definition effects.h:1013
Vec2f scale
Definition effects.h:996
Vec3f posA
Definition effects.h:994
EffectInstanceDataPtr data
Definition effects.h:2605
@ FX_AURA_BLUE
Definition effects.h:988
struct AuraFXData * aura
Definition effects.h:2523

Referenced by npc_update_decorations().

◆ npc_remove_decoration_bowser_aura()

void npc_remove_decoration_bowser_aura ( Npc * npc,
s32 idx )

Definition at line 1838 of file npc.c.

1838 {
1839 npc->decorations[idx]->data.aura->fadeTime = 5;
1840}
s32 fadeTime
Definition effects.h:999

Referenced by npc_remove_decoration().

◆ npc_update_decoration_sweat()

void npc_update_decoration_sweat ( Npc * npc,
s32 idx )

Definition at line 1842 of file npc.c.

1842 {
1843 switch (npc->decorationInitialized[idx]) {
1844 case 0:
1845 if (npc->yawCamOffset > 90) {
1846 fx_sweat(0, npc->pos.x, npc->pos.y + npc->collisionHeight, npc->pos.z, 5.0f, 45.0f, 20);
1847 } else {
1848 fx_sweat(0, npc->pos.x, npc->pos.y + npc->collisionHeight, npc->pos.z, 5.0f, -45.0f, 20);
1849 }
1850 npc->decorationGlowPhase[idx] = 10;
1851 npc->decorationInitialized[idx] = 1;
1852 break;
1853 case 1:
1854 if (npc->decorationGlowPhase[idx] != 0) {
1855 npc->decorationGlowPhase[idx]--;
1856 } else {
1857 npc->decorationInitialized[idx] = 0;
1858 }
1859 break;
1860 }
1861}
s16 decorationGlowPhase[2]

Referenced by npc_update_decorations().

◆ npc_remove_decoration_sweat()

void npc_remove_decoration_sweat ( Npc * npc,
s32 idx )

Definition at line 1863 of file npc.c.

1863 {
1864}

Referenced by npc_remove_decoration().

◆ npc_update_decoration_seeing_stars()

void npc_update_decoration_seeing_stars ( Npc * npc,
s32 idx )

Definition at line 1866 of file npc.c.

1866 {
1867 StarsOrbitingFXData* data;
1868
1869 switch (npc->decorationInitialized[idx]) {
1870 case 0:
1871 fx_stars_orbiting(0, npc->pos.x, npc->pos.y + npc->collisionHeight, npc->pos.z, 20.0f, 3, &npc->decorations[idx]);
1872 npc->decorationInitialized[idx] = 1;
1873 break;
1874 case 1:
1875 data = npc->decorations[idx]->data.starsOrbiting;
1876 data->pos.x = npc->pos.x;
1877 data->pos.y = npc->pos.y + npc->collisionHeight;
1878 data->pos.z = npc->pos.z;
1879 break;
1880 }
1881}
struct StarsOrbitingFXData * starsOrbiting
Definition effects.h:2511

Referenced by npc_update_decorations().

◆ npc_remove_decoration_seeing_stars()

void npc_remove_decoration_seeing_stars ( Npc * npc,
s32 idx )

Definition at line 1883 of file npc.c.

1883 {
1884 remove_effect(npc->decorations[idx]);
1885}
#define remove_effect

Referenced by npc_remove_decoration().

◆ npc_update_decoration_glow_in_front()

void npc_update_decoration_glow_in_front ( Npc * npc,
s32 idx )

Definition at line 1887 of file npc.c.

1887 {
1888 EnergyOrbWaveFXData* data;
1889
1890 switch (npc->decorationInitialized[idx]) {
1891 case 0:
1892 npc->decorations[idx] = fx_energy_orb_wave(2, npc->pos.x, npc->pos.y + npc->collisionHeight * 0.5, npc->pos.z, npc->scale.x * 0.8 + 0.2f, -1);
1893 npc->decorationInitialized[idx] = 1;
1894 break;
1895 case 1:
1896 data = npc->decorations[idx]->data.energyOrbWave;
1897 data->pos.x = npc->pos.x;
1898 data->pos.y = npc->pos.y + npc->collisionHeight * 0.5 * npc->scale.x;
1899 data->pos.z = npc->pos.z;
1900 data->scale = npc->scale.x * 0.8 + 0.2f;
1901 break;
1902 }
1903}
struct EnergyOrbWaveFXData * energyOrbWave
Definition effects.h:2546

Referenced by npc_update_decorations().

◆ npc_remove_decoration_glow_in_front()

void npc_remove_decoration_glow_in_front ( Npc * npc,
s32 idx )

Definition at line 1905 of file npc.c.

1905 {
1906 remove_effect(npc->decorations[idx]);
1907}

Referenced by npc_remove_decoration().

◆ npc_update_decoration_glow_behind()

void npc_update_decoration_glow_behind ( Npc * npc,
s32 idx )

Definition at line 1909 of file npc.c.

1909 {
1910 EnergyOrbWaveFXData* data;
1911
1912 switch (npc->decorationInitialized[idx]) {
1913 case 0:
1914 npc->decorations[idx] = fx_energy_orb_wave(2, npc->pos.x, npc->pos.y + npc->collisionHeight * 0.5, npc->pos.z - 5.0f, 1.0f, 0);
1915 npc->decorationInitialized[idx] = 1;
1916 break;
1917 case 1:
1918 data = npc->decorations[idx]->data.energyOrbWave;
1919 data->pos.x = npc->pos.x;
1920 data->pos.y = npc->pos.y + npc->collisionHeight * 0.5;
1921 data->pos.z = npc->pos.z - 5.0f;
1922 data->scale = 1.0f;
1923 break;
1924 }
1925}

Referenced by npc_update_decorations().

◆ npc_remove_decoration_glow_behind()

void npc_remove_decoration_glow_behind ( Npc * npc,
s32 idx )

Definition at line 1927 of file npc.c.

1927 {
1928 remove_effect(npc->decorations[idx]);
1929}

Referenced by npc_remove_decoration().

◆ npc_update_decoration_charged()

void npc_update_decoration_charged ( Npc * npc,
s32 idx )

Definition at line 1931 of file npc.c.

1931 {
1932 #define RGBA_BUF_SIZE 20
1933 u8 rbuf[RGBA_BUF_SIZE];
1934 u8 gbuf[RGBA_BUF_SIZE];
1935 u8 bbuf[RGBA_BUF_SIZE];
1936 s32 color;
1937 s32 alpha;
1938 s32 i;
1939
1940 if (npc->decorationInitialized[idx] == 0) {
1942 npc->decorationInitialized[idx] = 1;
1943 }
1944 if (npc->decorationInitialized[idx] == 1) {
1945 npc->decorationGlowPhase[idx] += 7;
1946 if (npc->decorationGlowPhase[idx] >= 360) {
1947 npc->decorationGlowPhase[idx] %= 360;
1948 }
1949
1950 for (i = 0; i < RGBA_BUF_SIZE; i++) {
1951 rbuf[i] = (cosine(npc->decorationGlowPhase[idx] + (25 * i)) + 1.0) * 80.0f;
1952 gbuf[i] = (cosine(npc->decorationGlowPhase[idx] + (25 * i) + 45) + 1.0) * 80.0f;
1953 bbuf[i] = (cosine(npc->decorationGlowPhase[idx] + (25 * i) + 90) + 1.0) * 80.0f;
1954 }
1955
1956 alpha = 255;
1957 for (i = 0; i < RGBA_BUF_SIZE; i++) {
1958 color = (rbuf[i] << 24) | (gbuf[i] << 16) | (bbuf[i] << 8) | alpha;
1960 }
1961 }
1962 #undef RGBA_BUF_SIZE
1963}
@ IMGFX_ALLOC_COLOR_BUF
Definition enums.h:5133
@ IMGFX_COLOR_BUF_SET_MODULATE
Definition enums.h:5128
f32 cosine(s16 arg0)
Definition 43F0.c:353
#define RGBA_BUF_SIZE

Referenced by npc_update_decorations().

◆ npc_remove_decoration_charged()

void npc_remove_decoration_charged ( Npc * npc,
s32 idx )

Definition at line 1965 of file npc.c.

1965 {
1966}

Referenced by npc_remove_decoration().

◆ npc_find_closest()

Npc * npc_find_closest ( f32 x,
f32 y,
f32 z,
f32 radius )

Finds the closest NPC to a given point within a radius.

Ignores Y position.

NPCs with NPC_FLAG_PARTNER set are ignored. See also npc_find_closest_simple(), which requires that NPC_FLAG_PARTNER be set.

Parameters
xX position
yY position (unused)
zZ position
radiusNo NPCs further than this distance will be considered
Returns
NULL if there are no NPCs within radius

Definition at line 1968 of file npc.c.

1968 {
1969 Npc* closestNpc = NULL;
1970 f32 closestDist = radius;
1971 f32 maxDist = radius;
1972 s32 i;
1973
1974 for (i = 0; i < ARRAY_COUNT(*gCurrentNpcListPtr); i++) {
1975 Npc* npc = (*gCurrentNpcListPtr)[i];
1976
1977 if (npc != NULL && npc->flags != 0 && !(npc->flags & NPC_FLAG_PARTNER)) {
1978 if (!(npc->flags & (NPC_FLAG_SUSPENDED | NPC_FLAG_INACTIVE))) {
1979 f32 distance = fabsf(dist2D(npc->pos.x, npc->pos.z, x, z));
1980
1981 if (distance <= maxDist) {
1982 if (distance < closestDist) {
1983 closestDist = distance;
1984 closestNpc = npc;
1985 }
1986 }
1987 }
1988 }
1989 }
1990
1991 return closestNpc;
1992}
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:669

Referenced by parasol_get_npc().

◆ npc_find_closest_simple()

Npc * npc_find_closest_simple ( f32 x,
f32 y,
f32 z,
f32 radius )

Finds the closest simple-hitbox NPC to a given point within a radius.

Ignores Y position.

Only NPCs with NPC_FLAG_PARTNER set are considered. See also npc_find_closest(), which requires that NPC_FLAG_PARTNER be unset.

Parameters
xX position
yY position (unused)
zZ position
radiusNo NPCs further than this distance will be considered
Returns
NULL if there are no NPCs within radius

Definition at line 1994 of file npc.c.

1994 {
1995 Npc* closestNpc = NULL;
1996 f32 closestDist = radius;
1997 f32 maxDist = radius;
1998 s32 i;
1999
2000 for (i = 0; i < ARRAY_COUNT(*gCurrentNpcListPtr); i++) {
2001 Npc* npc = (*gCurrentNpcListPtr)[i];
2002
2003 if (npc != NULL && npc->flags != 0 && (npc->flags & NPC_FLAG_PARTNER)) {
2004 if (!(npc->flags & (NPC_FLAG_SUSPENDED | NPC_FLAG_INACTIVE))) {
2005 f32 distance = fabsf(dist2D(npc->pos.x, npc->pos.z, x, z));
2006
2007 if (distance <= maxDist) {
2008 if (distance < closestDist) {
2009 closestDist = distance;
2010 closestNpc = npc;
2011 }
2012 }
2013 }
2014 }
2015 }
2016
2017 return closestNpc;
2018}

Referenced by entity_Tweester_idle().

◆ npc_find_standing_on_entity()

s32 npc_find_standing_on_entity ( s32 entityIndex)

Definition at line 2020 of file npc.c.

2020 {
2021 s32 idx = entityIndex | COLLISION_WITH_ENTITY_BIT;
2022 s32 y = get_entity_by_index(idx)->pos.y - 10.0f;
2023 Npc* npc;
2024 s32 i;
2025 s32 var_v1;
2026
2027 npc->pos = npc->pos; // TODO required to match
2028
2029 for (i = 0; i < ARRAY_COUNT(*gCurrentNpcListPtr); i++) {
2030 npc = (*gCurrentNpcListPtr)[i];
2031
2032 if (npc == NULL) {
2033 continue;
2034 }
2035 if (npc->flags == 0) {
2036 continue;
2037 }
2039 continue;
2040 }
2041 if (npc->flags & NPC_FLAG_PARTNER) {
2042 var_v1 = i; // TODO required to match (dummy if statement to load NPC_FLAG_PARTNER into s5)
2043 }
2044 if (npc->pos.y < y) {
2045 continue;
2046 }
2048 var_v1 = npc_get_collider_below(npc);
2049 if (var_v1 != 0) {
2050 if (idx == var_v1) {
2051 return i;
2052 }
2053 }
2054 } else {
2055 var_v1 = npc->curFloor;
2056 if (npc->curFloor & COLLISION_WITH_ENTITY_BIT) { // TODO required to match (can't use var_v1)
2057 if (idx == var_v1) {
2058 npc->pos = npc->pos; // TODO required to match
2059 return i;
2060 }
2061 }
2062 }
2063 }
2064
2065 return -1;
2066}
Entity * get_entity_by_index(s32 index)
Definition entity.c:530
s32 npc_get_collider_below(Npc *npc)
Definition npc.c:2068
#define COLLISION_WITH_ENTITY_BIT
Definition macros.h:156

Referenced by entity_HiddenPanel_idle().

◆ npc_get_collider_below()

s32 npc_get_collider_below ( Npc * npc)

Definition at line 2068 of file npc.c.

2068 {
2069 f32 x;
2070 f32 y;
2071 f32 z;
2072 f32 yaw;
2073
2074 if (npc->flags & NPC_FLAG_PARTNER) {
2075 y = get_shadow_by_index(npc->shadowIndex)->pos.y + 13.0f;
2076 } else {
2077 y = npc->pos.y + 13.0f;
2078 }
2079
2080 yaw = 16.0f;
2081 x = npc->pos.x;
2082 z = npc->pos.z;
2083
2085 if (yaw <= 16.0f) {
2086 return NpcHitQueryColliderID;
2087 }
2088 }
2089 return 0;
2090}
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4695
@ COLLIDER_FLAG_IGNORE_SHELL
Definition enums.h:4694

Referenced by npc_find_standing_on_entity().

◆ npc_imgfx_update()

void npc_imgfx_update ( Npc * npc)

Definition at line 2092 of file npc.c.

2092 {
2093 s32 imgfxType = npc->imgfxType;
2094 s32 imgfxArg1 = npc->imgfxArg1;
2095 s32 imgfxArg2 = npc->imgfxArg2;
2096 s32 imgfxArg3 = npc->imgfxArg3;
2097 s32 imgfxArg4 = npc->imgfxArg4;
2098 s32 imgfxFlags = npc->imgfxFlags;
2099
2100 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_CLEAR, 0, 0, 0, 0, 0);
2101
2102 switch (imgfxType) {
2103 case IMGFX_CLEAR:
2105 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_CLEAR, 0, 0, 0, 0, imgfxFlags);
2106 break;
2107 case IMGFX_UNK_2:
2108 case IMGFX_RESET:
2110 // fallthrough
2111 case IMGFX_UNK_1:
2112 set_npc_imgfx_all(npc->spriteInstanceID, imgfxType, 0, 0, 0, 0, imgfxFlags);
2113 break;
2114 case IMGFX_SET_WAVY:
2116 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_WAVY, imgfxArg1, imgfxArg2, imgfxArg3, 0, imgfxFlags);
2117 break;
2118 case IMGFX_SET_COLOR:
2120 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_COLOR, imgfxArg1, imgfxArg2, imgfxArg3, 255, imgfxFlags);
2121 break;
2122 case IMGFX_SET_ALPHA:
2124 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_ALPHA, 255, 255, 255, imgfxArg1, imgfxFlags);
2125 break;
2126 case IMGFX_SET_TINT:
2128 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_TINT, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, imgfxFlags);
2129 break;
2132 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_WHITE_FADE, imgfxArg1, imgfxArg2, imgfxArg3, 255, imgfxFlags);
2133 break;
2136 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_CREDITS_FADE, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, imgfxFlags);
2137 break;
2138 case IMGFX_SET_ANIM:
2140 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_SET_ANIM, imgfxArg1, imgfxArg2, imgfxArg3, 0, imgfxFlags);
2141 break;
2142 case IMGFX_HOLOGRAM:
2144 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_HOLOGRAM, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, imgfxFlags);
2145 break;
2146 case IMGFX_FILL_COLOR:
2148 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_FILL_COLOR, imgfxArg1, imgfxArg2, imgfxArg3, 255, imgfxFlags);
2149 break;
2150 case IMGFX_OVERLAY:
2152 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_OVERLAY, imgfxArg1, 255, 0, 255, imgfxFlags);
2153 break;
2154 case IMGFX_OVERLAY_XLU:
2156 set_npc_imgfx_all(npc->spriteInstanceID, IMGFX_OVERLAY, imgfxArg1, imgfxArg2, 0, imgfxArg2, imgfxFlags);
2157 break;
2158 }
2159}
@ IMGFX_RESET
Definition enums.h:5119
@ IMGFX_HOLOGRAM
Definition enums.h:5129
@ IMGFX_SET_COLOR
Definition enums.h:5122
@ IMGFX_OVERLAY_XLU
Definition enums.h:5132
@ IMGFX_OVERLAY
Definition enums.h:5131
@ IMGFX_SET_WAVY
Definition enums.h:5120
@ IMGFX_FILL_COLOR
Definition enums.h:5130
@ IMGFX_SET_CREDITS_FADE
Definition enums.h:5126
@ IMGFX_SET_TINT
Definition enums.h:5124
@ IMGFX_SET_WHITE_FADE
Definition enums.h:5125
@ IMGFX_SET_ANIM
Definition enums.h:5121
@ IMGFX_UNK_2
Definition enums.h:5118
@ IMGFX_UNK_1
Definition enums.h:5117
@ RENDER_MODE_SURFACE_XLU_LAYER2
Definition enums.h:3287
@ RENDER_MODE_ALPHATEST
Definition enums.h:3276
s16 imgfxArg2
s16 imgfxArg3
s16 imgfxArg4
s16 imgfxArg1

Referenced by appendGfx_npc_blur(), npc_reload_all(), and npc_set_imgfx_params().

◆ npc_set_imgfx_params()

void npc_set_imgfx_params ( Npc * npc,
s32 imgfxType,
s32 arg2,
s32 arg3,
s32 arg4,
s32 arg5,
s32 arg6 )

Definition at line 2161 of file npc.c.

2161 {
2162 npc->imgfxType = imgfxType;
2163 npc->imgfxArg1 = arg2;
2164 npc->imgfxArg2 = arg3;
2165 npc->imgfxArg3 = arg4;
2166 npc->imgfxArg4 = arg5;
2167 npc->imgfxFlags = arg6;
2168 npc_imgfx_update(npc);
2169}

Referenced by end_outta_sight_cleanup(), reset_outta_sight_alpha_on_menu_close(), and update_riding_physics().

◆ COPY_set_defeated()

void COPY_set_defeated ( s32 mapID,
s32 encounterID )

Duplicate of set_defeated().

Definition at line 2171 of file npc.c.

2171 {
2172 EncounterStatus* currentEncounter = &gCurrentEncounter;
2173 s32 encounterIdx = encounterID / 32;
2174 s32 encounterShift;
2175 s32 flag;
2176
2177 flag = encounterID % 32;
2178 encounterShift = flag;
2179 flag = currentEncounter->defeatFlags[mapID][encounterIdx];
2180 currentEncounter->defeatFlags[mapID][encounterIdx] = flag | (1 << encounterShift);
2181
2182 // TODO: The below should work but has regalloc issues:
2183 /*EncounterStatus *currentEncounter = &gCurrentEncounter;
2184 s32 encounterIdx = encounterID / 32;
2185 s32 encounterShift = encounterID % 32;
2186
2187 currentEncounter->defeatFlags[mapID][encounterIdx] |= (1 << encounterShift);*/
2188}
EncounterStatus gCurrentEncounter
Definition encounter.c:176
s32 defeatFlags[60][12]
Definition npc.h:403

Referenced by kill_enemy().

◆ init_encounter_status()

void init_encounter_status ( void )

Definition at line 2190 of file npc.c.

2190 {
2191 EncounterStatus* currentEncounter = &gCurrentEncounter;
2192 s32 i;
2193 s32 j;
2194
2195 for (i = 0; i < ARRAY_COUNT(currentEncounter->encounterList); i++) {
2196 currentEncounter->encounterList[i] = 0;
2197 }
2198
2199 currentEncounter->flags = ENCOUNTER_FLAG_NONE;
2200 currentEncounter->numEncounters = 0;
2201 currentEncounter->firstStrikeType = FIRST_STRIKE_NONE;
2202 currentEncounter->hitType = 0;
2203 currentEncounter->battleTriggerCooldown = 0;
2204 currentEncounter->npcGroupList = 0;
2205 currentEncounter->unk_08 = 0;
2206 currentEncounter->dropWhackaBump = FALSE;
2207
2208 for (i = 0; i < ARRAY_COUNT(currentEncounter->defeatFlags); i++) {
2209 for (j = 0; j < ARRAY_COUNT(currentEncounter->defeatFlags[i]); j++) {
2210 currentEncounter->defeatFlags[i][j] = 0;
2211 }
2212 }
2213
2214 for (i = 0; i < ARRAY_COUNT(currentEncounter->recentMaps); i++) {
2215 currentEncounter->recentMaps[i] = -1;
2216 }
2217
2218 func_80045AC0();
2221}
@ ENCOUNTER_FLAG_NONE
Definition enums.h:4985
@ ENCOUNTER_STATE_NONE
Definition enums.h:6293
@ FIRST_STRIKE_NONE
Definition enums.h:3458
void func_80045AC0(void)
s32 create_worker_scene(void(*updateFunc)(void), void(*renderFunc)(void))
Definition worker.c:32
void npc_render_worker_do_nothing(void)
Definition npc.c:2327
s16 recentMaps[2]
Definition npc.h:404
Encounter * encounterList[24]
Definition npc.h:392
s8 battleTriggerCooldown
set to 15 after victory, 45 after fleeing
Definition npc.h:373
s32 * npcGroupList
Definition npc.h:391
s8 numEncounters
Definition npc.h:384
s8 dropWhackaBump
Definition npc.h:381
s8 firstStrikeType
Definition npc.h:367
s32 gEncounterState
Definition encounter.c:174

Referenced by load_engine_data(), state_step_demo(), state_step_intro(), and state_step_startup().

◆ clear_encounter_status()

void clear_encounter_status ( void )

Definition at line 2223 of file npc.c.

2223 {
2224 EncounterStatus* currentEncounter = &gCurrentEncounter;
2225 s32 i;
2226 s32 j;
2227
2228 for (i = 0; i < ARRAY_COUNT(currentEncounter->encounterList); i++) {
2229 currentEncounter->encounterList[i] = 0;
2230 }
2231
2233 for (i = 0; i < ARRAY_COUNT(currentEncounter->defeatFlags); i++) {
2234 for (j = 0; j < ARRAY_COUNT(currentEncounter->defeatFlags[i]); j++) {
2235 currentEncounter->defeatFlags[i][j] = 0;
2236 }
2237 }
2238
2240 for (i = 0; i < ARRAY_COUNT(currentEncounter->recentMaps); i++) {
2241 currentEncounter->recentMaps[i] = -1;
2242 }
2243 }
2244 }
2245
2246 currentEncounter->numEncounters = 0;
2247 currentEncounter->firstStrikeType = FIRST_STRIKE_NONE;
2248 currentEncounter->hitType = 0;
2249 currentEncounter->battleTriggerCooldown = 0;
2250 currentEncounter->curAreaIndex = gGameStatusPtr->areaID;
2251 currentEncounter->curMapIndex = gGameStatusPtr->mapID;
2252 currentEncounter->curEntryIndex = gGameStatusPtr->entryID;
2253 currentEncounter->npcGroupList = 0;
2254 currentEncounter->unk_08 = 0;
2255 currentEncounter->scriptedBattle = FALSE;
2256
2257 func_80045AC0();
2260}
s8 scriptedBattle
battle started by StartBattle but not by encounter
Definition npc.h:380
u8 curMapIndex
Definition npc.h:386
u8 curEntryIndex
Definition npc.h:387
s8 curAreaIndex
Definition npc.h:385

Referenced by load_demo_battle(), and load_map_by_IDs().

◆ func_8003E50C()

void func_8003E50C ( void )

Definition at line 2262 of file npc.c.

2262 {
2263}

◆ func_8003E514()

void func_8003E514 ( s8 arg0)

Definition at line 2265 of file npc.c.

2265 {
2267}

Referenced by btl_state_update_end_battle().

◆ update_encounters()

void update_encounters ( void )

Definition at line 2269 of file npc.c.

2269 {
2270 switch (gEncounterState) {
2272 break;
2275 break;
2278 break;
2281 break;
2284 break;
2287 break;
2288 }
2289
2291}
@ ENCOUNTER_STATE_POST_BATTLE
Definition enums.h:6298
@ ENCOUNTER_STATE_CONVERSATION
Definition enums.h:6297
@ ENCOUNTER_STATE_NEUTRAL
Definition enums.h:6295
@ ENCOUNTER_STATE_PRE_BATTLE
Definition enums.h:6296
@ ENCOUNTER_STATE_CREATE
Definition enums.h:6294
void create_encounters(void)
Definition encounter.c:2461
void update_encounters_conversation(void)
Definition encounter.c:2263
void update_encounters_neutral(void)
Definition encounter.c:481
void update_encounters_post_battle(void)
Definition encounter.c:1619
void update_encounters_pre_battle(void)
Definition encounter.c:1261
void update_merlee_messages(void)

Referenced by state_step_battle(), state_step_change_map(), state_step_enter_world(), state_step_game_over(), state_step_intro(), state_step_pause(), state_step_unpause(), and state_step_world().

◆ draw_encounter_ui()

void draw_encounter_ui ( void )

Definition at line 2293 of file npc.c.

2293 {
2294 switch (gEncounterState) {
2296 break;
2299 break;
2302 break;
2305 break;
2308 break;
2311 break;
2312 }
2313
2315}
void init_encounters_ui(void)
Definition encounter.c:2814
void draw_encounters_pre_battle(void)
Definition encounter.c:1487
void draw_merlee_messages(void)
void draw_encounters_conversation(void)
Definition encounter.c:2319
void draw_encounters_neutral(void)
Definition encounter.c:1258
void draw_encounters_post_battle(void)
Definition encounter.c:2253

Referenced by state_drawUI_battle(), and state_drawUI_world().

◆ draw_first_strike_ui()

void draw_first_strike_ui ( void )

Definition at line 2317 of file npc.c.

2317 {
2318 switch (gEncounterState) {
2320 break;
2323 break;
2324 }
2325}
void show_first_strike_message(void)
Definition encounter.c:1563

Referenced by state_world_draw_aux_ui().

◆ npc_render_worker_do_nothing()

void npc_render_worker_do_nothing ( void )

Definition at line 2327 of file npc.c.

2327 {
2328}

Referenced by clear_encounter_status(), and init_encounter_status().

◆ make_npcs()

void make_npcs ( s32 flags,
s32 mapID,
s32 * npcGroupList )

Definition at line 2330 of file npc.c.

2330 {
2331 EncounterStatus* currentEncounter = &gCurrentEncounter;
2332 s32 i;
2333 s32 j;
2334
2335 currentEncounter->resetMapEncounterFlags = flags;
2336 currentEncounter->mapID = mapID;
2337 currentEncounter->npcGroupList = npcGroupList;
2338
2340 for (i = 0; i < ARRAY_COUNT(currentEncounter->defeatFlags); i++) {
2341 for (j = 0; j < ARRAY_COUNT(currentEncounter->defeatFlags[i]); j++) {
2342 currentEncounter->defeatFlags[i][j] = 0;
2343 }
2344 }
2345
2347 for (i = 0; i < ARRAY_COUNT(currentEncounter->recentMaps); i++) {
2348 currentEncounter->recentMaps[i] = -1;
2349 }
2350 }
2351 }
2352
2353 if (npcGroupList != NULL) {
2355 EncounterStateChanged = TRUE;
2357 }
2358}
s8 flags
Definition demo_api.c:15
@ ENCOUNTER_SUBSTATE_CREATE_INIT
Definition enums.h:6302
s8 resetMapEncounterFlags
Definition npc.h:389
b32 EncounterStateChanged
Definition encounter.c:24
s32 gEncounterSubState
Definition encounter.c:175

◆ kill_encounter()

s32 kill_encounter ( Enemy * enemy)

Definition at line 2360 of file npc.c.

2360 {
2362 s32 i;
2363
2364 for (i = 0; i < encounter->count; i++) {
2365 Enemy* currentEnemy = encounter->enemy[i];
2366 if (currentEnemy != NULL) {
2367 kill_enemy(currentEnemy);
2368 encounter->enemy[i] = NULL;
2369 }
2370 }
2371}
void kill_enemy(Enemy *enemy)
Definition npc.c:2373
s8 encounterIndex
Definition npc.h:296
Enemy * enemy[16]
Definition npc.h:352
s32 count
Definition npc.h:351
Definition npc.h:294

◆ kill_enemy()

void kill_enemy ( Enemy * enemy)

Definition at line 2373 of file npc.c.

2373 {
2374 EncounterStatus* encounterStatus = &gCurrentEncounter;
2375 Encounter* encounter = encounterStatus->encounterList[enemy->encounterIndex];
2376 s32 i;
2377 s32 j;
2378
2379 for (i = 0; i < encounter->count; i++) {
2380 Enemy* currentEnemy = encounter->enemy[i];
2381 if (currentEnemy == enemy) {
2382 break;
2383 }
2384 }
2385
2386 if (enemy->initScript != NULL) {
2388 }
2389 if (enemy->interactScript != NULL) {
2391 }
2392 if (enemy->aiScript != NULL) {
2394 }
2395 if (enemy->hitScript != NULL) {
2397 }
2398 if (enemy->auxScript != NULL) {
2400 }
2401 if (enemy->defeatScript != NULL) {
2403 }
2404
2405 enemy->interactBytecode = NULL;
2406 enemy->aiBytecode = NULL;
2407 enemy->hitBytecode = NULL;
2408 enemy->auxBytecode = NULL;
2409 enemy->defeatBytecode = NULL;
2410
2411 #if DX_DEBUG_MENU
2412 if (enemy->npcID != (s16) DX_DEBUG_DUMMY_ID) {
2413 free_npc(get_npc_unsafe(enemy->npcID));
2414 }
2415 #else
2416 free_npc(get_npc_unsafe(enemy->npcID));
2417 #endif
2418
2419 if (enemy->unk_64 != NULL) {
2420 heap_free(enemy->unk_64);
2421 }
2422
2423 for (j = 0; j < ARRAY_COUNT(encounter->enemy); j++) {
2424 if (encounter->enemy[j] == enemy) {
2425 encounter->enemy[j] = NULL;
2426 }
2427 }
2428
2429 if (!(enemy->flags & ENEMY_FLAG_DO_NOT_KILL)
2430 && (!(enemy->flags & ENEMY_FLAG_ENABLE_HIT_SCRIPT) || (enemy == encounterStatus->curEnemy))
2431 && !(enemy->flags & ENEMY_FLAG_PASSIVE)
2432 && !(enemy->flags & ENEMY_FLAG_FLED)
2433 ) {
2434 COPY_set_defeated(encounterStatus->mapID, encounter->encounterID + i);
2435 }
2436
2437 heap_free(enemy);
2438}
@ ENEMY_FLAG_DO_NOT_KILL
Definition enums.h:4522
@ ENEMY_FLAG_PASSIVE
Definition enums.h:4520
@ ENEMY_FLAG_FLED
Definition enums.h:4524
@ ENEMY_FLAG_ENABLE_HIT_SCRIPT
Definition enums.h:4523
void kill_script_by_ID(s32 id)
void free_npc(Npc *npc)
Definition npc.c:237
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:994
void COPY_set_defeated(s32 mapID, s32 encounterID)
Duplicate of set_defeated().
Definition npc.c:2171
struct Evt * interactScript
Definition npc.h:312
s32 flags
Definition npc.h:295
s16 npcID
Definition npc.h:300
s32 interactScriptID
Definition npc.h:318
s16 encounterID
Definition npc.h:355
struct Evt * hitScript
Definition npc.h:314
EvtScript * hitBytecode
Definition npc.h:308
s32 auxScriptID
Definition npc.h:321
s32 initScriptID
Definition npc.h:317
Enemy * curEnemy
Definition npc.h:394
struct Evt * defeatScript
Definition npc.h:316
EvtScript * interactBytecode
Definition npc.h:306
s32 aiScriptID
Definition npc.h:319
struct Evt * initScript
Definition npc.h:311
s32 defeatScriptID
Definition npc.h:322
struct Evt * auxScript
Definition npc.h:315
void * unk_64
Definition npc.h:323
EvtScript * defeatBytecode
Definition npc.h:310
EvtScript * aiBytecode
Definition npc.h:307
struct Evt * aiScript
Definition npc.h:313
EvtScript * auxBytecode
Definition npc.h:309
s32 hitScriptID
Definition npc.h:320

Referenced by kill_encounter(), and update_encounters_post_battle().

◆ bind_enemy_ai()

s32 bind_enemy_ai ( Enemy * enemy,
EvtScript * aiScriptBytecode )

Binds the specified ai script to the specified enemy.

Parameters
enemypointer to the enemy to bind the script to
aiScriptBytecodepointer to the script to be bound.

Definition at line 2440 of file npc.c.

2440 {
2441 Evt* aiScript;
2442 s32 id;
2443
2444 if (enemy->aiScript != NULL) {
2445 kill_script_by_ID(enemy->aiScript->id);
2446 }
2447 enemy->aiBytecode = aiScriptBytecode;
2448 aiScript = enemy->aiScript = start_script(aiScriptBytecode, EVT_PRIORITY_A, 0);
2449 id = enemy->aiScriptID = aiScript->id;
2450 aiScript->owner1.enemy = enemy;
2451 return id;
2452}
union Evt::@10 owner1
Initially -1.
@ EVT_PRIORITY_A
Definition evt.h:153
Evt * start_script(EvtScript *source, s32 priority, s32 initialState)

Referenced by bind_npc_ai().

◆ bind_enemy_aux()

s32 bind_enemy_aux ( Enemy * enemy,
EvtScript * auxScriptBytecode )

Binds the specified auxillary script to the specified enemy.

Parameters
enemypointer to the enemy to bind the script to
auxScriptBytecodepointer to the script to be bound.

Definition at line 2454 of file npc.c.

2454 {
2455 Evt* auxScript;
2456 s32 id;
2457
2458 if (enemy->auxScript != NULL) {
2460 }
2461 enemy->auxBytecode = auxScriptBytecode;
2462 auxScript = enemy->auxScript = start_script(auxScriptBytecode, EVT_PRIORITY_A, 0);
2463 id = enemy->auxScriptID = auxScript->id;
2464 auxScript->owner1.enemy = enemy;
2465 return id;
2466}

Referenced by bind_npc_aux().

◆ bind_enemy_interact()

s32 bind_enemy_interact ( Enemy * enemy,
EvtScript * interactScriptBytecode )

Binds the specified interact script to the specified enemy.

Parameters
enemypointer to the enemy to bind the script to
interactScriptBytecodepointer to the script to be bound.

Definition at line 2468 of file npc.c.

2468 {
2469 Evt* interactScript;
2470 s32 id;
2471
2472 if (enemy->interactScript != NULL) {
2474 }
2475 enemy->interactBytecode = interactScriptBytecode;
2476 interactScript = enemy->interactScript = start_script(interactScriptBytecode, EVT_PRIORITY_A, 0);
2477 id = enemy->interactScriptID = interactScript->id;
2478 interactScript->owner1.enemy = enemy;
2479 return id;
2480}

Referenced by bind_npc_interact().

◆ bind_npc_ai()

void bind_npc_ai ( s32 npcID,
EvtScript * npcAiBytecode )

Binds the specified ai script to the npc matching the specified npcId.

Parameters
npcIDID of the desired npc
npcAiBytecodepointer to the script to be bound.

Definition at line 2482 of file npc.c.

2482 {
2483 EncounterStatus* currentEncounterStatus = &gCurrentEncounter;
2484 s32 i;
2485 s32 j;
2486
2487 for (i = 0; i < currentEncounterStatus->numEncounters; i++) {
2488 Encounter* currentEncounter = currentEncounterStatus->encounterList[i];
2489 if (currentEncounter != NULL) {
2490 for (j = 0; j < currentEncounter->count; j++) {
2491 Enemy* currentEnemy = currentEncounter->enemy[j];
2492 if ((currentEnemy != NULL) && (currentEnemy->npcID == npcID)) {
2493 bind_enemy_ai(currentEnemy, npcAiBytecode);
2494 break;
2495 }
2496 }
2497 }
2498 }
2499}
s32 bind_enemy_ai(Enemy *enemy, EvtScript *aiScriptBytecode)
Binds the specified ai script to the specified enemy.
Definition npc.c:2440

◆ bind_npc_aux()

void bind_npc_aux ( s32 npcID,
EvtScript * npcAuxBytecode )

Binds the specified auxillary script to the npc matching the specified npcId.

Parameters
npcIDID of the desired npc
npcAuxBytecodepointer to the script to be bound.

Definition at line 2501 of file npc.c.

2501 {
2502 EncounterStatus* currentEncounterStatus = &gCurrentEncounter;
2503 s32 i;
2504 s32 j;
2505
2506 for (i = 0; i < currentEncounterStatus->numEncounters; i++) {
2507 Encounter* currentEncounter = currentEncounterStatus->encounterList[i];
2508 if (currentEncounter != NULL) {
2509 for (j = 0; j < currentEncounter->count; j++) {
2510 Enemy* currentEnemy = currentEncounter->enemy[j];
2511 if ((currentEnemy != NULL) && (currentEnemy->npcID == npcID)) {
2512 bind_enemy_aux(currentEnemy, npcAuxBytecode);
2513 break;
2514 }
2515 }
2516 }
2517 }
2518}
s32 bind_enemy_aux(Enemy *enemy, EvtScript *auxScriptBytecode)
Binds the specified auxillary script to the specified enemy.
Definition npc.c:2454

◆ bind_npc_interact()

void bind_npc_interact ( s32 npcID,
EvtScript * npcInteractBytecode )

Binds the specified interact script to the npc matching the specified npcId.

Parameters
npcIDID of the desired npc
npcInteractBytecodepointer to the script to be bound.

Definition at line 2520 of file npc.c.

2520 {
2521 EncounterStatus* currentEncounterStatus = &gCurrentEncounter;
2522 s32 i;
2523 s32 j;
2524
2525 for (i = 0; i < currentEncounterStatus->numEncounters; i++) {
2526 Encounter* currentEncounter = currentEncounterStatus->encounterList[i];
2527 if (currentEncounter != NULL) {
2528 for (j = 0; j < currentEncounter->count; j++) {
2529 Enemy* currentEnemy = currentEncounter->enemy[j];
2530 if ((currentEnemy != NULL) && (currentEnemy->npcID == npcID)) {
2531 bind_enemy_interact(currentEnemy, npcInteractBytecode);
2532 break;
2533 }
2534 }
2535 }
2536 }
2537}
s32 bind_enemy_interact(Enemy *enemy, EvtScript *interactScriptBytecode)
Binds the specified interact script to the specified enemy.
Definition npc.c:2468

◆ get_enemy()

Enemy * get_enemy ( s32 npcID)

Looks for an enemy matching the specified npcID.

Parameters
npcIDID of the npc bound to the desired enemy.
Returns
pointer to Enemy struct, if one is found. If one is not found, a panic occurs.

Definition at line 2539 of file npc.c.

2539 {
2540 EncounterStatus* currentEncounterStatus = &gCurrentEncounter;
2541 s32 i;
2542 s32 j;
2543
2544 for (i = 0; i < currentEncounterStatus->numEncounters; i++) {
2545 Encounter* currentEncounter = currentEncounterStatus->encounterList[i];
2546 if (currentEncounter != NULL) {
2547 for (j = 0; j < currentEncounter->count; j++) {
2548 Enemy* currentEnemy = currentEncounter->enemy[j];
2549 if ((currentEnemy != NULL) && (currentEnemy->npcID == npcID)) {
2550 return currentEnemy;
2551 }
2552 }
2553 }
2554 }
2555 PANIC();
2556}
#define PANIC()
Definition macros.h:55

Referenced by ai_enemy_play_sound(), FlyingMagikoopaAI_23(), LakituAI_GetAvailableSpiny(), MagikoopaAI_23(), MagikoopaAI_CanShootSpell(), MeleeHitbox_CanSeePlayer(), ProjectileHitbox_30(), ProjectileHitbox_32(), ProjectileHitbox_GetUsableProjectileID(), SentinelAI_DescendInit(), set_npc_animation(), and UnkNpcAIFunc48().

◆ get_enemy_safe()

Enemy * get_enemy_safe ( s32 npcID)

Same as get_enemy(), with the exception of always returning a value if an enemy is not found.

Parameters
npcIDID of the npc bound to the desired enemy.
Returns
pointer to Enemy struct, if one is found. Otherwise, NULL.

Definition at line 2558 of file npc.c.

2558 {
2559 EncounterStatus* currentEncounterStatus = &gCurrentEncounter;
2560 s32 i;
2561 s32 j;
2562
2563 for (i = 0; i < currentEncounterStatus->numEncounters; i++) {
2564 Encounter* currentEncounter = currentEncounterStatus->encounterList[i];
2565
2566 if (currentEncounter != NULL) {
2567 for (j = 0; j < currentEncounter->count; j++) {
2568 Enemy* currentEnemy = currentEncounter->enemy[j];
2569 if ((currentEnemy != NULL) && (currentEnemy->npcID == npcID)) {
2570 return currentEnemy;
2571 }
2572 }
2573 }
2574 }
2575 return NULL;
2576}

Variable Documentation

◆ gNpcCount

s16 gNpcCount

Definition at line 10 of file npc.c.

Referenced by clear_npcs(), create_npc_impl(), free_npc(), free_npc_by_index(), and init_npc_list().

◆ wWattIdlePalettesAnim

u8 wWattIdlePalettesAnim[]
Initial value:

Definition at line 32 of file npc.c.

32 {
34 WATT_DEFAULT, 52,
36 WATT_DEFAULT, 54,
37 WATT_DEFAULT, 54,
39 WATT_DEFAULT, 28,
41 WATT_DEFAULT, 6,
43 WATT_DEFAULT, 44,
45 WATT_DEFAULT, 44,
47};
#define PAL_ANIM_END
Definition npc.c:16

Referenced by npc_render_with_watt_idle_palettes().