diff --git a/src/game/behaviors/eyerok.inc.c b/src/game/behaviors/eyerok.inc.c index a781638de..59f5868aa 100644 --- a/src/game/behaviors/eyerok.inc.c +++ b/src/game/behaviors/eyerok.inc.c @@ -13,13 +13,38 @@ struct ObjectHitbox sEyerokHitbox = { s8 D_80331BA4[] = { 0, 1, 3, 2, 1, 0 }; static u8 eyerokBossImmediateUpdate = FALSE; -static s32 eyerok_check_mario_relative_z(s32 arg0) { - struct Object* player = nearest_player_to_object(o); - if (player && player->oPosZ - o->oHomeZ < arg0) { - return TRUE; - } else { - return FALSE; +static s32 eyerok_check_mario_relative_z(s32 zDist) { + for (s32 i = 0; i < MAX_PLAYERS; i++) { + struct MarioState* m = &gMarioStates[i]; + if (m->marioObj == NULL) { continue; } + if (is_player_active(m) && m->marioObj->oPosZ - o->oHomeZ >= zDist) { + return FALSE; + } } + return TRUE; +} + +static struct Object* eyerok_nearest_targetable_player_to_object(s32 zDist) { + if (!o) { return NULL; } + struct Object* nearest = NULL; + f32 nearestDist = 0; + for (s32 i = 0; i < MAX_PLAYERS; i++) { + struct MarioState *m = &gMarioStates[i]; + if (!m->marioObj) { continue; } + if (m->marioObj == o) { continue; } + if (!m->visibleToEnemies) { continue; } + if (!is_player_active(m)) { continue; } + f32 dist = dist_between_objects(o, m->marioObj); + if (m->marioObj->oPosZ - o->oHomeZ < zDist) { + dist += 10000; // always prefer players that are not past z position + } + if (nearest == NULL || dist < nearestDist) { + nearest = m->marioObj; + nearestDist = dist; + } + } + + return nearest; } static struct Object* eyerok_spawn_hand(s16 side, s32 model, const BehaviorScript *behavior) { @@ -172,7 +197,7 @@ static void eyerok_boss_act_fight(void) { o->oEyerokBossUnk108 = 1.0f; } - struct Object* player = nearest_player_to_object(o); + struct Object* player = eyerok_nearest_targetable_player_to_object(400); if (player) { o->oEyerokBossUnk10C = player->oPosZ; } @@ -311,7 +336,7 @@ static void eyerok_hand_act_sleep(void) { static void eyerok_hand_act_idle(void) { if (!o->parentObj) { return; } - struct Object* player = nearest_player_to_object(o); + struct Object* player = eyerok_nearest_targetable_player_to_object(400); s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0; cur_obj_init_animation_with_sound(2); @@ -502,7 +527,7 @@ static void eyerok_hand_act_retreat(void) { static void eyerok_hand_act_target_mario(void) { if (!o->parentObj) { return; } - struct Object* player = nearest_player_to_object(o); + struct Object* player = eyerok_nearest_targetable_player_to_object(400); s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0; if (eyerok_check_mario_relative_z(400) != 0 || (player && o->oPosZ - player->oPosZ > 0.0f) || o->oPosZ - o->parentObj->oPosZ > 1700.0f || absf(o->oPosX - o->parentObj->oPosX) > 900.0f @@ -519,7 +544,7 @@ static void eyerok_hand_act_target_mario(void) { } static void eyerok_hand_act_smash(void) { - struct Object* player = nearest_player_to_object(o); + struct Object* player = eyerok_nearest_targetable_player_to_object(400); s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000; s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0; s16 sp1E; @@ -549,7 +574,7 @@ static void eyerok_hand_act_smash(void) { } static void eyerok_hand_act_fist_push(void) { - struct Object* player = nearest_player_to_object(o); + struct Object* player = eyerok_nearest_targetable_player_to_object(400); if (o->oTimer > 5 && ((player && o->oPosZ - player->oPosZ > 0.0f) || (o->oMoveFlags & OBJ_MOVE_HIT_EDGE))) { o->oAction = EYEROK_HAND_ACT_FIST_SWEEP; o->oForwardVel = 0.0f;