sm64pc/src/game/behaviors/dorrie.inc.c

174 lines
5.5 KiB
C

void dorrie_raise_head(void) {
s16 startAngle;
f32 xzDisp;
f32 yDisp;
startAngle = o->oDorrieNeckAngle;
o->oDorrieNeckAngle -= (s16) absf(370.0f * sins(o->oDorrieHeadRaiseSpeed));
xzDisp = 440.0f * (coss(o->oDorrieNeckAngle) - coss(startAngle));
yDisp = 440.0f * (sins(o->oDorrieNeckAngle) - sins(startAngle));
set_mario_pos(gMarioObject->oPosX + xzDisp * sins(o->oMoveAngleYaw), gMarioObject->oPosY - yDisp,
gMarioObject->oPosZ + xzDisp * coss(o->oMoveAngleYaw));
}
void dorrie_act_move(void) {
s16 startYaw;
s16 targetYaw;
s16 targetSpeed;
s16 circularTurn;
startYaw = o->oMoveAngleYaw;
o->oDorrieNeckAngle = -0x26F4;
cur_obj_init_animation_with_sound(1);
if (o->oDorrieForwardDistToMario < 320.0f && o->oDorrieGroundPounded) {
cur_obj_play_sound_2(SOUND_OBJ_DORRIE);
o->collisionData = segmented_to_virtual(dorrie_seg6_collision_0600FBB8);
o->oAction = DORRIE_ACT_LOWER_HEAD;
o->oForwardVel = 0.0f;
o->oDorrieYawVel = 0;
} else {
if (gMarioObject->platform == o) {
targetYaw = gMarioObject->oFaceAngleYaw;
targetSpeed = 10;
} else {
circularTurn = 0x4000 - atan2s(2000.0f, o->oDorrieDistToHome - 2000.0f);
if ((s16)(o->oMoveAngleYaw - o->oDorrieAngleToHome) < 0) {
circularTurn = -circularTurn;
}
targetYaw = o->oDorrieAngleToHome + circularTurn;
targetSpeed = 5;
}
obj_forward_vel_approach(targetSpeed, 0.5f);
o->oDorrieYawVel =
approach_s16_symmetric(o->oDorrieYawVel, (s16)(targetYaw - o->oMoveAngleYaw) / 50, 5);
o->oMoveAngleYaw += o->oDorrieYawVel;
}
o->oAngleVelYaw = o->oMoveAngleYaw - startYaw;
}
void dorrie_begin_head_raise(s32 liftingMario) {
o->oDorrieLiftingMario = liftingMario;
o->oAction = DORRIE_ACT_RAISE_HEAD;
o->oDorrieHeadRaiseSpeed = 0;
}
void dorrie_act_lower_head(void) {
if (cur_obj_init_anim_check_frame(2, 35)) {
cur_obj_reverse_animation();
#ifdef VERSION_JP
if (o->oTimer > 150) {
dorrie_begin_head_raise(FALSE);
} else if (gMarioObject->platform == o) {
if (o->oDorrieForwardDistToMario > 830.0f && set_mario_npc_dialog(2) == 1) {
dorrie_begin_head_raise(TRUE);
} else if (o->oDorrieForwardDistToMario > 320.0f) {
o->oTimer = 0;
}
}
#else
if (gMarioObject->platform == o) {
if (o->oDorrieOffsetY == -17.0f && o->oDorrieForwardDistToMario > 780.0f
&& set_mario_npc_dialog(2) == 1) {
dorrie_begin_head_raise(TRUE);
} else if (o->oDorrieForwardDistToMario > 320.0f) {
o->oTimer = 0;
}
} else if (o->oTimer > 150) {
dorrie_begin_head_raise(FALSE);
}
#endif
} else {
o->oDorrieNeckAngle += 0x115;
}
}
void dorrie_act_raise_head(void) {
o->collisionData = segmented_to_virtual(dorrie_seg6_collision_0600F644);
if (cur_obj_check_if_near_animation_end()) {
o->oAction = DORRIE_ACT_MOVE;
} else if (o->oDorrieLiftingMario && o->header.gfx.unk38.animFrame < 74) {
if (set_mario_npc_dialog(2) == 2) {
o->oDorrieHeadRaiseSpeed += 0x1CC;
if (cur_obj_check_anim_frame(73)) {
set_mario_npc_dialog(0);
}
dorrie_raise_head();
} else {
cur_obj_reverse_animation();
}
}
}
void bhv_dorrie_update(void) {
f32 boundsShift;
UNUSED s32 unused1;
UNUSED s32 unused2;
f32 maxOffsetY;
if (!(o->activeFlags & 0x0008)) {
o->oDorrieForwardDistToMario = o->oDistanceToMario * coss(o->oAngleToMario - o->oMoveAngleYaw);
obj_perform_position_op(0);
cur_obj_move_using_fvel_and_gravity();
o->oDorrieAngleToHome = cur_obj_angle_to_home();
o->oDorrieDistToHome = cur_obj_lateral_dist_to_home();
// Shift dorrie's bounds to account for her neck
boundsShift =
440.0f * coss(o->oDorrieNeckAngle) * coss(o->oMoveAngleYaw - o->oDorrieAngleToHome);
if (clamp_f32(&o->oDorrieDistToHome, 1650.0f + boundsShift, 2300.0f + boundsShift)) {
o->oPosX = o->oHomeX - o->oDorrieDistToHome * sins(o->oDorrieAngleToHome);
o->oPosZ = o->oHomeZ - o->oDorrieDistToHome * coss(o->oDorrieAngleToHome);
}
o->oDorrieGroundPounded = cur_obj_is_mario_ground_pounding_platform();
if (gMarioObject->platform == o) {
maxOffsetY = -17.0f;
if (o->oDorrieOffsetY >= 0.0f) {
if (o->oDorrieGroundPounded) {
o->oDorrieVelY = -15.0f;
} else {
o->oDorrieVelY = -6.0f;
}
}
} else {
maxOffsetY = 0.0f;
}
o->oDorrieOffsetY += o->oDorrieVelY;
approach_f32_ptr(&o->oDorrieVelY, 3.0f, 1.0f);
if (o->oDorrieVelY > 0.0f && o->oDorrieOffsetY > maxOffsetY) {
o->oDorrieOffsetY = maxOffsetY;
}
o->oPosY = o->oHomeY + o->oDorrieOffsetY;
switch (o->oAction) {
case DORRIE_ACT_MOVE:
dorrie_act_move();
break;
case DORRIE_ACT_LOWER_HEAD:
dorrie_act_lower_head();
break;
case DORRIE_ACT_RAISE_HEAD:
dorrie_act_raise_head();
break;
}
obj_perform_position_op(1);
}
}