diff --git a/src/game/behaviors/butterfly.inc.c b/src/game/behaviors/butterfly.inc.c index d435d8d8..2cee0f25 100644 --- a/src/game/behaviors/butterfly.inc.c +++ b/src/game/behaviors/butterfly.inc.c @@ -42,15 +42,16 @@ void butterfly_step(s32 speed) { } 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; + struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ); + player->oPosX += 5 * o->oButterflyYPhase / 4; + player->oPosZ += 5 * o->oButterflyYPhase / 4; + obj_turn_toward_object(o, player, 16, 0x300); + player->oPosX -= 5 * o->oButterflyYPhase / 4; + player->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; + player->oPosY += (5 * o->oButterflyYPhase + 0x100) / 4; + obj_turn_toward_object(o, player, 15, 0x500); + player->oPosY -= (5 * o->oButterflyYPhase + 0x100) / 4; } void butterfly_act_rest(void) { @@ -58,7 +59,8 @@ void butterfly_act_rest(void) { cur_obj_init_animation(0); o->oAction = BUTTERFLY_ACT_FOLLOW_MARIO; - o->oMoveAngleYaw = gMarioObject->header.gfx.angle[1]; + struct Object* player = nearest_player_object(o->oPosX, o->oPosY, o->oPosZ); + o->oMoveAngleYaw = player->header.gfx.angle[1]; } } diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index f3774bc0..cadf366c 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -514,6 +514,27 @@ s32 is_point_within_radius_of_mario(f32 x, f32 y, f32 z, s32 dist) { return FALSE; } +/** + * Returns either gMarioObject or gLuigiObject depending on what is closer + */ +struct Object* nearest_player_object(f32 x, f32 y, f32 z) { + f32 mx = gMarioObject->header.gfx.pos[0] - x; + f32 my = gMarioObject->header.gfx.pos[1] - y; + f32 mz = gMarioObject->header.gfx.pos[2] - z; + mx *= mx; + my *= my; + mz *= mz; + + f32 lx = gLuigiObject->header.gfx.pos[0] - x; + f32 ly = gLuigiObject->header.gfx.pos[1] - y; + f32 lz = gLuigiObject->header.gfx.pos[2] - z; + lx *= lx; + ly *= ly; + lz *= lz; + + return (mx + my + mz <= lx + ly + lz) ? gMarioObject : gLuigiObject; +} + /** * Checks whether a point is within distance of a given point. Test is exclusive. */