From f4e6cd0894a3d31645baab11e3af2fb3faec9d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emily=E2=99=A5?= <77174187+EmilyEmmi@users.noreply.github.com> Date: Fri, 16 May 2025 13:01:10 -0400 Subject: [PATCH] Fix Eyerok pounding in multiplayer (#805) * Fix Eyerok pounding in multiplayer Eyerok now only enters the double pound state if ALL players stand on the pedestal rather than just one. Players standing on the pedestal will be ignored. I had to write a new function for this, I hope this is acceptable. * Suggested changes I didn't want to change the name of arg0 in eyerok_check_mario_relative_z because it was a vanilla function, but I suppose I can. --- src/game/behaviors/eyerok.inc.c | 47 +++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) 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;