sm64coopdx/src/game/behaviors/capswitch.inc.c
MysterD efa1600ad0 Truly deal with the NPC dialog softlock problem
Reported by somario360:
After I (Luigi) gave the baby penguin to the mother, the start spawned,
but I was stuck in the looking up animation.
My friend (Mario) talked to Bowser after defeating him, Bowser turned into
a key, but he was stuck in the looking up animation after (I was able to
grab the key though, but Bowser was slightly visible) (Also don't mind 0
stars, he loves doing the lobby BLJ)

The issue is the state machine moved on without removing the reading
dialog action. There was no straight forward way to deal with this.
Custom functions were written for each call to dialog to ensure that we
should stay reading the dialog.
2020-08-31 21:10:34 -07:00

69 lines
2.2 KiB
C

// capswitch.c.inc
static u8 capSwitchForcePress = FALSE;
void cap_switch_act_0(void) {
o->oAnimState = o->oBehParams2ndByte;
cur_obj_scale(0.5f);
o->oPosY += 71.0f;
spawn_object_relative_with_scale(0, 0, -71, 0, 0.5f, o, MODEL_CAP_SWITCH_BASE, bhvCapSwitchBase);
if (gCurrLevelNum != LEVEL_UNKNOWN_32) {
if (save_file_get_flags() & D_8032F0C0[o->oBehParams2ndByte]) {
o->oAction = 3;
o->header.gfx.scale[1] = 0.1f;
} else
o->oAction = 1;
} else
o->oAction = 1;
}
void cap_switch_act_1(void) {
if (capSwitchForcePress || cur_obj_is_mario_on_platform()) {
save_file_set_flags(D_8032F0C0[o->oBehParams2ndByte]);
o->oAction = 2;
cur_obj_play_sound_2(SOUND_GENERAL_ACTIVATE_CAP_SWITCH);
if (!capSwitchForcePress) {
capSwitchForcePress = TRUE;
network_send_object(o);
}
capSwitchForcePress = FALSE;
}
}
u8 cap_switch_act_2_continue_dialog(void) { return o->oAction == 2 && o->oTimer >= 5; }
void cap_switch_act_2(void) {
capSwitchForcePress = FALSE;
s32 sp1C;
if (o->oTimer < 5) {
cur_obj_scale_over_time(2, 4, 0.5f, 0.1f);
if (o->oTimer == 4) {
cur_obj_shake_screen(SHAKE_POS_SMALL);
spawn_mist_particles();
spawn_triangle_break_particles(60, 139, 0.3f, o->oBehParams2ndByte);
queue_rumble_data_object(o, 5, 80);
}
} else {
struct MarioState* marioState = nearest_mario_state_to_object(o);
if (marioState == &gMarioStates[0]) {
sp1C = cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 1, 0x0C, CUTSCENE_CAP_SWITCH_PRESS, 0, cap_switch_act_2_continue_dialog);
if (sp1C) { o->oAction = 3; }
}
}
}
void cap_switch_act_3(void) {
capSwitchForcePress = FALSE;
} // dead function
void (*sCapSwitchActions[])(void) = { cap_switch_act_0, cap_switch_act_1,
cap_switch_act_2, cap_switch_act_3 };
void bhv_cap_switch_loop(void) {
if (!network_sync_object_initialized(o)) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_init_object_field(o, &capSwitchForcePress);
}
cur_obj_call_action_function(sCapSwitchActions);
}