From cf91cc03f849bba498cd8d91505bf8db04f8b1f9 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Sat, 30 Jul 2022 15:55:58 +0300 Subject: [PATCH] Add settings option for "sfx_on_idle" which allows you to play a custom SFX alongside an Idle emote (#744) * Add an "sfx_on_idle" FL packet flag, UNFORTUNATELY servers have to go out of their way to support this feature due to clients below 2.10 fucking spamming sfx for 2.10 otherwise * Revert feature flag, implement a method that works regardless of server instead * Revert "Revert feature flag, implement a method that works regardless of server instead" This reverts commit c14b4fb2a1bbf2796db4a26e83609ba743826655. * Stop using FL packet, but make SFX on Idle a client-side setting to reduce confusion and reliance on servers for a client feature to a minimum. This reverts commit 687e64e37839b77923c93d13f971ee6750bd4330. * Update src/aooptionsdialog.cpp Co-authored-by: stonedDiscord Co-authored-by: oldmud0 --- include/aoapplication.h | 3 +++ include/aooptionsdialog.h | 3 +++ src/aooptionsdialog.cpp | 16 +++++++++++++ src/courtroom.cpp | 45 ++++++++++++++++++++++++------------- src/text_file_functions.cpp | 6 +++++ 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index 5367400..ce74215 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -535,6 +535,9 @@ public: // Get whether to opt out of player count metrics sent to the master server bool get_player_count_optout(); + // Get if sfx can be sent to play on idle + bool get_sfx_on_idle(); + // Whether opening evidence requires a single or double click bool get_evidence_double_click(); diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h index a5b1e4d..d78f8e9 100644 --- a/include/aooptionsdialog.h +++ b/include/aooptionsdialog.h @@ -112,6 +112,9 @@ private: QLabel *ui_category_stop_lbl; QCheckBox *ui_category_stop_cb; + QLabel *ui_sfx_on_idle_lbl; + QCheckBox *ui_sfx_on_idle_cb; + QWidget *ui_callwords_tab; QWidget *ui_callwords_widget; QVBoxLayout *ui_callwords_layout; diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 4bb15cb..a17a5e8 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -466,6 +466,20 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_category_stop_cb); row += 1; + + ui_sfx_on_idle_lbl = new QLabel(ui_form_layout_widget); + ui_sfx_on_idle_lbl->setText(tr("Always Send SFX:")); + ui_sfx_on_idle_lbl->setToolTip( + tr("If the SFX dropdown has an SFX selected, send the custom SFX alongside the message even if Preanim is OFF.")); + + ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_sfx_on_idle_lbl); + + ui_sfx_on_idle_cb = new QCheckBox(ui_form_layout_widget); + + ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_sfx_on_idle_cb); + + row += 1; + ui_evidence_double_click_lbl = new QLabel(ui_form_layout_widget); ui_evidence_double_click_lbl->setText(tr("Evidence Double Click:")); ui_evidence_double_click_lbl->setToolTip( @@ -1199,6 +1213,7 @@ void AOOptionsDialog::update_values() { ui_sticker_cb->setChecked(ao_app->is_sticker_enabled()); ui_continuous_cb->setChecked(ao_app->is_continuous_enabled()); ui_category_stop_cb->setChecked(ao_app->is_category_stop_enabled()); + ui_sfx_on_idle_cb->setChecked(ao_app->get_sfx_on_idle()); ui_blank_blips_cb->setChecked(ao_app->get_blank_blip()); ui_loopsfx_cb->setChecked(ao_app->get_looping_sfx()); ui_objectmusic_cb->setChecked(ao_app->objection_stop_music()); @@ -1286,6 +1301,7 @@ void AOOptionsDialog::save_pressed() configini->setValue("demo_logging_enabled", ui_log_demo_cb->isChecked()); configini->setValue("continuous_playback", ui_continuous_cb->isChecked()); configini->setValue("category_stop", ui_category_stop_cb->isChecked()); + configini->setValue("sfx_on_idle", ui_sfx_on_idle_cb->isChecked()); configini->setValue("evidence_double_click", ui_evidence_double_click_cb->isChecked()); QFile *callwordsini = new QFile(ao_app->get_base_path() + "callwords.ini"); diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 614d97a..d6a1acf 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -1886,18 +1886,11 @@ void Courtroom::on_chat_return_pressed() packet_contents.append(f_desk_mod); - packet_contents.append(ao_app->get_pre_emote(current_char, current_emote)); - - packet_contents.append(current_char); - - packet_contents.append(ao_app->get_emote(current_char, current_emote)); - - packet_contents.append(ui_ic_chat_message->text()); - - packet_contents.append(f_side); - + QString f_pre = ao_app->get_pre_emote(current_char, current_emote); int f_emote_mod = ao_app->get_emote_mod(current_char, current_emote); QString f_sfx = "1"; + int f_sfx_delay = get_char_sfx_delay(); + // EMOTE MOD OVERRIDES: // Emote_mod 2 is only used by objection check later, having it in the char.ini does nothing if (f_emote_mod == 2) { @@ -1944,13 +1937,33 @@ void Courtroom::on_chat_return_pressed() // Custom sfx override via sound list dropdown. if (!custom_sfx.isEmpty() || ui_sfx_dropdown->currentIndex() != 0) { f_sfx = get_char_sfx(); + // We have a custom sfx but we're on idle emotes. + // Turn them into pre so the sound plays if client setting sfx_on_idle is enabled. + if (ao_app->get_sfx_on_idle() && (f_emote_mod == IDLE || f_emote_mod == ZOOM)) { + // We turn idle into preanim, but make it not send a pre animation + f_pre = ""; + // Set sfx delay to 0 so the sfx plays immediately + f_sfx_delay = 0; + // Set the emote mod to preanim so the sound plays + f_emote_mod = f_emote_mod == IDLE ? PREANIM : PREANIM_ZOOM; + } } + packet_contents.append(f_pre); + + packet_contents.append(current_char); + + packet_contents.append(ao_app->get_emote(current_char, current_emote)); + + packet_contents.append(ui_ic_chat_message->text()); + + packet_contents.append(f_side); + packet_contents.append(f_sfx); packet_contents.append(QString::number(f_emote_mod)); packet_contents.append(QString::number(m_cid)); - packet_contents.append(QString::number(get_char_sfx_delay())); + packet_contents.append(QString::number(f_sfx_delay)); QString f_obj_state; @@ -2118,12 +2131,16 @@ void Courtroom::reset_ui() ui_screenshake->set_image("screenshake"); ui_evidence_present->set_image("present"); - if (!ao_app->is_stickysounds_enabled()) { + // If sticky sounds is disabled and we either have SFX on Idle enabled, or our Preanim checkbox is checked + if (!ao_app->is_stickysounds_enabled() && (ao_app->get_sfx_on_idle() || ui_pre->isChecked())) { + // Reset the SFX Dropdown to "Default" ui_sfx_dropdown->setCurrentIndex(0); ui_sfx_remove->hide(); custom_sfx = ""; } + // If sticky preanims is disabled if (!ao_app->is_stickypres_enabled()) + // Turn off our Preanim checkbox ui_pre->setChecked(false); } @@ -2555,7 +2572,7 @@ void Courtroom::handle_emote_mod(int emote_mod, bool p_immediate) switch (emote_mod) { case PREANIM: case PREANIM_ZOOM: - // Emotes 1, 2 and 6 all play preanim that makes the chatbox wait for it to finish. + // play preanim that makes the chatbox wait for it to finish. play_preanim(false); break; case IDLE: @@ -2563,8 +2580,6 @@ void Courtroom::handle_emote_mod(int emote_mod, bool p_immediate) // If immediate is not ticked on... if (!p_immediate) { - // Play the sound effect if one was sent to us - play_sfx(); // Skip preanim. handle_ic_speaking(); } diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index 48e1359..74a8ab4 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -1228,6 +1228,12 @@ bool AOApplication::get_player_count_optout() .startsWith("true"); } +bool AOApplication::get_sfx_on_idle() +{ + return configini->value("sfx_on_idle", "false").value() + .startsWith("true"); +} + bool AOApplication::get_evidence_double_click() { return configini->value("evidence_double_click", "true").value()