sm64pc/src/game/behaviors/butterfly.inc.c
2020-04-03 14:57:26 -04:00

113 lines
3.2 KiB
C

// butterfly.c.inc
void bhv_butterfly_init(void) {
cur_obj_init_animation(1);
o->oButterflyYPhase = random_float() * 100.0f;
o->header.gfx.unk38.animFrame = random_float() * 7.0f;
o->oHomeX = o->oPosX;
o->oHomeY = o->oPosY;
o->oHomeZ = o->oPosZ;
}
// sp28 = speed
void butterfly_step(s32 speed) {
struct FloorGeometry *sp24;
s16 yaw = o->oMoveAngleYaw;
s16 pitch = o->oMoveAnglePitch;
s16 yPhase = o->oButterflyYPhase;
f32 floorY;
o->oVelX = sins(yaw) * (f32) speed;
o->oVelY = sins(pitch) * (f32) speed;
o->oVelZ = coss(yaw) * (f32) speed;
o->oPosX += o->oVelX;
o->oPosZ += o->oVelZ;
if (o->oAction == BUTTERFLY_ACT_FOLLOW_MARIO)
o->oPosY -= o->oVelY + coss((s32)(yPhase * 655.36)) * 20.0f / 4;
else
o->oPosY -= o->oVelY;
floorY = find_floor_height_and_data(o->oPosX, o->oPosY, o->oPosZ, &sp24);
if (o->oPosY < floorY + 2.0f)
o->oPosY = floorY + 2.0f;
o->oButterflyYPhase++;
if (o->oButterflyYPhase >= 101)
o->oButterflyYPhase = 0;
}
void butterfly_calculate_angle(void) {
gMarioObject->oPosX += 5 * o->oButterflyYPhase / 4;
gMarioObject->oPosZ += 5 * o->oButterflyYPhase / 4;
obj_turn_toward_object(o, gMarioObject, 16, 0x300);
gMarioObject->oPosX -= 5 * o->oButterflyYPhase / 4;
gMarioObject->oPosZ -= 5 * o->oButterflyYPhase / 4;
gMarioObject->oPosY += (5 * o->oButterflyYPhase + 0x100) / 4;
obj_turn_toward_object(o, gMarioObject, 15, 0x500);
gMarioObject->oPosY -= (5 * o->oButterflyYPhase + 0x100) / 4;
}
void butterfly_act_rest(void) {
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 1000)) {
cur_obj_init_animation(0);
o->oAction = BUTTERFLY_ACT_FOLLOW_MARIO;
o->oMoveAngleYaw = gMarioObject->header.gfx.angle[1];
}
}
void butterfly_act_follow_mario(void) {
butterfly_calculate_angle();
butterfly_step(7);
if (!is_point_within_radius_of_mario(o->oHomeX, o->oHomeY, o->oHomeZ, 1200))
o->oAction = BUTTERFLY_ACT_RETURN_HOME;
}
void butterfly_act_return_home(void) {
f32 homeDistX = o->oHomeX - o->oPosX;
f32 homeDistY = o->oHomeY - o->oPosY;
f32 homeDistZ = o->oHomeZ - o->oPosZ;
s16 hAngleToHome = atan2s(homeDistZ, homeDistX);
s16 vAngleToHome = atan2s(sqrtf(homeDistX * homeDistX + homeDistZ * homeDistZ), -homeDistY);
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, hAngleToHome, 0x800);
o->oMoveAnglePitch = approach_s16_symmetric(o->oMoveAnglePitch, vAngleToHome, 0x50);
butterfly_step(7);
if (homeDistX * homeDistX + homeDistY * homeDistY + homeDistZ * homeDistZ < 144.0f) {
cur_obj_init_animation(1);
o->oAction = BUTTERFLY_ACT_RESTING;
o->oPosX = o->oHomeX;
o->oPosY = o->oHomeY;
o->oPosZ = o->oHomeZ;
}
}
void bhv_butterfly_loop(void) {
switch (o->oAction) {
case BUTTERFLY_ACT_RESTING:
butterfly_act_rest();
break;
case BUTTERFLY_ACT_FOLLOW_MARIO:
butterfly_act_follow_mario();
break;
case BUTTERFLY_ACT_RETURN_HOME:
butterfly_act_return_home();
break;
}
set_object_visibility(o, 3000);
}