2019-08-25 04:46:40 +00:00
|
|
|
// whomp.c.inc
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_play_sfx_from_pound_animation(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
UNUSED s32 sp2C = o->header.gfx.unk38.animFrame;
|
|
|
|
s32 sp28 = 0;
|
|
|
|
if (o->oForwardVel < 5.0f) {
|
2020-03-02 03:42:52 +00:00
|
|
|
sp28 = cur_obj_check_anim_frame(0);
|
|
|
|
sp28 |= cur_obj_check_anim_frame(23);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2020-03-02 03:42:52 +00:00
|
|
|
sp28 = cur_obj_check_anim_frame_in_range(0, 3);
|
|
|
|
sp28 |= cur_obj_check_anim_frame_in_range(23, 3);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
if (sp28)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_OBJ_POUNDING1);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_0(void) {
|
2020-08-12 06:03:40 +00:00
|
|
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
|
|
|
struct Object* player = marioState->marioObj;
|
|
|
|
int distanceToPlayer = dist_between_objects(o, player);
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
|
|
|
|
cur_obj_set_pos_to_home();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oBehParams2ndByte != 0) {
|
|
|
|
gSecondCameraFocus = o;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_scale(2.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oSubAction == 0) {
|
2020-08-12 06:03:40 +00:00
|
|
|
if (distanceToPlayer < 600.0f) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oSubAction++;
|
2020-04-03 18:57:26 +00:00
|
|
|
func_8031FFB4(SEQ_PLAYER_LEVEL, 60, 40);
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_set_pos_to_home();
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oHealth = 3;
|
|
|
|
}
|
2020-08-12 06:03:40 +00:00
|
|
|
} else if (marioState == &gMarioState[0] && cur_obj_update_dialog_with_cutscene(&gMarioState[0], 2, 1, CUTSCENE_DIALOG, DIALOG_114)) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 2;
|
2020-08-12 06:03:40 +00:00
|
|
|
network_send_object(o);
|
|
|
|
}
|
|
|
|
} else if (distanceToPlayer < 500.0f)
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 1;
|
2020-03-02 03:42:52 +00:00
|
|
|
whomp_play_sfx_from_pound_animation();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_7(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oSubAction == 0) {
|
|
|
|
o->oForwardVel = 0.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer > 31)
|
|
|
|
o->oSubAction++;
|
|
|
|
else
|
|
|
|
o->oMoveAngleYaw += 0x400;
|
|
|
|
} else {
|
|
|
|
o->oForwardVel = 3.0f;
|
|
|
|
if (o->oTimer > 42)
|
|
|
|
o->oAction = 1;
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
whomp_play_sfx_from_pound_animation();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_1(void) {
|
2020-08-12 06:03:40 +00:00
|
|
|
struct Object* player = nearest_player_to_object(o);
|
|
|
|
int distanceToPlayer = dist_between_objects(o, player);
|
|
|
|
int angleToPlayer = obj_angle_to_object(o, player);
|
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 sp26;
|
|
|
|
f32 sp20;
|
|
|
|
f32 sp1C;
|
2020-08-12 06:03:40 +00:00
|
|
|
sp26 = abs_angle_diff(angleToPlayer, o->oMoveAngleYaw);
|
2020-03-02 03:42:52 +00:00
|
|
|
sp20 = cur_obj_lateral_dist_to_home();
|
2019-08-25 04:46:40 +00:00
|
|
|
if (gCurrLevelNum == LEVEL_BITS)
|
|
|
|
sp1C = 200.0f;
|
|
|
|
else
|
|
|
|
sp1C = 700.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oForwardVel = 3.0f;
|
|
|
|
if (sp20 > sp1C)
|
|
|
|
o->oAction = 7;
|
|
|
|
else if (sp26 < 0x2000) {
|
2020-08-12 06:03:40 +00:00
|
|
|
if (distanceToPlayer < 1500.0f) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oForwardVel = 9.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation_with_accel_and_sound(0, 3.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2020-08-12 06:03:40 +00:00
|
|
|
if (distanceToPlayer < 300.0f)
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 3;
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
whomp_play_sfx_from_pound_animation();
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_2(void) {
|
2020-08-12 06:03:40 +00:00
|
|
|
struct Object* player = nearest_player_to_object(o);
|
|
|
|
int distanceToPlayer = dist_between_objects(o, player);
|
|
|
|
int angleToPlayer = obj_angle_to_object(o, player);
|
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
s16 sp1E;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oForwardVel = 3.0f;
|
2020-08-12 06:03:40 +00:00
|
|
|
cur_obj_rotate_yaw_toward(angleToPlayer, 0x200);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer > 30) {
|
2020-08-12 06:03:40 +00:00
|
|
|
sp1E = abs_angle_diff(angleToPlayer, o->oMoveAngleYaw);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (sp1E < 0x2000) {
|
2020-08-12 06:03:40 +00:00
|
|
|
if (distanceToPlayer < 1500.0f) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oForwardVel = 9.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation_with_accel_and_sound(0, 3.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
2020-08-12 06:03:40 +00:00
|
|
|
if (distanceToPlayer < 300.0f)
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 3;
|
|
|
|
}
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
whomp_play_sfx_from_pound_animation();
|
|
|
|
if (mario_is_far_below_object(1000.0f)) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 0;
|
|
|
|
stop_background_music(SEQUENCE_ARGS(4, SEQ_EVENT_BOSS));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_3(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oForwardVel = 0.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation_with_accel_and_sound(1, 1.0f);
|
|
|
|
if (cur_obj_check_if_near_animation_end())
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 4;
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_4(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer == 0)
|
|
|
|
o->oVelY = 40.0f;
|
|
|
|
if (o->oTimer < 8) {
|
|
|
|
} else {
|
|
|
|
o->oAngleVelPitch += 0x100;
|
|
|
|
o->oFaceAnglePitch += o->oAngleVelPitch;
|
|
|
|
if (o->oFaceAnglePitch > 0x4000) {
|
|
|
|
o->oAngleVelPitch = 0;
|
|
|
|
o->oFaceAnglePitch = 0x4000;
|
|
|
|
o->oAction = 5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_5(void) {
|
2020-07-04 15:18:55 +00:00
|
|
|
if (o->oSubAction == 0 && o->oMoveFlags & OBJ_MOVE_LANDED) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_OBJ_WHOMP_LOWPRIO);
|
|
|
|
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oVelY = 0.0f;
|
|
|
|
o->oSubAction++;
|
|
|
|
}
|
2020-07-04 15:18:55 +00:00
|
|
|
if (o->oMoveFlags & OBJ_MOVE_ON_GROUND)
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 6;
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void king_whomp_on_ground(void) {
|
2020-08-12 06:03:40 +00:00
|
|
|
struct Object* player = nearest_player_to_object(o);
|
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
Vec3f pos;
|
|
|
|
if (o->oSubAction == 0) {
|
2020-03-02 03:42:52 +00:00
|
|
|
if (cur_obj_is_mario_ground_pounding_platform()) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oHealth--;
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_OBJ2_WHOMP_SOUND_SHORT);
|
|
|
|
cur_obj_play_sound_2(SOUND_OBJ_KING_WHOMP_DEATH);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oHealth == 0)
|
|
|
|
o->oAction = 8;
|
|
|
|
else {
|
2020-03-02 03:42:52 +00:00
|
|
|
vec3f_copy_2(pos, &o->oPosX);
|
2020-08-12 06:03:40 +00:00
|
|
|
vec3f_copy_2(&o->oPosX, &player->oPosX);
|
2020-03-02 03:42:52 +00:00
|
|
|
spawn_mist_particles_variable(0, 0, 100.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
spawn_triangle_break_particles(20, 138, 3.0f, 4);
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
|
|
|
vec3f_copy_2(&o->oPosX, pos);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
o->oSubAction++;
|
|
|
|
}
|
2020-06-02 16:44:34 +00:00
|
|
|
o->oWhompShakeVal = 0;
|
2019-08-25 04:46:40 +00:00
|
|
|
} else {
|
2020-06-02 16:44:34 +00:00
|
|
|
if (o->oWhompShakeVal < 10) {
|
|
|
|
if (o->oWhompShakeVal % 2)
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oPosY += 8.0f;
|
|
|
|
else
|
|
|
|
o->oPosY -= 8.0f;
|
|
|
|
} else
|
|
|
|
o->oSubAction = 10;
|
2020-06-02 16:44:34 +00:00
|
|
|
o->oWhompShakeVal++;
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_on_ground(void) {
|
2020-08-12 06:03:40 +00:00
|
|
|
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oSubAction == 0) {
|
2020-08-12 06:03:40 +00:00
|
|
|
u8 anyMarioOnPlatform = FALSE;
|
|
|
|
for (int i = 0; i < MAX_PLAYERS; i++) {
|
|
|
|
if (gMarioStates[i].marioObj->platform == o) { anyMarioOnPlatform = TRUE; }
|
|
|
|
}
|
|
|
|
if (anyMarioOnPlatform) {
|
2020-03-02 03:42:52 +00:00
|
|
|
if (cur_obj_is_mario_ground_pounding_platform()) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oNumLootCoins = 5;
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_spawn_loot_yellow_coins(o, 5, 20.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 8;
|
|
|
|
} else {
|
2020-08-12 06:03:40 +00:00
|
|
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
|
|
|
cur_obj_spawn_loot_coin_at_mario_pos(marioState);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oSubAction++;
|
|
|
|
}
|
|
|
|
}
|
2020-03-02 03:42:52 +00:00
|
|
|
} else if (!cur_obj_is_mario_on_platform())
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oSubAction = 0;
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_6(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oSubAction != 10) {
|
|
|
|
o->oForwardVel = 0.0f;
|
|
|
|
o->oAngleVelPitch = 0;
|
|
|
|
o->oAngleVelYaw = 0;
|
|
|
|
o->oAngleVelRoll = 0;
|
|
|
|
if (o->oBehParams2ndByte != 0)
|
2020-03-02 03:42:52 +00:00
|
|
|
king_whomp_on_ground();
|
2019-08-25 04:46:40 +00:00
|
|
|
else
|
2020-03-02 03:42:52 +00:00
|
|
|
whomp_on_ground();
|
2020-08-12 06:03:40 +00:00
|
|
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
|
|
|
if (o->oTimer > 100 || (marioState->action == ACT_SQUISHED && o->oTimer > 30))
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oSubAction = 10;
|
|
|
|
} else {
|
|
|
|
if (o->oFaceAnglePitch > 0) {
|
|
|
|
o->oAngleVelPitch = -0x200;
|
|
|
|
o->oFaceAnglePitch += o->oAngleVelPitch;
|
|
|
|
} else {
|
|
|
|
o->oAngleVelPitch = 0;
|
|
|
|
o->oFaceAnglePitch = 0;
|
|
|
|
if (o->oBehParams2ndByte != 0)
|
|
|
|
o->oAction = 2;
|
|
|
|
else
|
|
|
|
o->oAction = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_8(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oBehParams2ndByte != 0) {
|
2020-08-12 06:03:40 +00:00
|
|
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
|
|
|
if (marioState == &gMarioState[0] && cur_obj_update_dialog_with_cutscene(&gMarioState[0], 2, 2, CUTSCENE_DIALOG, DIALOG_115)) {
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_set_angle(o, 0, 0, 0);
|
|
|
|
cur_obj_hide();
|
|
|
|
cur_obj_become_intangible();
|
|
|
|
spawn_mist_particles_variable(0, 0, 200.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
spawn_triangle_break_particles(20, 138, 3.0f, 4);
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oPosY += 100.0f;
|
2020-03-02 03:42:52 +00:00
|
|
|
spawn_default_star(180.0f, 3880.0f, 340.0f);
|
|
|
|
cur_obj_play_sound_2(SOUND_OBJ_KING_WHOMP_DEATH);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = 9;
|
2020-08-12 06:03:40 +00:00
|
|
|
network_send_object(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
} else {
|
2020-03-02 03:42:52 +00:00
|
|
|
spawn_mist_particles_variable(0, 0, 100.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
spawn_triangle_break_particles(20, 138, 3.0f, 4);
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
2019-10-05 19:08:05 +00:00
|
|
|
create_sound_spawner(SOUND_OBJ_THWOMP);
|
2020-03-02 03:42:52 +00:00
|
|
|
obj_mark_for_deletion(o);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void whomp_act_9(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer == 60)
|
|
|
|
stop_background_music(SEQUENCE_ARGS(4, SEQ_EVENT_BOSS));
|
|
|
|
}
|
|
|
|
|
|
|
|
void (*sWhompActions[])(void) = {
|
2020-03-02 03:42:52 +00:00
|
|
|
whomp_act_0, whomp_act_1, whomp_act_2, whomp_act_3, whomp_act_4,
|
|
|
|
whomp_act_5, whomp_act_6, whomp_act_7, whomp_act_8, whomp_act_9
|
2019-08-25 04:46:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// MM
|
|
|
|
void bhv_whomp_loop(void) {
|
2020-08-12 06:03:40 +00:00
|
|
|
if (o->oSyncID == 0) {
|
|
|
|
network_init_object(o, 4000.0f);
|
|
|
|
network_init_object_field(o, &o->oAngleVelPitch);
|
|
|
|
network_init_object_field(o, &o->oFaceAnglePitch);
|
|
|
|
network_init_object_field(o, &o->oForwardVel);
|
|
|
|
network_init_object_field(o, &o->oHealth);
|
|
|
|
network_init_object_field(o, &o->oFaceAnglePitch);
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_update_floor_and_walls();
|
|
|
|
cur_obj_call_action_function(sWhompActions);
|
|
|
|
cur_obj_move_standard(-20);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oAction != 9) {
|
2020-05-16 18:33:41 +00:00
|
|
|
#ifndef NODRAWINGDISTANCE
|
2020-05-16 05:59:29 +00:00
|
|
|
// o->oBehParams2ndByte here seems to be a flag
|
|
|
|
// indicating whether this is a normal or king whomp
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oBehParams2ndByte != 0)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_hide_if_mario_far_away_y(2000.0f);
|
2019-08-25 04:46:40 +00:00
|
|
|
else
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_hide_if_mario_far_away_y(1000.0f);
|
2020-05-16 18:33:41 +00:00
|
|
|
#endif
|
2019-08-25 04:46:40 +00:00
|
|
|
load_object_collision_model();
|
|
|
|
}
|
|
|
|
}
|