mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-10-20 20:22:38 +00:00
d2a2a80d56
Synchronized currentRoom per-player Synchronized haunted bookshelf, and the bookshelf manager Synchronized haunted chairs Synchronized mad piano Synchronized BBH's tilting trap, and made the physics multiple-player-aware Synchronized scuttlebugs Synchronized every variety of Boo Synchronized elevators Synchronized flamethrowers Synchronized the various types of enemy books Synchronized the book switches Synchronized jumping box Made coffins multiple-player-aware Fixed everything that used gMarioState as an array instead of gMarioStates Prevented some NPC-dialog softlocks Prevented the remote player from messing up the local's camera settings Possibly fixed the relatively rare chain chomp softlock Possibly fixed the relatively rare chain hoot softlock Fixed the first-person-camera softlock Forced camera code to use the correct mario struct
293 lines
9.3 KiB
C
293 lines
9.3 KiB
C
// whomp.c.inc
|
|
|
|
void whomp_play_sfx_from_pound_animation(void) {
|
|
UNUSED s32 sp2C = o->header.gfx.unk38.animFrame;
|
|
s32 sp28 = 0;
|
|
if (o->oForwardVel < 5.0f) {
|
|
sp28 = cur_obj_check_anim_frame(0);
|
|
sp28 |= cur_obj_check_anim_frame(23);
|
|
} else {
|
|
sp28 = cur_obj_check_anim_frame_in_range(0, 3);
|
|
sp28 |= cur_obj_check_anim_frame_in_range(23, 3);
|
|
}
|
|
if (sp28)
|
|
cur_obj_play_sound_2(SOUND_OBJ_POUNDING1);
|
|
}
|
|
|
|
void whomp_act_0(void) {
|
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
|
struct Object* player = marioState->marioObj;
|
|
int distanceToPlayer = dist_between_objects(o, player);
|
|
|
|
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
|
|
cur_obj_set_pos_to_home();
|
|
if (o->oBehParams2ndByte != 0) {
|
|
gSecondCameraFocus = o;
|
|
cur_obj_scale(2.0f);
|
|
if (o->oSubAction == 0) {
|
|
if (distanceToPlayer < 600.0f) {
|
|
o->oSubAction++;
|
|
func_8031FFB4(SEQ_PLAYER_LEVEL, 60, 40);
|
|
} else {
|
|
cur_obj_set_pos_to_home();
|
|
o->oHealth = 3;
|
|
}
|
|
} else if (marioState == &gMarioStates[0] && cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 2, 1, CUTSCENE_DIALOG, DIALOG_114)) {
|
|
o->oAction = 2;
|
|
network_send_object(o);
|
|
}
|
|
} else if (distanceToPlayer < 500.0f)
|
|
o->oAction = 1;
|
|
whomp_play_sfx_from_pound_animation();
|
|
}
|
|
|
|
void whomp_act_7(void) {
|
|
if (o->oSubAction == 0) {
|
|
o->oForwardVel = 0.0f;
|
|
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
|
|
if (o->oTimer > 31)
|
|
o->oSubAction++;
|
|
else
|
|
o->oMoveAngleYaw += 0x400;
|
|
} else {
|
|
o->oForwardVel = 3.0f;
|
|
if (o->oTimer > 42)
|
|
o->oAction = 1;
|
|
}
|
|
whomp_play_sfx_from_pound_animation();
|
|
}
|
|
|
|
void whomp_act_1(void) {
|
|
struct Object* player = nearest_player_to_object(o);
|
|
int distanceToPlayer = dist_between_objects(o, player);
|
|
int angleToPlayer = obj_angle_to_object(o, player);
|
|
|
|
s16 sp26;
|
|
f32 sp20;
|
|
f32 sp1C;
|
|
sp26 = abs_angle_diff(angleToPlayer, o->oMoveAngleYaw);
|
|
sp20 = cur_obj_lateral_dist_to_home();
|
|
if (gCurrLevelNum == LEVEL_BITS)
|
|
sp1C = 200.0f;
|
|
else
|
|
sp1C = 700.0f;
|
|
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
|
|
o->oForwardVel = 3.0f;
|
|
if (sp20 > sp1C)
|
|
o->oAction = 7;
|
|
else if (sp26 < 0x2000) {
|
|
if (distanceToPlayer < 1500.0f) {
|
|
o->oForwardVel = 9.0f;
|
|
cur_obj_init_animation_with_accel_and_sound(0, 3.0f);
|
|
}
|
|
if (distanceToPlayer < 300.0f)
|
|
o->oAction = 3;
|
|
}
|
|
whomp_play_sfx_from_pound_animation();
|
|
}
|
|
|
|
void whomp_act_2(void) {
|
|
struct Object* player = nearest_player_to_object(o);
|
|
int distanceToPlayer = dist_between_objects(o, player);
|
|
int angleToPlayer = obj_angle_to_object(o, player);
|
|
|
|
s16 sp1E;
|
|
cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
|
|
o->oForwardVel = 3.0f;
|
|
cur_obj_rotate_yaw_toward(angleToPlayer, 0x200);
|
|
if (o->oTimer > 30) {
|
|
sp1E = abs_angle_diff(angleToPlayer, o->oMoveAngleYaw);
|
|
if (sp1E < 0x2000) {
|
|
if (distanceToPlayer < 1500.0f) {
|
|
o->oForwardVel = 9.0f;
|
|
cur_obj_init_animation_with_accel_and_sound(0, 3.0f);
|
|
}
|
|
if (distanceToPlayer < 300.0f)
|
|
o->oAction = 3;
|
|
}
|
|
}
|
|
whomp_play_sfx_from_pound_animation();
|
|
if (mario_is_far_below_object(1000.0f)) {
|
|
o->oAction = 0;
|
|
stop_background_music(SEQUENCE_ARGS(4, SEQ_EVENT_BOSS));
|
|
}
|
|
}
|
|
|
|
void whomp_act_3(void) {
|
|
o->oForwardVel = 0.0f;
|
|
cur_obj_init_animation_with_accel_and_sound(1, 1.0f);
|
|
if (cur_obj_check_if_near_animation_end())
|
|
o->oAction = 4;
|
|
}
|
|
|
|
void whomp_act_4(void) {
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
void whomp_act_5(void) {
|
|
if (o->oSubAction == 0 && o->oMoveFlags & OBJ_MOVE_LANDED) {
|
|
cur_obj_play_sound_2(SOUND_OBJ_WHOMP_LOWPRIO);
|
|
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
|
o->oVelY = 0.0f;
|
|
o->oSubAction++;
|
|
}
|
|
if (o->oMoveFlags & OBJ_MOVE_ON_GROUND)
|
|
o->oAction = 6;
|
|
}
|
|
|
|
void king_whomp_on_ground(void) {
|
|
struct Object* player = nearest_player_to_object(o);
|
|
|
|
Vec3f pos;
|
|
if (o->oSubAction == 0) {
|
|
if (cur_obj_is_mario_ground_pounding_platform()) {
|
|
o->oHealth--;
|
|
cur_obj_play_sound_2(SOUND_OBJ2_WHOMP_SOUND_SHORT);
|
|
cur_obj_play_sound_2(SOUND_OBJ_KING_WHOMP_DEATH);
|
|
if (o->oHealth == 0)
|
|
o->oAction = 8;
|
|
else {
|
|
vec3f_copy_2(pos, &o->oPosX);
|
|
vec3f_copy_2(&o->oPosX, &player->oPosX);
|
|
spawn_mist_particles_variable(0, 0, 100.0f);
|
|
spawn_triangle_break_particles(20, 138, 3.0f, 4);
|
|
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
|
vec3f_copy_2(&o->oPosX, pos);
|
|
}
|
|
o->oSubAction++;
|
|
}
|
|
o->oWhompShakeVal = 0;
|
|
} else {
|
|
if (o->oWhompShakeVal < 10) {
|
|
if (o->oWhompShakeVal % 2)
|
|
o->oPosY += 8.0f;
|
|
else
|
|
o->oPosY -= 8.0f;
|
|
} else
|
|
o->oSubAction = 10;
|
|
o->oWhompShakeVal++;
|
|
}
|
|
}
|
|
|
|
void whomp_on_ground(void) {
|
|
|
|
if (o->oSubAction == 0) {
|
|
u8 anyMarioOnPlatform = FALSE;
|
|
for (int i = 0; i < MAX_PLAYERS; i++) {
|
|
if (gMarioStates[i].marioObj->platform == o) { anyMarioOnPlatform = TRUE; }
|
|
}
|
|
if (anyMarioOnPlatform) {
|
|
if (cur_obj_is_mario_ground_pounding_platform()) {
|
|
o->oNumLootCoins = 5;
|
|
obj_spawn_loot_yellow_coins(o, 5, 20.0f);
|
|
o->oAction = 8;
|
|
} else {
|
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
|
cur_obj_spawn_loot_coin_at_mario_pos(marioState);
|
|
o->oSubAction++;
|
|
}
|
|
}
|
|
} else if (!cur_obj_is_mario_on_platform())
|
|
o->oSubAction = 0;
|
|
}
|
|
|
|
void whomp_act_6(void) {
|
|
if (o->oSubAction != 10) {
|
|
o->oForwardVel = 0.0f;
|
|
o->oAngleVelPitch = 0;
|
|
o->oAngleVelYaw = 0;
|
|
o->oAngleVelRoll = 0;
|
|
if (o->oBehParams2ndByte != 0)
|
|
king_whomp_on_ground();
|
|
else
|
|
whomp_on_ground();
|
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
|
if (o->oTimer > 100 || (marioState->action == ACT_SQUISHED && o->oTimer > 30))
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
void whomp_act_8(void) {
|
|
if (o->oBehParams2ndByte != 0) {
|
|
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
|
if (marioState == &gMarioStates[0] && cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 2, 2, CUTSCENE_DIALOG, DIALOG_115)) {
|
|
obj_set_angle(o, 0, 0, 0);
|
|
cur_obj_hide();
|
|
cur_obj_become_intangible();
|
|
spawn_mist_particles_variable(0, 0, 200.0f);
|
|
spawn_triangle_break_particles(20, 138, 3.0f, 4);
|
|
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
|
o->oPosY += 100.0f;
|
|
spawn_default_star(180.0f, 3880.0f, 340.0f);
|
|
cur_obj_play_sound_2(SOUND_OBJ_KING_WHOMP_DEATH);
|
|
o->oAction = 9;
|
|
network_send_object(o);
|
|
}
|
|
} else {
|
|
spawn_mist_particles_variable(0, 0, 100.0f);
|
|
spawn_triangle_break_particles(20, 138, 3.0f, 4);
|
|
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
|
create_sound_spawner(SOUND_OBJ_THWOMP);
|
|
obj_mark_for_deletion(o);
|
|
}
|
|
}
|
|
|
|
void whomp_act_9(void) {
|
|
if (o->oTimer == 60)
|
|
stop_background_music(SEQUENCE_ARGS(4, SEQ_EVENT_BOSS));
|
|
}
|
|
|
|
void (*sWhompActions[])(void) = {
|
|
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
|
|
};
|
|
|
|
// MM
|
|
void bhv_whomp_loop(void) {
|
|
if (!network_sync_object_initialized(o)) {
|
|
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);
|
|
}
|
|
|
|
cur_obj_update_floor_and_walls();
|
|
cur_obj_call_action_function(sWhompActions);
|
|
cur_obj_move_standard(-20);
|
|
if (o->oAction != 9) {
|
|
#ifndef NODRAWINGDISTANCE
|
|
// o->oBehParams2ndByte here seems to be a flag
|
|
// indicating whether this is a normal or king whomp
|
|
if (o->oBehParams2ndByte != 0)
|
|
cur_obj_hide_if_mario_far_away_y(2000.0f);
|
|
else
|
|
cur_obj_hide_if_mario_far_away_y(1000.0f);
|
|
#endif
|
|
load_object_collision_model();
|
|
}
|
|
}
|