Synchronized piranha plant

This commit is contained in:
MysterD 2020-08-11 23:02:16 -07:00
parent aec993b5b6
commit 84ef9e97c1

View file

@ -22,8 +22,11 @@ void piranha_plant_act_idle(void) {
cur_obj_scale(1); cur_obj_scale(1);
#endif #endif
if (o->oDistanceToMario < 1200.0f) { struct Object* player = nearest_player_to_object(o);
int distanceToPlayer = dist_between_objects(o, player);
if (distanceToPlayer < 1200.0f) {
o->oAction = PIRANHA_PLANT_ACT_SLEEPING; o->oAction = PIRANHA_PLANT_ACT_SLEEPING;
if (network_owns_object(o)) { network_send_object(o); }
} }
} }
@ -87,11 +90,14 @@ void piranha_plant_act_sleeping(void) {
o->oDamageOrCoinValue = 3; o->oDamageOrCoinValue = 3;
#endif #endif
if (o->oDistanceToMario < 400.0f) { struct Object* player = nearest_player_to_object(o);
int distanceToPlayer = dist_between_objects(o, player);
if (distanceToPlayer < 400.0f) {
if (mario_moving_fast_enough_to_make_piranha_plant_bite()) { if (mario_moving_fast_enough_to_make_piranha_plant_bite()) {
o->oAction = PIRANHA_PLANT_ACT_WOKEN_UP; o->oAction = PIRANHA_PLANT_ACT_WOKEN_UP;
if (network_owns_object(o)) { network_send_object(o); }
} }
} else if (o->oDistanceToMario < 1000.0f) { } else if (distanceToPlayer < 1000.0f) {
play_secondary_music(SEQ_EVENT_PIRANHA_PLANT, 0, 255, 1000); play_secondary_music(SEQ_EVENT_PIRANHA_PLANT, 0, 255, 1000);
o->oPiranhaPlantSleepMusicState = PIRANHA_PLANT_SLEEP_MUSIC_PLAYING; o->oPiranhaPlantSleepMusicState = PIRANHA_PLANT_SLEEP_MUSIC_PLAYING;
} else if (o->oPiranhaPlantSleepMusicState == PIRANHA_PLANT_SLEEP_MUSIC_PLAYING) { } else if (o->oPiranhaPlantSleepMusicState == PIRANHA_PLANT_SLEEP_MUSIC_PLAYING) {
@ -117,9 +123,12 @@ void piranha_plant_act_woken_up(void) {
if (o->oTimer == 0) if (o->oTimer == 0)
func_80321080(50); func_80321080(50);
if (piranha_plant_check_interactions() == 0) if (piranha_plant_check_interactions() == 0) {
if (o->oTimer > 10) if (o->oTimer > 10) {
o->oAction = PIRANHA_PLANT_ACT_BITING; o->oAction = PIRANHA_PLANT_ACT_BITING;
if (network_owns_object(o)) { network_send_object(o); }
}
}
} }
#if BUGFIX_PIRANHA_PLANT_STATE_RESET #if BUGFIX_PIRANHA_PLANT_STATE_RESET
@ -153,8 +162,10 @@ void piranha_plant_attacked(void) {
cur_obj_become_intangible(); cur_obj_become_intangible();
cur_obj_init_animation_with_sound(2); cur_obj_init_animation_with_sound(2);
o->oInteractStatus = 0; o->oInteractStatus = 0;
if (cur_obj_check_if_near_animation_end()) if (cur_obj_check_if_near_animation_end()) {
o->oAction = PIRANHA_PLANT_ACT_SHRINK_AND_DIE; o->oAction = PIRANHA_PLANT_ACT_SHRINK_AND_DIE;
if (network_owns_object(o)) { network_send_object(o); }
}
#if BUGFIX_PIRANHA_PLANT_STATE_RESET #if BUGFIX_PIRANHA_PLANT_STATE_RESET
piranha_plant_reset_when_far(); // see this function's comment piranha_plant_reset_when_far(); // see this function's comment
#endif #endif
@ -183,6 +194,7 @@ void piranha_plant_act_shrink_and_die(void) {
o->oPiranhaPlantScale = 0.0f; o->oPiranhaPlantScale = 0.0f;
cur_obj_spawn_loot_blue_coin(); cur_obj_spawn_loot_blue_coin();
o->oAction = PIRANHA_PLANT_ACT_WAIT_TO_RESPAWN; o->oAction = PIRANHA_PLANT_ACT_WAIT_TO_RESPAWN;
if (network_owns_object(o)) { network_send_object(o); }
} }
cur_obj_scale(o->oPiranhaPlantScale); cur_obj_scale(o->oPiranhaPlantScale);
@ -196,8 +208,11 @@ void piranha_plant_act_shrink_and_die(void) {
* Wait for Mario to move far away, then respawn the Piranha Plant. * Wait for Mario to move far away, then respawn the Piranha Plant.
*/ */
void piranha_plant_act_wait_to_respawn(void) { void piranha_plant_act_wait_to_respawn(void) {
if (o->oDistanceToMario > 1200.0f) { struct Object* player = nearest_player_to_object(o);
int distanceToPlayer = dist_between_objects(o, player);
if (distanceToPlayer > 1200.0f) {
o->oAction = PIRANHA_PLANT_ACT_RESPAWN; o->oAction = PIRANHA_PLANT_ACT_RESPAWN;
if (network_owns_object(o)) { network_send_object(o); }
} }
} }
@ -223,6 +238,7 @@ void piranha_plant_act_respawn(void) {
} else { } else {
o->oPiranhaPlantScale = 1.0f; o->oPiranhaPlantScale = 1.0f;
o->oAction = PIRANHA_PLANT_ACT_IDLE; o->oAction = PIRANHA_PLANT_ACT_IDLE;
if (network_owns_object(o)) { network_send_object(o); }
} }
cur_obj_scale(o->oPiranhaPlantScale); cur_obj_scale(o->oPiranhaPlantScale);
} }
@ -240,6 +256,11 @@ static s8 sPiranhaPlantBiteSoundFrames[] = { 12, 28, 50, 64, -1 };
* Piranha Plant will move to the attacked state. * Piranha Plant will move to the attacked state.
*/ */
void piranha_plant_act_biting(void) { void piranha_plant_act_biting(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o);
struct Object* player = marioState->marioObj;
int distanceToPlayer = dist_between_objects(o, player);
int angleToPlayer = obj_angle_to_object(o, player);
s32 frame = o->header.gfx.unk38.animFrame; s32 frame = o->header.gfx.unk38.animFrame;
cur_obj_become_tangible(); cur_obj_become_tangible();
@ -257,17 +278,23 @@ void piranha_plant_act_biting(void) {
} }
// Move to face the player. // Move to face the player.
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oAngleToMario, 0x400); o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, angleToPlayer, 0x400);
if (o->oDistanceToMario > 500.0f) if (distanceToPlayer > 500.0f) {
if (cur_obj_check_if_near_animation_end()) if (cur_obj_check_if_near_animation_end()) {
o->oAction = PIRANHA_PLANT_ACT_STOPPED_BITING; o->oAction = PIRANHA_PLANT_ACT_STOPPED_BITING;
if (network_owns_object(o)) { network_send_object(o); }
}
}
// If the player is wearing the Metal Cap and interacts with the Piranha // If the player is wearing the Metal Cap and interacts with the Piranha
// Plant, the Piranha Plant will die. // Plant, the Piranha Plant will die.
if (o->oInteractStatus & INT_STATUS_INTERACTED) if (o->oInteractStatus & INT_STATUS_INTERACTED) {
if (gMarioState->flags & MARIO_METAL_CAP) if (marioState->flags & MARIO_METAL_CAP) {
o->oAction = PIRANHA_PLANT_ACT_ATTACKED; o->oAction = PIRANHA_PLANT_ACT_ATTACKED;
if (network_owns_object(o)) { network_send_object(o); }
}
}
} }
/** /**
@ -277,11 +304,12 @@ void piranha_plant_act_biting(void) {
* This is called from both the "stopped biting" state and the "sleeping" state. * This is called from both the "stopped biting" state and the "sleeping" state.
*/ */
s32 mario_moving_fast_enough_to_make_piranha_plant_bite(void) { s32 mario_moving_fast_enough_to_make_piranha_plant_bite(void) {
if (gMarioStates->vel[1] > 10.0f) struct MarioState* marioState = nearest_mario_state_to_object(o);
return 1; if (marioState->vel[1] > 10.0f)
if (gMarioStates->forwardVel > 10.0f) return TRUE;
return 1; if (marioState->forwardVel > 10.0f)
return 0; return TRUE;
return FALSE;
} }
/** /**
@ -293,8 +321,10 @@ void piranha_plant_act_stopped_biting(void) {
cur_obj_become_intangible(); cur_obj_become_intangible();
cur_obj_init_animation_with_sound(6); cur_obj_init_animation_with_sound(6);
if (cur_obj_check_if_near_animation_end()) if (cur_obj_check_if_near_animation_end()) {
o->oAction = PIRANHA_PLANT_ACT_SLEEPING; o->oAction = PIRANHA_PLANT_ACT_SLEEPING;
if (network_owns_object(o)) { network_send_object(o); }
}
/** /**
* Note that this state only occurs initially when the player goes further * Note that this state only occurs initially when the player goes further
@ -303,9 +333,12 @@ void piranha_plant_act_stopped_biting(void) {
* of the Piranha Plant during the short time the Piranha Plant's nod * of the Piranha Plant during the short time the Piranha Plant's nod
* animation plays. * animation plays.
*/ */
if (o->oDistanceToMario < 400.0f) if (o->oDistanceToMario < 400.0f) {
if (mario_moving_fast_enough_to_make_piranha_plant_bite()) if (mario_moving_fast_enough_to_make_piranha_plant_bite()) {
o->oAction = PIRANHA_PLANT_ACT_BITING; o->oAction = PIRANHA_PLANT_ACT_BITING;
if (network_owns_object(o)) { network_send_object(o); }
}
}
} }
/** /**
@ -327,11 +360,23 @@ void (*TablePiranhaPlantActions[])(void) = {
* Main loop for bhvPiranhaPlant. * Main loop for bhvPiranhaPlant.
*/ */
void bhv_piranha_plant_loop(void) { void bhv_piranha_plant_loop(void) {
if (o->oSyncID == 0) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_init_object_field(o, &o->oAction);
network_init_object_field(o, &o->oInteractStatus);
network_init_object_field(o, &o->oInteractType);
network_init_object_field(o, &o->oMoveAngleYaw);
network_init_object_field(o, &o->oPiranhaPlantScale);
network_init_object_field(o, &o->oPiranhaPlantSleepMusicState);
network_init_object_field(o, &o->oTimer);
}
cur_obj_call_action_function(TablePiranhaPlantActions); cur_obj_call_action_function(TablePiranhaPlantActions);
#ifndef NODRAWINGDISTANCE #ifndef NODRAWINGDISTANCE
// In WF, hide all Piranha Plants once high enough up. // In WF, hide all Piranha Plants once high enough up.
if (gCurrLevelNum == LEVEL_WF) { if (gCurrLevelNum == LEVEL_WF) {
if (gMarioObject->oPosY > 3400.0f) struct Object* player = nearest_player_to_object(o);
if (player->oPosY > 3400.0f)
cur_obj_hide(); cur_obj_hide();
else else
cur_obj_unhide(); cur_obj_unhide();