113 lines
3.2 KiB
C
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);
|
|
}
|