Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
partners.h File Reference

Go to the source code of this file.

Data Structures

struct  WorldPartner
 

Typedefs

typedef void(* PartnerFunc) (Npc *partner)
 
typedef s32(* PartnerBoolFunc) (Npc *partner)
 
typedef s32(* PartnerTesHitFunc) (Npc *partner, Npc *enemy)
 

Functions

s32 partner_init_get_out (Npc *)
 
s32 partner_get_out (Npc *)
 
s32 partner_init_put_away (Npc *partner)
 
s32 partner_put_away (Npc *partner)
 
s32 partner_can_use_ability (void)
 
s32 partner_use_ability (void)
 
void partner_do_player_collision (Npc *partner)
 
void partner_walking_follow_player (Npc *partner)
 
s32 func_800EA52C (s32)
 
s32 partner_force_player_flip_done (void)
 
void partner_suspend_ability_script (void)
 
void partner_resume_ability_script (void)
 
void partner_enable_input (void)
 

Variables

NpcwPartnerNpc
 

Data Structure Documentation

◆ WorldPartner

struct WorldPartner
Data Fields
void * dmaStart
void * dmaEnd
void * dmaDest Always 0x802BD100
s32 isFlying
PartnerFunc init
EvtScript * takeOut
EvtScript * update
EvtScript * useAbility
EvtScript * putAway
s32 idle
PartnerTesHitFunc testFirstStrike
PartnerBoolFunc canUseAbility
PartnerBoolFunc canPlayerOpenMenus
PartnerFunc preBattle
PartnerFunc postBattle
EvtScript * onEnterMap

Typedef Documentation

◆ PartnerFunc

typedef void(* PartnerFunc) (Npc *partner)

Definition at line 4 of file partners.h.

◆ PartnerBoolFunc

typedef s32(* PartnerBoolFunc) (Npc *partner)

Definition at line 5 of file partners.h.

◆ PartnerTesHitFunc

typedef s32(* PartnerTesHitFunc) (Npc *partner, Npc *enemy)

Definition at line 6 of file partners.h.

Function Documentation

◆ partner_init_get_out()

s32 partner_init_get_out ( Npc * npc)

Definition at line 2252 of file partners.c.

2252 {
2256 return wPartnerFollowState;
2257}
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4696
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:3006
BSS s16 wPartnerFollowState
Definition partners.c:51
s32 flags
s32 collisionChannel

◆ partner_get_out()

s32 partner_get_out ( Npc * partner)
Bug
? collider flags not properly masked with COLLIDER_FLAG_SURFACE_TYPE

Definition at line 2259 of file partners.c.

2259 {
2260 PlayerStatus* playerStatus = &gPlayerStatus;
2261 Camera* camera = &gCameras[gCurrentCameraID];
2262 f32 x, y, z, hitDepth;
2263 f32 var_f0;
2264
2265 f32 moveToX, moveToY, moveToZ;
2266
2267 switch (wPartnerFollowState) {
2268 case 0:
2269 if (clamp_angle(playerStatus->spriteFacingAngle) < 180.0f) {
2270 partner->yaw = clamp_angle(camera->curYaw + 90.0f);
2271 } else {
2272 partner->yaw = clamp_angle(camera->curYaw - 90.0f);
2273 }
2274 partner->moveToPos.x = playerStatus->pos.x;
2275 partner->moveToPos.y = playerStatus->pos.y;
2276 if (wPartner->isFlying) {
2277 partner->moveToPos.y = playerStatus->pos.y;
2278 }
2279 partner->moveToPos.z = playerStatus->pos.z;
2280 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, playerStatus->colliderDiameter, partner->yaw);
2281 moveToX = partner->moveToPos.x;
2282 moveToY = partner->moveToPos.y;
2283 moveToZ = partner->moveToPos.z;
2284 if (!wPartner->isFlying) {
2285 x = moveToX;
2286 y = moveToY + partner->collisionHeight;
2287 z = moveToZ;
2288 add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw);
2289 hitDepth = 1000.0f;
2290 if (npc_raycast_down_around(COLLIDER_FLAG_IGNORE_PLAYER, &x, &y, &z, &hitDepth, partner->yaw, partner->collisionDiameter)) {
2292 s32 surfaceType = get_collider_flags(NpcHitQueryColliderID);
2293
2294 if ((surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) || (hitDepth > 100.0f)) {
2295 moveToX = playerStatus->pos.x;
2296 moveToY = playerStatus->pos.y;
2297 moveToZ = playerStatus->pos.z;
2298 add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw);
2299 }
2300 } else {
2301 moveToX = playerStatus->pos.x;
2302 moveToY = playerStatus->pos.y;
2303 moveToZ = playerStatus->pos.z;
2304 add_vec2D_polar(&x, &z, 2.0f, gCameras[gCurrentCameraID].curYaw);
2305 }
2306 }
2307
2308 x = partner->pos.x = playerStatus->pos.x;
2309 y = partner->pos.y = playerStatus->pos.y + (playerStatus->colliderHeight / 2);
2310 z = partner->pos.z = playerStatus->pos.z;
2311
2312 partner->moveSpeed = 4.0f;
2313 partner->jumpScale = 1.2f;
2314 partner->planarFlyDist = dist2D(x, z, moveToX, moveToZ);
2315 partner->yaw = atan2(x, z, moveToX, moveToZ);
2316 partner->duration = partner->planarFlyDist / partner->moveSpeed;
2317 if (partner->duration < 10) {
2318 partner->duration = 10;
2319 partner->moveSpeed = partner->planarFlyDist / partner->duration;
2320 }
2321 partner->jumpVel = (moveToY - y + (partner->jumpScale * partner->duration * partner->duration * 0.5f)) /
2322 partner->duration;
2324 y = moveToY - y;
2326 break;
2327 case 1:
2328 if (partner->jumpVel < 0.0f && npc_try_snap_to_ground(partner, fabsf(partner->jumpVel))) {
2330 break;
2331 }
2332 partner->jumpVel -= partner->jumpScale;
2333 partner->pos.y += partner->jumpVel;
2334 if (partner->jumpVel <= 0.0f) {
2336 }
2337 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
2338 npc_do_world_collision(partner);
2339 var_f0 = partner->duration;
2340 if (var_f0 > 10.0f) {
2341 var_f0 = 10.0f;
2342 }
2343
2344 partner->scale.x = (10.0f - var_f0) / 10.0f;
2345 partner->scale.y = partner->scale.x;
2346 partner->scale.z = partner->scale.x;
2347
2348 partner->duration--;
2349 if (partner->duration < 0) {
2351 }
2352 break;
2353 case 2:
2354 partner->pos.y = partner->moveToPos.y;
2355 partner->jumpVel = 0.0f;
2356 partner->scale.x = 1.0f;
2357 partner->scale.y = 1.0f;
2358 partner->scale.z = 1.0f;
2359 partner->moveToPos.x = partner->pos.x;
2360 partner->moveToPos.y = partner->pos.y;
2361 partner->moveToPos.z = partner->pos.z;
2362 partner->pos.x = partner->pos.x;
2363 partner->pos.y = playerStatus->pos.y;
2364 if (wPartner->isFlying) {
2365 partner->pos.y = playerStatus->pos.y;
2366 }
2367 partner->pos.z = partner->pos.z;
2369 partner->pos.x = partner->moveToPos.x;
2370 partner->pos.y = partner->moveToPos.y;
2371 partner->pos.z = partner->moveToPos.z;
2372 if (partner->flags & NPC_FLAG_GROUNDED) {
2373 if (!wPartner->isFlying) {
2375 }
2376 }
2377 return TRUE;
2378 }
2379 return FALSE;
2380}
#define clamp_angle
#define atan2
@ SURFACE_TYPE_LAVA
Definition enums.h:4673
@ SURFACE_TYPE_SPIKES
Definition enums.h:4672
@ SURFACE_INTERACT_LAND
Definition enums.h:4686
@ NPC_FLAG_GROUNDED
Definition enums.h:3010
f32 fabsf(f32 f)
b32 npc_raycast_down_around(s32, f32 *, f32 *, f32 *, f32 *, f32, f32)
s32 get_collider_flags(s32 colliderID)
Definition collision.c:481
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
void add_vec2D_polar(f32 *x, f32 *y, f32 r, f32 theta)
Definition 43F0.c:685
s32 npc_try_snap_to_ground(Npc *npc, f32 velocity)
Definition npc.c:581
void npc_surface_spawn_fx(Npc *npc, SurfaceInteractMode mode)
Definition surfaces.c:394
void npc_do_world_collision(Npc *npc)
Definition npc.c:278
void npc_move_heading(Npc *npc, f32 speed, f32 yaw)
Definition npc.c:986
PartnerAnimations gPartnerAnimations[]
Definition partners.c:343
void partner_clear_player_tracking(Npc *partner)
Definition partners.c:2436
BSS s32 wCurrentPartnerId
Definition partners.c:57
BSS WorldPartner * wPartner
Definition partners.c:62
s16 collisionDiameter
f32 jumpScale
Vec3f scale
f32 jumpVel
AnimID curAnim
Vec3f moveToPos
f32 planarFlyDist
s16 collisionHeight
Vec3f pos
f32 moveSpeed
s16 duration
s32 NpcHitQueryColliderID
Camera gCameras[4]
Definition cam_main.c:17
PlayerStatus gPlayerStatus
Definition 77480.c:39
s32 gCurrentCameraID
Definition cam_math.c:4

◆ partner_init_put_away()

s32 partner_init_put_away ( Npc * partner)

Definition at line 2178 of file partners.c.

◆ partner_put_away()

s32 partner_put_away ( Npc * partner)

Definition at line 2185 of file partners.c.

2185 {
2186 PlayerStatus* playerStatus = &gPlayerStatus;
2187 f32 tempMoveToX;
2188 f32 tempMoveToY;
2189 f32 tempMoveToZ;
2190 f32 tempPosX;
2191 f32 tempPosZ;
2192 f32 tempPosY;
2193 f32 tempDuration;
2194
2195 switch (wPartnerFollowState){
2196 case 0:
2197 tempMoveToX = partner->pos.x;
2198 tempMoveToY = partner->pos.y;
2199 tempMoveToZ = partner->pos.z;
2200 partner->flags &= ~NPC_FLAG_GRAVITY;
2201 partner->flags &= ~NPC_FLAG_FLYING;
2202 tempPosX = playerStatus->pos.x;
2203 partner->moveToPos.x = tempPosX;
2204 tempPosY = playerStatus->pos.y + (playerStatus->colliderHeight / 2);
2205 partner->moveToPos.y = playerStatus->pos.y + (playerStatus->colliderHeight / 2);
2206 tempPosZ = playerStatus->pos.z;
2207 wSavedPartnerPosX = tempMoveToX;
2208 wSavedPartnerPosY = tempMoveToY;
2209 wSavedPartnerPosZ = tempMoveToZ;
2210 partner->moveSpeed = 4.0f;
2211 partner->jumpScale = 1.6f;
2212 partner->moveToPos.z = tempPosZ;
2213 partner->planarFlyDist = dist2D(tempMoveToX, tempMoveToZ, tempPosX, tempPosZ);
2214 partner->yaw = atan2(tempMoveToX, tempMoveToZ, tempPosX, tempPosZ);
2215 partner->duration = 15;
2216 partner->moveSpeed = partner->planarFlyDist / partner->duration;
2217 tempMoveToY = tempPosY - tempMoveToY;
2218 partner->jumpVel = (tempMoveToY + partner->jumpScale * partner->duration * partner->duration * 0.5f) / partner->duration;
2220 enable_npc_blur(partner);
2222 break;
2223 case 1:
2224 partner->jumpVel -= partner->jumpScale;
2225 partner->pos.y += partner->jumpVel;
2226 if (partner->jumpVel <= 0.0f) {
2228 }
2229 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
2230 tempDuration = partner->duration;
2231 if (partner->duration > 10.0f) {
2232 tempDuration = 10.0f;
2233 }
2234 partner->scale.x = tempDuration / 10.0f;
2235 partner->scale.y = partner->scale.x;
2236 partner->scale.z = partner->scale.x;
2237 partner->duration--;
2238 if (partner->duration < 0) {
2240 }
2241 break;
2242 case 2:
2244 partner->jumpVel = 0.0f;
2245 partner->pos.y = partner->moveToPos.y;
2246 disable_npc_blur(partner);
2247 return TRUE;
2248 }
2249 return FALSE;
2250}
void disable_npc_blur(Npc *npc)
Definition npc.c:1088
void enable_npc_blur(Npc *npc)
Definition npc.c:1067
f32 wSavedPartnerPosZ
Definition partners.c:341
f32 wSavedPartnerPosX
Definition partners.c:339
f32 wSavedPartnerPosY
Definition partners.c:340

◆ partner_can_use_ability()

s32 partner_can_use_ability ( void )

Definition at line 993 of file partners.c.

993 {
995 return TRUE;
996 }
997 return FALSE;
998}
Npc * wPartnerNpc
Definition partners.c:43
PartnerBoolFunc canUseAbility
Definition partners.h:20

◆ partner_use_ability()

s32 partner_use_ability ( void )

Definition at line 964 of file partners.c.

964 {
965 PartnerStatus* partnerStatus = &gPartnerStatus;
966
968 && wPartner != NULL
970 {
971 if (gGameStatusPtr->multiplayerEnabled && (partnerStatus->curButtons & BUTTON_B)) {
973 } else if (wCurrentPartnerId != PARTNER_NONE) {
974 D_8010CFE0 = 1;
977 return TRUE;
978 }
979 }
980 return FALSE;
981}
@ BUTTON_B
Definition enums.h:2789
@ SOUND_MENU_ERROR
Definition enums.h:933
@ PARTNER_NONE
Definition enums.h:2885
@ PARTNER_CMD_USE_ABILITY
Definition enums.h:2953
s32 is_starting_conversation(void)
Definition encounter.c:2818
PartnerStatus gPartnerStatus
Definition partners.c:42
BSS s32 NextPartnerCommand
Definition partners.c:61
BSS s32 D_8010CFE0
Definition partners.c:59
void _use_partner_ability(void)
Definition partners.c:625
void sfx_play_sound(s32 soundID)
Definition sfx.c:517
GameStatus * gGameStatusPtr
Definition main_loop.c:32

◆ partner_do_player_collision()

void partner_do_player_collision ( Npc * partner)

Definition at line 2495 of file partners.c.

2495 {
2496 PlayerStatus* playerStatus = &gPlayerStatus;
2497 f32 playerScreenX;
2498 f32 playerScreenY;
2499 f32 playerScreenZ;
2500 f32 partnerScreenX;
2501 f32 partnerScreenY;
2502 f32 partnerScreenZ;
2503 f32 W;
2504
2505 transform_point(gCameras[CAM_DEFAULT].mtxPerspective,
2506 playerStatus->pos.x, playerStatus->pos.y, playerStatus->pos.z, 1.0f,
2507 &playerScreenX, &playerScreenY, &playerScreenZ, &W);
2508 transform_point(gCameras[CAM_DEFAULT].mtxPerspective, partner->pos.x, partner->pos.y, partner->pos.z, 1.0f,
2509 &partnerScreenX, &partnerScreenY, &partnerScreenZ, &W);
2510 playerScreenX = fabsf(playerScreenX - partnerScreenX);
2511 playerScreenY = fabsf(playerScreenY - partnerScreenY);
2512 playerScreenZ = fabsf(playerScreenZ - partnerScreenZ);
2513 if (playerScreenX <= (partner->collisionDiameter + playerStatus->colliderDiameter) * 0.9f &&
2514 playerScreenY <= partner->collisionHeight + playerStatus->colliderHeight && playerScreenZ <= 4.0)
2515 {
2516 npc_move_heading(partner, 1.0f,
2517 atan2(playerStatus->pos.x, playerStatus->pos.z, partner->pos.x, partner->pos.z));
2518 add_vec2D_polar(&partner->pos.x, &partner->pos.z, 2.0f, gCameras[gCurrentCameraID].curYaw);
2519 }
2520}
#define transform_point
@ CAM_DEFAULT
Definition enums.h:1800

Referenced by partner_flying_update_motion(), and partner_walking_update_motion().

◆ partner_walking_follow_player()

void partner_walking_follow_player ( Npc * partner)

Definition at line 1231 of file partners.c.

1231 {
1232 PlayerStatus* playerStatus = &gPlayerStatus;
1233 Camera* cameras = &gCameras[CAM_DEFAULT];
1234 s32 surfaceType;
1235 f32 moveHistoryX, moveHistoryY, moveHistoryZ;
1236 f32 x, y, z;
1237 f32 distance;
1238 f32 yaw;
1239 f32 temp_a3;
1240 f32 angle;
1241 s32 var_a1;
1242 PlayerPathElement* currentSnapshot;
1243
1244 switch (wPartnerFollowState) {
1245 case 0:
1246 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1247 moveHistoryX = currentSnapshot->pos.x;
1248 moveHistoryZ = currentSnapshot->pos.z;
1249 x = partner->pos.x;
1250 y = partner->pos.y;
1251 z = partner->pos.z;
1252 partner->moveSpeed = 3.0f;
1253
1254 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1255 if (distance >= 50.0) {
1256 partner->moveSpeed = !(playerStatus->animFlags & PA_FLAG_SPINNING) ? 5.0f : 7.0f;
1257 }
1258 if (wPartnerTetherDistance < 20.0) {
1259 partner->moveSpeed = 4.0f;
1260 }
1262 if (!(partner->flags & NPC_FLAG_GROUNDED)) {
1264 }
1265 while (TRUE) {
1266 distance = dist2D(x, z, moveHistoryX, moveHistoryZ);
1267 yaw = atan2(x, z, moveHistoryX, moveHistoryZ);
1268 if (partner->moveSpeed < distance) {
1269 distance = dist2D(x, z, playerStatus->pos.x, playerStatus->pos.z);
1270 if (distance >= 50.0) {
1271 break;
1272 }
1273 if (wPartnerTetherDistance < distance) {
1274 partner->moveSpeed = distance - wPartnerTetherDistance;
1275 if (partner->moveSpeed > 3.0) {
1276 partner->moveSpeed = 3.0f;
1277 if (wPartnerTetherDistance < 20.0f) {
1278 partner->moveSpeed = 4.0f;
1279 }
1280 } else {
1281 partner->moveSpeed += 1.0;
1282 }
1283 break;
1284 } else {
1285 partner->moveSpeed = 0.0f;
1286 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1287 }
1288 }
1290 yaw = partner->yaw;
1291 partner->moveSpeed = 0.0f;
1292 partner->jumpScale = 0.0f;
1295 break;
1296 } else {
1297 D_8010CFBC++;
1298 if (D_8010CFBC >= 40) {
1299 D_8010CFBC = 0;
1300 }
1301 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1302 moveHistoryX = currentSnapshot->pos.x;
1303 moveHistoryZ = currentSnapshot->pos.z;
1304
1305 if (fabsf(get_clamped_angle_diff(partner->yaw, atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ))) > 90.0f) {
1307 break;
1308 }
1309
1310 if ((partner->flags & NPC_FLAG_GROUNDED) && currentSnapshot->isJumping) {
1312 break;
1313 }
1314 }
1315 }
1316
1317 if (!(partner->flags & NPC_FLAG_GROUNDED)) {
1318 partner->moveSpeed *= 0.5f;
1319 }
1320 partner->yaw = yaw;
1321 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
1323 surfaceType = get_collider_flags(partner->curFloor);
1324 if (surfaceType == SURFACE_TYPE_SPIKES
1325 || surfaceType == SURFACE_TYPE_LAVA
1326 || ((partner->flags & NPC_FLAG_GROUNDED) && (partner->flags & NPC_FLAG_COLLDING_FORWARD_WITH_WORLD))
1327 ) {
1328 if (!func_800EA4B0(partner->curWall)) {
1329 D_8010CFBC++;
1330 if (D_8010CFBC >= 40) {
1331 D_8010CFBC = 0;
1332 }
1333 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1334 moveHistoryX = currentSnapshot->pos.x;
1335 moveHistoryZ = currentSnapshot->pos.z;
1336 if (fabsf(get_clamped_angle_diff(partner->yaw, atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ))) > 90.0f) {
1338 return;
1339 }
1340 } else {
1342 return;
1343 }
1344 }
1345 break;
1346 case 1:
1347 surfaceType = get_collider_flags(partner->curFloor);
1349 if (surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) {
1350 moveHistoryX = partner->pos.x;
1351 moveHistoryY = playerStatus->pos.y;
1352 moveHistoryZ = partner->pos.z;
1353 add_vec2D_polar(&moveHistoryX, &moveHistoryZ, 6.0f, atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z));
1354 } else {
1355 break;
1356 }
1357 } else {
1358 D_8010CFBC++;
1359 if (D_8010CFBC >= 40) {
1360 D_8010CFBC = 0;
1361 }
1362 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1363 moveHistoryX = currentSnapshot->pos.x;
1364 moveHistoryY = currentSnapshot->pos.y;
1365 moveHistoryZ = currentSnapshot->pos.z;
1366 }
1367 partner->moveToPos.x = moveHistoryX;
1368 partner->moveToPos.y = moveHistoryY;
1369 partner->moveToPos.z = moveHistoryZ;
1370 partner->duration = 0;
1371 partner->jumpScale = 3.0f;
1372 partner->moveSpeed = 6.0f;
1373 partner->planarFlyDist = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1374 partner->yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1375 if (partner->planarFlyDist > 50.0) {
1376 partner->planarFlyDist = 50.0f;
1377 }
1378 distance = partner->planarFlyDist;
1379 y = partner->moveToPos.y - partner->pos.y;
1380 if (distance < wPartnerTetherDistance && !(surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA)) {
1381 partner->jumpVel = 0.0f;
1382 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1384 return;
1385 }
1386 partner->duration = distance / partner->moveSpeed;
1387 if (partner->duration < 10) {
1388 partner->duration = 10;
1389 }
1390 partner->moveSpeed = partner->planarFlyDist / partner->duration;
1391 partner->jumpVel = (y + partner->jumpScale * partner->duration * partner->duration * 0.5f) / partner->duration;
1392 if (partner->jumpVel > 20.0) {
1393 partner->jumpVel = 20.0f;
1394 }
1395 if (partner->jumpVel < 0.0) {
1396 partner->jumpVel = 0.0f;
1397 }
1398 if (!(surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA)) {
1400 } else {
1402 }
1403
1404 partner->moveToPos.x = partner->pos.x;
1405 partner->moveToPos.y = partner->pos.y;
1406 partner->moveToPos.z = partner->pos.z;
1407 partner->flags |= NPC_FLAG_JUMPING;
1409 // fallthrough
1410 case 2:
1411 partner->jumpVel -= partner->jumpScale;
1412 partner->pos.y += partner->jumpVel;
1413 if (partner->jumpVel <= 0.0f) {
1415 }
1416 if (partner->pos.y < -2000.0f) {
1418 partner->flags &= ~NPC_FLAG_JUMPING;
1419 partner->jumpVel = 0.0f;
1420 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1421 partner->pos.x = playerStatus->pos.x;
1422 partner->pos.y = playerStatus->pos.y;
1423 partner->pos.z = playerStatus->pos.z;
1425 return;
1426 }
1427 if (partner->jumpVel <= 0.0f) {
1428 distance = fabsf(partner->jumpVel) + 11.0f;
1429 x = partner->pos.x;
1430 y = partner->pos.y + distance;
1431 z = partner->pos.z;
1432 if (npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) != 0) {
1433 if (distance <= fabsf(partner->jumpVel) + 22.0f) {
1435 partner->flags &= ~NPC_FLAG_JUMPING;
1436 partner->jumpVel = 0.0f;
1437 partner->pos.y = y;
1438 partner->yaw = atan2(x, z, playerStatus->pos.x, playerStatus->pos.z);
1441 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1442 if (distance < 5.0) {
1443 partner->pos.x = playerStatus->pos.x;
1444 partner->pos.y = playerStatus->pos.y;
1445 partner->pos.z = playerStatus->pos.z;
1446 add_vec2D_polar(&partner->pos.x, &partner->pos.z, 5.0f, clamp_angle((cameras[CAM_DEFAULT].curYaw + 90.0f) - playerStatus->spriteFacingAngle));
1448 }
1449 break;
1450 }
1451 }
1452 }
1453 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
1454 break;
1455 case 5:
1456 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1457 moveHistoryX = currentSnapshot->pos.x;
1458 moveHistoryZ = currentSnapshot->pos.z;
1459 x = partner->pos.x;
1460 y = partner->pos.y;
1461 z = partner->pos.z;
1462 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1463 if (distance <= wPartnerTetherDistance) {
1464 if (D_8010CFCA == 0) {
1465 partner->moveSpeed = 0.0f;
1466 partner->jumpScale = 0.0f;
1468 if (playerStatus->actionState == ACTION_STATE_TALK) {
1469 D_8010CFCA = 0;
1470 }
1471 surfaceType = get_collider_flags(partner->curFloor);
1472 if (surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) {
1474 return;
1475 }
1476 } else {
1477 temp_a3 = clamp_angle(cameras[CAM_DEFAULT].curYaw + (playerStatus->spriteFacingAngle < 180.0f ? 90.0f : -90.0f));
1478 partner->moveToPos.x = playerStatus->pos.x;
1479 partner->moveToPos.y = playerStatus->pos.y;
1480 partner->moveToPos.z = playerStatus->pos.z;
1481 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, wPartnerTetherDistance - 10.0f, temp_a3);
1482 yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1483 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1484 partner->moveSpeed = 2.0f;
1485 if (distance > 2.0f) {
1486 partner->yaw = yaw;
1488 if (!(partner->flags & NPC_FLAG_COLLDING_FORWARD_WITH_WORLD)) {
1489 D_800F803A = 0;
1490 } else {
1491 D_800F803A++;
1492 if (D_800F803A > 10) {
1493 yaw = playerStatus->targetYaw;
1494 partner->moveSpeed = 0.0f;
1495 partner->jumpScale = 0.0f;
1496 partner->renderYaw = yaw;
1498 if (D_8010CFCA == 2 || playerStatus->actionState == ACTION_STATE_TALK) {
1499 D_8010CFCA = 0;
1500 }
1501 }
1502 }
1503 } else {
1504 yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1505 partner->yaw = yaw;
1506 partner->moveSpeed = 0.0f;
1507 partner->jumpScale = 0.0f;
1509 if (D_8010CFCA == 2 || playerStatus->actionState == ACTION_STATE_TALK) {
1510 D_8010CFCA = 0;
1511 }
1512 }
1513 partner->yaw = yaw;
1514 npc_move_heading(partner, partner->moveSpeed, yaw);
1516 distance = 1000.0f;
1517 x = partner->pos.x;
1518 z = partner->pos.z;
1519 y = partner->pos.y + partner->collisionHeight;
1520 if (npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) != 0) {
1521 s32 surfaceType = get_collider_flags(NpcHitQueryColliderID);
1522 if (surfaceType == SURFACE_TYPE_SPIKES || surfaceType == SURFACE_TYPE_LAVA) {
1523 partner->yaw = clamp_angle(yaw + 180.0f);
1524 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
1525 partner->moveSpeed = 0.0f;
1526 partner->jumpScale = 0.0f;
1528 if (D_8010CFCA == 2) {
1529 D_8010CFCA = 0;
1530 } else if (playerStatus->actionState == ACTION_STATE_TALK) {
1531 D_8010CFCA = 0;
1532 }
1533 } else if (!func_800EA4B0(NpcHitQueryColliderID)) {
1534 D_8010CFCA = 2;
1535 }
1536 }
1537 break;
1538 }
1539 }
1540 distance = dist2D(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1541 if (distance <= wPartnerTetherDistance) {
1543 D_8010CFCA = 2;
1544 }
1545 } else {
1546 while (TRUE) {
1547 if (currentSnapshot->isJumping) {
1548 break;
1549 }
1550 yaw = atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ);
1551 if (fabsf(get_clamped_angle_diff(yaw, atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z))) < 90.0f) {
1552 break;
1553 }
1555 break;
1556 }
1557 D_8010CFBC++;
1558 if (D_8010CFBC >= 40) {
1559 D_8010CFBC = 0;
1560 }
1561 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1562 moveHistoryX = currentSnapshot->pos.x;
1563 moveHistoryZ = currentSnapshot->pos.z;
1564 }
1565 if (!currentSnapshot->isJumping) {
1567 return;
1568 }
1569 while (TRUE) {
1570 if (!currentSnapshot->isJumping) {
1571 break;
1572 }
1573 yaw = atan2(partner->pos.x, partner->pos.z, moveHistoryX, moveHistoryZ);
1574 if (fabsf(get_clamped_angle_diff(yaw, atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z))) < 90.0f) {
1575 break;
1576 }
1578 break;
1579 }
1580 D_8010CFBC++;
1581 if (D_8010CFBC >= 40) {
1582 D_8010CFBC = 0;
1583 }
1584 currentSnapshot = &gPlayerMoveHistory[D_8010CFBC];
1585 moveHistoryX = currentSnapshot->pos.x;
1586 moveHistoryZ = currentSnapshot->pos.z;
1587 }
1589 return;
1590 }
1591 break;
1592 case 15:
1593 switch (D_8010CFCE) {
1594 case 0:
1595 angle = clamp_angle(player_get_side_angle() + 180.0f);
1596 partner->moveToPos.x = playerStatus->pos.x;
1597 partner->moveToPos.y = playerStatus->pos.y;
1598 partner->moveToPos.z = playerStatus->pos.z;
1599 add_vec2D_polar(&partner->moveToPos.x, &partner->moveToPos.z, playerStatus->colliderDiameter, angle);
1600 distance = dist2D(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1602 partner->moveSpeed = wPartnerMoveSpeed;
1604 yaw = atan2(partner->pos.x, partner->pos.z, partner->moveToPos.x, partner->moveToPos.z);
1605 partner->yaw = D_800F8034 = yaw;
1606 D_8010CFCE++;
1607 // fallthrough
1608 case 1:
1609 if (wPartnerMoveTime != 0) {
1611 if (partner->jumpScale != 0.0f) {
1612 partner->jumpVel -= partner->jumpScale;
1613 partner->pos.y += partner->jumpVel;
1614 if (partner->jumpVel <= 0.0f) {
1616 }
1617 if (partner->jumpVel <= 0.0f) {
1618 distance = fabsf(partner->jumpVel) + 11.0f;
1619 x = partner->pos.x;
1620 y = partner->pos.y + distance;
1621 z = partner->pos.z;
1622 if ((npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) != 0) && (distance <= (fabsf(partner->jumpVel) + 22.0f))) {
1624 partner->jumpScale = 0.0f;
1625 partner->jumpVel = 0.0f;
1626 partner->pos.y = y;
1627 partner->flags &= ~NPC_FLAG_JUMPING;
1628 }
1629 }
1630 }
1631 partner->moveSpeed = wPartnerMoveSpeed;
1632 partner->yaw = D_800F8034;
1633 npc_move_heading(partner, partner->moveSpeed, partner->yaw);
1635 } else {
1637 partner->moveSpeed = 0.0f;
1638 partner->jumpScale = 0.0f;
1640 partner->yaw = clamp_angle((cameras[CAM_DEFAULT].curYaw + 270.0f) - playerStatus->spriteFacingAngle);
1641 wPartnerMoveTime = 30;
1642 D_8010CFCE++;
1643 }
1644 return;
1645 case 2:
1646 if (wPartnerMoveTime != 0) {
1648 return;
1649 }
1651 D_8010CFCA = 0;
1652 D_8010CFCE = 0;
1653 }
1654 break;
1655 case 20:
1656 partner_move_to_goal(partner, FALSE);
1657 break;
1658 case 40:
1659 if (partner->flags & NPC_FLAG_GROUNDED) {
1660 if (func_800EA4B0(partner->curFloor)) {
1663 } else {
1665 }
1666 break;
1667 }
1668 partner->jumpScale = 3.0f;
1669 partner->jumpVel -= partner->jumpScale;
1670 partner->pos.y += partner->jumpVel;
1671 if (partner->jumpVel <= 0.0f) {
1673 }
1674 if (partner->pos.y < -2000.0f) {
1676 partner->flags &= ~NPC_FLAG_JUMPING;
1677 partner->jumpVel = 0.0f;
1678 partner->yaw = atan2(partner->pos.x, partner->pos.z, playerStatus->pos.x, playerStatus->pos.z);
1679 partner->pos.x = playerStatus->pos.x;
1680 partner->pos.y = playerStatus->pos.y;
1681 partner->pos.z = playerStatus->pos.z;
1683 return;
1684 }
1685 distance = fabsf(partner->jumpVel) + 11.0f;
1686 x = partner->pos.x;
1687 y = partner->pos.y + distance;
1688 z = partner->pos.z;
1689 if (npc_raycast_down_around(partner->collisionChannel, &x, &y, &z, &distance, partner->yaw, partner->collisionDiameter) != 0) {
1691 partner->flags &= ~NPC_FLAG_JUMPING;
1692 partner->jumpVel = 0.0f;
1693 partner->pos.y = y;
1694 partner->yaw = atan2(x, z, playerStatus->pos.x, playerStatus->pos.z);
1697 }
1698 break;
1699 case 50:
1700 break;
1701 }
1702}
@ PARTNER_ANIM_INDEX_RUN
Definition enums.h:3408
@ PARTNER_ANIM_INDEX_WALK
Definition enums.h:3403
@ PA_FLAG_SPINNING
Definition enums.h:3107
@ ACTION_STATE_TALK
Reading signs doesn't count.
Definition enums.h:2440
@ SURFACE_INTERACT_RUN
Definition enums.h:4685
@ SURFACE_INTERACT_WALK
Definition enums.h:4684
@ NPC_FLAG_JUMPING
Definition enums.h:3009
@ NPC_FLAG_COLLDING_FORWARD_WITH_WORLD
Definition enums.h:3012
f32 player_get_side_angle(void)
Definition 7BB60.c:1178
f32 get_clamped_angle_diff(f32, f32)
Definition 43F0.c:606
BSS PlayerPathElement gPlayerMoveHistory[40]
Definition partners.c:46
BSS s32 gPlayerMoveHistoryIndex
Definition partners.c:47
s16 D_800F803A
Definition partners.c:165
s32 func_800EA4B0(s32 collisionID)
Definition partners.c:497
BSS s32 D_8010CFBC
Definition partners.c:48
BSS s16 D_8010CFCA
Definition partners.c:52
s32 wPartnerMoveTime
Definition partners.c:161
f32 D_800F8034
Definition partners.c:163
BSS f32 wPartnerTetherDistance
Definition partners.c:49
f32 wPartnerMoveSpeed
Definition partners.c:162
void partner_move_to_goal(Npc *, s32)
Definition partners.c:2522
BSS s16 D_8010CFCE
Definition partners.c:54
f32 renderYaw
s16 curFloor
s16 curWall

Referenced by partner_walking_update_motion().

◆ func_800EA52C()

s32 func_800EA52C ( s32 partnerID)

Definition at line 537 of file partners.c.

537 {
538 PlayerStatus* playerStatus = &gPlayerStatus;
539 u32 playerActionState = playerStatus->actionState;
540 s32 ret = FALSE;
541
542 if (playerStatus->flags & PS_FLAG_HIT_FIRE) {
543 return FALSE;
544 }
545
546 // any partner
547 if (playerActionState == ACTION_STATE_IDLE
548 || playerActionState == ACTION_STATE_WALK
549 || playerActionState == ACTION_STATE_RUN
550 ) {
551 ret = TRUE;
552 }
553
554 // check specific partners
555 if (partnerID == PARTNER_BOW) {
556 if (playerActionState == ACTION_STATE_RIDE) {
557 ret = TRUE;
558 }
559 } else if (partnerID == PARTNER_PARAKARRY) {
560 if (playerActionState == ACTION_STATE_RIDE
561 || playerActionState == ACTION_STATE_IDLE
562 || playerActionState == ACTION_STATE_WALK
563 || playerActionState == ACTION_STATE_RUN
564 ) {
565 ret = TRUE;
566 }
567 }
568
569 return ret;
570}
@ PS_FLAG_HIT_FIRE
Definition enums.h:3050
@ PARTNER_BOW
Definition enums.h:2894
@ PARTNER_PARAKARRY
Definition enums.h:2889
@ ACTION_STATE_RIDE
Definition enums.h:2461
@ ACTION_STATE_IDLE
Definition enums.h:2426
@ ACTION_STATE_WALK
Definition enums.h:2427
@ ACTION_STATE_RUN
Definition enums.h:2428

◆ partner_force_player_flip_done()

s32 partner_force_player_flip_done ( void )

Definition at line 2454 of file partners.c.

2454 {
2455 PlayerStatus* playerStatus = &gPlayerStatus;
2456 Camera* cameras = gCameras;
2457 s32 isFacingLeft;
2458
2459 if (playerStatus->flipYaw[CAM_DEFAULT] == 0.0f) {
2460 if (!(playerStatus->spriteFacingAngle >= 90.0f) || !(playerStatus->spriteFacingAngle < 270.0f)) {
2461 isFacingLeft = TRUE;
2462 playerStatus->targetYaw = clamp_angle(cameras[CAM_DEFAULT].curYaw - 90.0f);
2463 } else {
2464 isFacingLeft = FALSE;
2465 playerStatus->targetYaw = clamp_angle(cameras[CAM_DEFAULT].curYaw + 90.0f);
2466 }
2467 } else if (get_clamped_angle_diff(cameras[CAM_DEFAULT].curYaw, playerStatus->targetYaw) < 0.0f) {
2468 isFacingLeft = TRUE;
2469 playerStatus->targetYaw = clamp_angle(cameras[CAM_DEFAULT].curYaw - 90.0f);
2470
2471 } else {
2472 isFacingLeft = FALSE;
2473 playerStatus->targetYaw = clamp_angle(cameras[CAM_DEFAULT].curYaw + 90.0f);
2474 }
2475
2476 playerStatus->curYaw = playerStatus->targetYaw;
2477 return isFacingLeft;
2478}

◆ partner_suspend_ability_script()

void partner_suspend_ability_script ( void )

Definition at line 1117 of file partners.c.

1117 {
1118 if (wCurrentPartnerId != NULL) {
1121 }
1122 }
1123}
s32 suspend_all_script(s32 id)
s32 does_script_exist(s32 id)
BSS s32 wPartnerCurrentScriptID
Definition partners.c:58

◆ partner_resume_ability_script()

void partner_resume_ability_script ( void )

Definition at line 1125 of file partners.c.

1125 {
1126 if (wCurrentPartnerId != NULL) {
1129 }
1130 }
1131}
s32 resume_all_script(s32 id)

◆ partner_enable_input()

void partner_enable_input ( void )

Definition at line 2480 of file partners.c.

2480 {
2481 PartnerStatus* partnerStatus = &gPartnerStatus;
2482
2483 partnerStatus->inputDisabledCount--;
2484 if (partnerStatus->inputDisabledCount < 0) {
2485 partnerStatus->inputDisabledCount = 0;
2486 }
2487}

Referenced by check_input_open_menus(), SentinelAI_GrabPlayer(), update_encounters_conversation(), update_encounters_post_battle(), and update_item_entity_pickup().

Variable Documentation

◆ wPartnerNpc