7#include "sprite/player.h"
11#define inspect_icon_VRAM inspect_icon_VRAM
12#define speech_bubble_VRAM speech_bubble_VRAM
13#define pulse_stone_VRAM pulse_stone_VRAM
14#define i_spy_VRAM i_spy_VRAM
16#define inspect_icon_VRAM (void*)0x802B7000
17#define speech_bubble_VRAM (void*)0x802B7000
18#define pulse_stone_VRAM (void*)0x802B7000
19#define i_spy_VRAM (void*)0x802B7000
23extern Addr i_spy_ROM_START;
24extern Addr i_spy_ROM_END;
25extern Addr pulse_stone_ROM_START;
26extern Addr pulse_stone_ROM_END;
27extern Addr speech_bubble_ROM_START;
28extern Addr speech_bubble_ROM_END;
29extern Addr inspect_icon_ROM_START;
30extern Addr inspect_icon_ROM_END;
46HitID player_raycast_general(s32, f32, f32, f32, f32, f32, f32, f32*, f32*, f32*, f32*, f32*, f32*, f32*);
72 f32* hitDirX, f32* hitDirZ) {
74 f32 inputX, inputY, inputZ, inputLength;
87 inputLength = *outLength;
88 temp_f20 = diameter * 0.28f;
90 sinTemp = temp_f20 * sinTheta;
91 cosTemp = -temp_f20 * cosTheta;
114 x = inputX - sinTemp;
116 z = inputZ - cosTemp;
117 length = inputLength;
132 x = inputX + cosTemp;
134 z = inputZ + sinTemp;
135 length = inputLength;
150 x = inputX - cosTemp;
152 z = inputZ - sinTemp;
153 length = inputLength;
170 length = inputLength;
194 f32* hitRx, f32* hitRz, f32* hitDirX, f32* hitDirZ) {
202 outX, outY, outZ, outLength, hitRx, hitRz, hitDirX, hitDirZ);
213 s32 entityID, colliderID;
218 entityID =
test_ray_entities(*x, *y, *z, 0.0f, -1.0f, 0.0f, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
221 if (entity->
alpha < 255) {
229 colliderID =
test_ray_colliders(
COLLIDER_FLAG_IGNORE_PLAYER, *x, *y, *z, 0, -1.0f, 0, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
270 deltaX = radius *
sin_rad(theta);
271 deltaZ = -radius *
cos_rad(theta);
344 hitID =
test_ray_colliders(
COLLIDER_FLAG_IGNORE_PLAYER, sx, sy, sz, 0.0f, 1.0f, 0.0f, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
354 hitID =
test_ray_entities(*x, *y, *z, 0.0f, 1.0f, 0.0f, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
403 cosTheta = -cosTheta;
404 hitDepth = length + radius;
405 hitID =
player_raycast_general(mode, *x, *y + height, *z, sinTheta, 0, cosTheta, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
411 targetDx = length * sinTheta;
412 targetDz = length * cosTheta;
416 originalDepth = length + radius;
417 if (hitDepth <= originalDepth) {
418 depthDiff = hitDepth - originalDepth;
419 dx = depthDiff * sinTheta;
420 dz = depthDiff * cosTheta;
435 f32* hitY, f32* hitZ, f32* hitDepth, f32*hitNx, f32* hitNy, f32* hitNz) {
445 if (dx_debug_is_cheat_enabled(DEBUG_CHEAT_IGNORE_WALLS)) {
450 entityID =
test_ray_entities(startX, startY, startZ, dirX, dirY, dirZ, hitX, hitY, hitZ, hitDepth, hitNx, hitNy,
455 if (entity->
alpha < 255) {
463 hitX, hitY, hitZ, hitDepth, hitNx, hitNy, hitNz);
476 colliderID =
test_ray_colliders(ignoreFlags, startX, startY, startZ, dirX, dirY, dirZ,
477 hitX, hitY, hitZ, hitDepth, hitNx, hitNy, hitNz);
484 nAngleZ = 180.0f -
atan2(0, 0, *hitNz * 100.0, *hitNy * 100.0);
485 nAngleX = 180.0f -
atan2(0, 0, *hitNx * 100.0, *hitNy * 100.0);
487 if (!((nAngleZ == 90.0f && nAngleX == 90.0f) ||
fabs(nAngleZ) >= 30.0 ||
fabs(nAngleX) >= 30.0)) {
522 depth = length + radius;
523 cosTheta = -cosTheta;
525 dx = radius * sinTheta;
528 hitID =
player_raycast_general(
PLAYER_COLLISION_0, *x, *y + 0.1, *z, sinTheta, 0, cosTheta, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
530 *hasClimbableStep = TRUE;
533 depth = length + radius;
535 dz = radius * cosTheta;
537 hitID =
player_raycast_general(
PLAYER_COLLISION_0, *x, *y + height, *z, sinTheta, 0, cosTheta, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
543 depthDiff = hitDepth - depth;
544 dx = depthDiff * sinTheta;
545 dz = depthDiff * cosTheta;
557 f32 projectionLength = (x * nX) + (y * nY);
559 *outX = (x - projectionLength * nX) * 0.5f;
560 *outY = (y - projectionLength * nY) * 0.5f;
578 f32 targetDx, targetDz;
590 cosTheta = -cosTheta;
591 hitDepth = length + radius;
593 targetDx = length * sinTheta;
594 targetDz = length * cosTheta;
596 hitID =
player_raycast_general(
PLAYER_COLLISION_0, *x, *y + height, *z, sinTheta, 0, cosTheta, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
597 if (hitID >
NO_COLLIDER && (depthDiff = hitDepth, depthDiff <= length + radius)) {
598 depthDiff -= (length + radius);
599 dx = depthDiff * sinTheta;
600 dz = depthDiff * cosTheta;
607 hitID =
player_raycast_general(
PLAYER_COLLISION_0, *x, *y + height, *z, sinTheta, 0, cosTheta, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
608 if (hitID >
NO_COLLIDER && (depthDiff = hitDepth, depthDiff <= length + radius)) {
609 depthDiff -= (length + radius);
610 dx = depthDiff * sinTheta;
611 dz = depthDiff * cosTheta;
630 if (dx_debug_is_cheat_enabled(DEBUG_CHEAT_SPEED_MODE)) {
638 if ((playerStatus->
timeInAir > 100) || (playerStatus->
pos.
y < -2000.0f)) {
666 playerStatus->
flags &= ~PS_FLAG_SPECIAL_LAND;
684 playerStatus->
flags &= ~PS_FLAG_CUTSCENE_MOVEMENT;
714 playerStatus->
flags &= ~PS_FLAG_SLIDING;
715 playerStatus->
animFlags &= ~PA_FLAG_FORCE_USE_PARTNER;
744 if (dx_debug_is_cheat_enabled(DEBUG_CHEAT_FLY) && playerStatus->
curButtons &
BUTTON_L) {
745 playerStatus->
pos.
y += 5.0f;
818 playerStatus->
pos.
z);
844 && anim != ANIM_Mario1_Flail
845 && anim != ANIM_Mario1_Jump
852 anim = ANIM_MarioW2_RideLaki;
857 && anim != ANIM_Mario1_Crouch
858 && anim != ANIM_Mario1_Idle
868 if (anim == ANIM_MarioW1_Lift || anim == ANIM_Peach2_SpreadArms || anim == ANIM_Mario1_Idle) {
874 anim = ANIM_Peach2_SpreadArms;
881 && (anim == ANIM_Peach2_RaiseArms || anim == ANIM_Peach2_Talk || anim == ANIM_Peach2_LowerArms)
883 anim = ANIM_Peach3_PresentCompleteCake;
887 if (anim == ANIM_MarioW2_Collapse) {
899 playerStatus->
anim = newAnim;
901 playerStatus->
flags &= ~PS_FLAG_FACE_FORWARD;
908 playerStatus->
anim = anim;
910 playerStatus->
flags &= ~PS_FLAG_FACE_FORWARD;
918 playerStatus->
anim = newAnim;
926 s32 outtaSight = FALSE;
951 playerStatus->
flags &= ~PS_FLAG_HAZARD_INVINCIBILITY;
985 playerStatus->
flags &= ~PS_FLAG_NO_STATIC_COLLISION;
1003 playerStatus->
flags &= ~PS_FLAG_INPUT_DISABLED;
1077 if ((dx + dy) > 5) {
1200 playerStatus->
flags &= ~PS_FLAG_INTERACTED;
1210 b32 collidingWithEntity = FALSE;
1234 collidingWithEntity = TRUE;
1235 curInteraction = floor;
1259 playerStatus->
flags &= ~PS_FLAG_INTERACTED;
1264 collidingWithEntity = TRUE;
1267 playerStatus->
flags &= ~PS_FLAG_INTERACTED;
1274 playerStatus->
flags &= ~PS_FLAG_INTERACTED;
1285 playerStatus->
flags &= ~PS_FLAG_INTERACTED;
1358 if (camRelativeYaw < -5.0f && camRelativeYaw > -175.0f) {
1359 camRelativeYaw = 0.0f;
1361 }
else if (camRelativeYaw > 5.0f && camRelativeYaw < 175.0f) {
1362 camRelativeYaw = 180.0f;
1380 if (angle != 0.0f) {
1403 if (playerStatus->
curSpeed == 0.0f) {
1407 trueAnim = playerStatus->
anim;
1409 sprIndex = (playerStatus->
anim >> 0x10) & 0xFF;
1413 && (sprIndex == SPR_Mario1 || sprIndex == SPR_MarioW1 || sprIndex == SPR_Peach1)
1421 && (sprIndex == SPR_Mario1 || sprIndex == SPR_MarioW1 || sprIndex == SPR_Peach1)
1443 s32 sprIndex = (anim >> 16) & 0xff;
1446 if (sprIndex != SPR_Mario1) {
1447 if (sprIndex != SPR_MarioW1 && sprIndex != SPR_Peach1) {
1451 if (sprIndex == SPR_Mario1) {
1452 if (anim > ANIM_Mario1_SpinFall) {
1455 }
else if (sprIndex == SPR_MarioW1) {
1456 if (anim == ANIM_MarioW1_Lift) {
1457 outAnim = ANIM_MarioW1_Lift_Back;
1458 }
else if (anim == ANIM_MarioW1_Toss) {
1459 outAnim = ANIM_MarioW1_Toss_Back;
1460 }
else if (anim == ANIM_MarioW1_Smash1_Miss) {
1461 outAnim = ANIM_MarioW1_Smash1_Miss_Back;
1462 }
else if (anim == ANIM_MarioW1_Smash1_Hit) {
1463 outAnim = ANIM_MarioW1_Smash1_Hit_Back;
1464 }
else if (anim == ANIM_MarioW1_Smash2_Miss) {
1465 outAnim = ANIM_MarioW1_Smash2_Miss_Back;
1466 }
else if (anim == ANIM_MarioW1_Smash2_Hit) {
1467 outAnim = ANIM_MarioW1_Smash2_Hit_Back;
1468 }
else if (anim == ANIM_MarioW1_Smash3_Miss) {
1469 outAnim = ANIM_MarioW1_Smash3_Miss_Back;
1470 }
else if (anim == ANIM_MarioW1_Smash3_Hit) {
1471 outAnim = ANIM_MarioW1_Smash3_Hit_Back;
1473 }
else if (sprIndex == SPR_Peach1) {
1474 if (anim > ANIM_Peach1_StepDown) {
1478 }
else if (anim > ANIM_Mario1_SpinFall) {
1502 playerStatus->
flags &= ~PS_FLAG_SPRITE_REDRAW;
1504 playerStatus->
pos.
z, &x, &y, &z);
1507 if (playerStatus->
curAlpha < 254) {
1552 guRotateF(sp20, temp_f0, 0.0f, 1.0f, 0.0f);
1560 guRotateF(spA0, temp_f0, 0.0f, -1.0f, 0.0f);
1565 guRotateF(spA0, temp_f0, 0.0f, 1.0f, 0.0f);
1615 for (i = 0; i < 2; i++) {
1632 tint = 255 - (tint * 60);
1639 guRotateF(rotation, yaw, 0.0f, -1.0f, 0.0f);
1642 px = playerStatus->
pos.
x;
1643 py = playerStatus->
pos.
y;
1644 pz = playerStatus->
pos.
z;
1648 if (y == 0x80000000) {
1649 py = playerStatus->
pos.
y;
1654 px = playerStatus->
pos.
x;
1655 pz = playerStatus->
pos.
z;
1658 guRotateF(rotation, yaw, 0.0f, -1.0f, 0.0f);
1659 guRotateF(mtx, blurAngle, 0.0f, 1.0f, 0.0f);
1665 guRotateF(rotation, yaw, 0.0f, 1.0f, 0.0f);
1690 f32 shadowScale = 0.0f;
1692 f32 hitDirX, hitDirZ;
1695 f32 playerX, playerZ;
1703 shadow->
pos.
x = playerX = playerStatus->
pos.
x;
1704 shadow->
pos.
z = playerZ = playerStatus->
pos.
z;
1708 shadowScale = 1024.0f;
1710 &shadowScale, &hitRx, &hitRz, &hitDirX, &hitDirZ);
1711 shadow->
rot.
x = hitRx;
1712 shadow->
rot.
z = hitRz;
1717 if (hitRx != 0.0f || hitRz != 0.0f) {
1718 s32 dist =
dist2D(x, z, playerStatus->
pos.
x, playerStatus->
pos.
z);
1719 f32 tan =
atan2(playerStatus->
pos.
x, playerStatus->
pos.
z, x, z);
void force_player_anim(AnimID anim)
HitID player_raycast_up_corner(f32 *x, f32 *y, f32 *z, f32 *length)
void appendGfx_player_spin(void *data)
Only used when speedy spinning.
void clear_pulse_stone_icon(void)
void phys_update_lava_reset(void)
void clear_interact_prompt(void)
HitID player_test_move_with_slipping(PlayerStatus *playerStatus, f32 *x, f32 *y, f32 *z, f32 length, f32 yaw)
s32 WorldTattleInteractionID
HitID player_raycast_below_cam_relative(PlayerStatus *playerStatus, f32 *outX, f32 *outY, f32 *outZ, f32 *outLength, f32 *hitRx, f32 *hitRz, f32 *hitDirX, f32 *hitDirZ)
s32 has_valid_conversation_npc(void)
HitID player_test_move_without_slipping(PlayerStatus *playerStatus, f32 *x, f32 *y, f32 *z, f32 length, f32 yaw, s32 *hasClimbableStep)
Only used for Peach physics.
void suggest_player_anim_always_forward(AnimID anim)
HitID player_raycast_down(f32 *, f32 *, f32 *, f32 *)
b32 check_player_action_debug(void)
s32 disable_player_input(void)
HitID player_raycast_general(s32, f32, f32, f32, f32, f32, f32, f32 *, f32 *, f32 *, f32 *, f32 *, f32 *, f32 *)
void render_interact_prompt(void)
s32 disable_player_static_collisions(void)
s32 enable_player_input(void)
void update_partner_timers(void)
void phys_update_standard(void)
void(* TalkNotificationCallback)(void)
s32 get_overriding_player_anim(s32 anim)
void render_conversation_prompt(void)
void player_reset_data(void)
void clear_player_status(void)
void enable_player_shadow(void)
void render_pulse_stone_icon(void)
s32 partner_use_ability(void)
void player_render_interact_prompts(void)
void update_player_blink(void)
void player_get_slip_vector(f32 *outX, f32 *outY, f32 x, f32 y, f32 nX, f32 nY)
void check_for_pulse_stone(void)
unavoidable use of hardcoded map and area IDs
void(* PulseStoneNotificationCallback)(void)
void render_player_model(void)
PlayerStatus gPlayerStatus
void check_for_conversation_prompt(void)
HitID player_test_lateral_overlap(s32 mode, PlayerStatus *playerStatus, f32 *x, f32 *y, f32 *z, f32 length, f32 yaw)
void render_ispy_icon(void)
f32 get_xz_dist_to_player(f32 x, f32 z)
void suggest_player_anim_allow_backward(AnimID anim)
void(* InteractNotificationCallback)(void)
void appendGfx_player(void *data)
void check_input_use_partner(void)
HitID player_raycast_up_corners(PlayerStatus *player, f32 *posX, f32 *posY, f32 *posZ, f32 *hitDepth, f32 yaw)
void clear_conversation_prompt(void)
void update_player_shadow(void)
void func_800E06C0(s32 arg0)
void(* ISpyNotificationCallback)(void)
void appendGfx_interact_prompt(void)
s32 enable_player_static_collisions(void)
HitID player_raycast_below(f32 yaw, f32 diameter, f32 *outX, f32 *outY, f32 *outZ, f32 *outLength, f32 *hitRx, f32 *hitRz, f32 *hitDirX, f32 *hitDirZ)
void player_update_sprite(void)
b32 is_player_dismounted(void)
s32 get_player_back_anim(s32 arg0)
void disable_player_shadow(void)
void clear_ispy_icon(void)
void check_for_ispy(void)
void check_for_interactables(void)
DisguiseAnims BasicPeachDisguiseAnims[]
s8 enableCollisionOverlapsCheck
Vec3f playerGroundTraceNormal
AnimID trueAnimation
Encoding back-facing sprite.
s32 partnerUnlockedTime[12]
Vec3f playerGroundTraceAngles
#define queue_render_task
@ PS_FLAG_ENTERING_BATTLE
@ PS_FLAG_ROTATION_LOCKED
@ PS_FLAG_CAMERA_DOESNT_FOLLOW
@ PS_FLAG_CUTSCENE_MOVEMENT
@ PS_FLAG_NO_PARTNER_USAGE
@ PS_FLAG_HAZARD_INVINCIBILITY
@ PS_FLAG_NO_STATIC_COLLISION
@ PS_FLAG_HAS_CONVERSATION_NPC
@ COLLIDER_FLAG_DOCK_WALL
@ COLLIDER_FLAG_IGNORE_PLAYER
@ COLLIDER_FLAG_IGNORE_SHELL
@ ENTITY_TYPE_PADLOCK_RED_FACE
@ ENTITY_TYPE_PADLOCK_RED_FRAME
@ ENTITY_TYPE_PADLOCK_BLUE_FACE
@ PLAYER_COLLISION_HAMMER
@ PA_FLAG_INTERRUPT_USE_PARTNER
forces actions with bow, parakarry, watt, and lakilester to end (sushie not tested)
@ PA_FLAG_SPEECH_PROMPT_AVAILABLE
(...) prompt
@ PA_FLAG_FORCE_USE_PARTNER
triggers partner use when set
@ PA_FLAG_DISMOUNTING_ALLOWED
@ PA_FLAG_ISPY_VISIBLE
The I Spy icon is being shown.
@ PA_FLAG_PULSE_STONE_VISIBLE
The pulse stone icon is being shown.
@ PA_FLAG_USING_PEACH_PHYSICS
@ PA_FLAG_USING_PULSE_STONE
@ PA_FLAG_INTERACT_PROMPT_AVAILABLE
! prompt
@ RENDER_MODE_SURFACE_XLU_LAYER2
@ RENDER_MODE_SURFACE_XLU_LAYER1
@ ENTITY_FLAG_CONTINUOUS_COLLISION
@ ENTITY_FLAG_SHOWS_INSPECT_PROMPT
@ ACTION_STATE_USE_SPINNING_FLOWER
@ ACTION_STATE_ENEMY_FIRST_STRIKE
@ ACTION_STATE_TORNADO_JUMP
@ NPC_FLAG_USE_INSPECT_ICON
void reset_player_status(void)
Entity * get_entity_by_index(s32 index)
void peach_set_disguise_anim(AnimID)
void clear_world_menus(void)
s32 phys_can_player_interact(void)
void get_screen_coords(s32 camID, f32 x, f32 y, f32 z, s32 *screenX, s32 *screenY, s32 *screenZ)
void phys_update_action_state(void)
void set_standard_shadow_scale(Shadow *shadow, f32 scale)
void appendGfx_speech_bubble(void)
void interact_speech_setup(void)
void phys_update_falling(void)
Shadow * get_shadow_by_index(s32 index)
void appendGfx_ispy_icon(void)
void appendGfx_pulse_stone_icon(void)
void interact_inspect_setup(void)
void check_input_open_menus(void)
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
void phys_main_collision_below(void)
void collision_check_player_overlaps(void)
u32 get_entity_type(s32 arg0)
void collision_lateral_peach(void)
void pulse_stone_notification_setup(void)
void set_action_state(s32 actionState)
void exec_ShakeCam1(s32 arg0, s32 arg1, s32 arg2)
void update_player_input(void)
void check_input_status_bar(void)
s32 test_ray_entities(f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz)
Test a general ray from a given starting position and direction against all entities.
s32 should_collider_allow_interact(s32)
void set_peach_shadow_scale(Shadow *shadow, f32 scale)
s32 create_shadow_type(s32 type, f32 x, f32 y, f32 z)
void collision_main_lateral(void)
void collision_lava_reset_check_additional_overlaps(void)
s32 test_ray_colliders(s32 ignoreFlags, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz)
void player_surface_spawn_fx(void)
f32 get_player_normal_pitch(void)
void phys_update_jump(void)
void sin_cos_rad(f32 rad, f32 *outSinTheta, f32 *outCosTheta)
void partner_reset_tether_distance(void)
f32 phys_get_spin_history(s32 lag, s32 *x, s32 *y, s32 *z)
f32 get_clamped_angle_diff(f32, f32)
f32 get_player_normal_yaw(void)
void check_input_midair_jump(void)
void ispy_notification_setup(void)
HitID collision_main_above(void)
Npc * get_npc_unsafe(s32 npcID)
#define DMA_COPY_SEGMENT(segment)
#define SPRITE_WORLD_SCALE_D
#define COLLISION_WITH_ENTITY_BIT
#define COLLISION_WITH_NPC_BIT
void set_player_imgfx_all(s32 animID, ImgFXType imgfxType, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6)
s32 spr_draw_player_sprite(s32 spriteInstanceID, s32 yaw, s32 alphaIn, PAL_PTR *paletteList, Matrix4f mtx)
s32 spr_update_player_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale)
void set_player_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 flags)
@ DRAW_SPRITE_UPSIDE_DOWN
void(* appendGfx)(void *)
u8 Addr[]
Linker symbol address, as in ld_addrs.h.
PlayerStatus * gPlayerStatusPtr
CollisionStatus gCollisionStatus
PartnerStatus gPartnerStatus
GameStatus * gGameStatusPtr
s32 PrevPlayerCamRelativeYaw
HiddenPanelsData gCurrentHiddenPanels
void world_watt_sync_held_position(void)