diff --git a/include/aoapplication.h b/include/aoapplication.h index 2ee1120..5f808f5 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -421,6 +421,9 @@ public: // Returns the custom realisation used by the character. QString get_custom_realization(QString p_char); + // Returns whether the given pos is a judge position + bool get_pos_is_judge(const QString &p_pos); + // Returns the name of p_char QString get_char_name(QString p_char); diff --git a/include/courtroom.h b/include/courtroom.h index bf688b5..55e8b4e 100644 --- a/include/courtroom.h +++ b/include/courtroom.h @@ -304,7 +304,7 @@ public: void set_hp_bar(int p_bar, int p_state); // Toggles the judge buttons, whether they should appear or not. - void toggle_judge_buttons(bool is_on); + void show_judge_controls(bool visible); void announce_case(QString title, bool def, bool pro, bool jud, bool jur, bool steno); @@ -325,6 +325,16 @@ public: void on_authentication_state_received(int p_state); + enum JudgeState { + POS_DEPENDENT = -1, + HIDE_CONTROLS = 0, + SHOW_CONTROLS = 1 + }; + + JudgeState get_judge_state() { return judge_state; } + void set_judge_state(JudgeState new_state) { judge_state = new_state; } + void set_judge_buttons() { show_judge_controls(ao_app->get_pos_is_judge(current_side)); } + ~Courtroom(); private: AOApplication *ao_app; @@ -480,6 +490,8 @@ private: bool is_muted = false; + JudgeState judge_state = POS_DEPENDENT; + // state of animation, 0 = objecting, 1 = preanim, 2 = talking, 3 = idle, 4 = // noniterrupting preanim, 5 = (c) animation int anim_state = 3; diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 8e60994..1e1fcd0 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -1406,10 +1406,7 @@ void Courtroom::set_side(QString p_side) ui_pos_remove->show(); } - toggle_judge_buttons(false); - - if (f_side == "jud") - toggle_judge_buttons(true); + set_judge_buttons(); // Block the signals to prevent setCurrentIndex from triggering a pos // change @@ -4042,27 +4039,28 @@ void Courtroom::set_hp_bar(int p_bar, int p_state) } } -void Courtroom::toggle_judge_buttons(bool is_on) +void Courtroom::show_judge_controls(bool visible) { - if (is_on) { - ui_witness_testimony->show(); - ui_cross_examination->show(); - ui_guilty->show(); - ui_not_guilty->show(); - ui_defense_minus->show(); - ui_defense_plus->show(); - ui_prosecution_minus->show(); - ui_prosecution_plus->show(); + if (judge_state != POS_DEPENDENT) { + visible = judge_state == SHOW_CONTROLS; // Server-side override } - else { - ui_witness_testimony->hide(); - ui_cross_examination->hide(); - ui_guilty->hide(); - ui_not_guilty->hide(); - ui_defense_minus->hide(); - ui_defense_plus->hide(); - ui_prosecution_minus->hide(); - ui_prosecution_plus->hide(); + QList judge_controls = + { + ui_witness_testimony, + ui_cross_examination, + ui_guilty, + ui_not_guilty, + ui_defense_minus, + ui_defense_plus, + ui_prosecution_minus, + ui_prosecution_plus + }; + + for (QWidget* control : judge_controls) { + if (visible) + control->show(); + else + control->hide(); } } @@ -4093,10 +4091,10 @@ void Courtroom::on_ooc_return_pressed() //Using an arbitrary 2.8 feature flag certainly won't cause issues someday. if (ooc_message.startsWith("/pos") & !ao_app->effects_enabled) { if (ooc_message == "/pos jud") { - toggle_judge_buttons(true); + show_judge_controls(true); } else { - toggle_judge_buttons(false); + show_judge_controls(false); } } @@ -4373,6 +4371,8 @@ void Courtroom::on_pos_remove_clicked() ui_pos_dropdown->blockSignals(true); QString default_side = ao_app->get_char_side(current_char); + show_judge_controls(ao_app->get_pos_is_judge(default_side)); + for (int i = 0; i < ui_pos_dropdown->count(); ++i) { QString pos = ui_pos_dropdown->itemText(i); if (pos == default_side) { diff --git a/src/packet_distribution.cpp b/src/packet_distribution.cpp index 0fe25dc..8ac1b28 100644 --- a/src/packet_distribution.cpp +++ b/src/packet_distribution.cpp @@ -606,10 +606,31 @@ void AOApplication::server_packet_received(AOPacket *p_packet) else if (header == "AUTH") { if (!courtroom_constructed || !auth_packet_enabled || f_contents.size() < 1) goto end; - int authenticated = f_contents.at(0).toInt(); + bool ok; + int authenticated = f_contents.at(0).toInt(&ok); + if (!ok) { + qWarning() << "Malformed AUTH packet! Contents:" << f_contents.at(0); + } w_courtroom->on_authentication_state_received(authenticated); } + else if (header == "JD") { + if (!courtroom_constructed || f_contents.empty()) { + goto end; + } + bool ok; + Courtroom::JudgeState state = static_cast(f_contents.at(0).toInt(&ok)); + if (!ok) { + goto end; // ignore malformed packet + } + w_courtroom->set_judge_state(state); + if (w_courtroom->get_judge_state() != Courtroom::POS_DEPENDENT) { // If we receive JD -1, it means the server asks us to fall back to client-side judge buttons behavior + w_courtroom->show_judge_controls(w_courtroom->get_judge_state() == Courtroom::SHOW_CONTROLS); + } + else { + w_courtroom->set_judge_buttons(); // client-side judge behavior + } + } //AssetURL Packet else if (header == "ASS") { diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index b020941..05d8416 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -912,6 +912,15 @@ QString AOApplication::get_custom_realization(QString p_char) return get_sfx_suffix(get_sounds_path(f_result)); } +bool AOApplication::get_pos_is_judge(const QString &p_pos) +{ + QStringList positions = read_design_ini("judges", get_background_path("design.ini")).split(","); + if (positions.size() == 1 && positions[0] == "") { + return p_pos == "jud"; //Hardcoded BS only if we have no judges= defined + } + return positions.contains(p_pos.trimmed()); +} + bool AOApplication::get_blank_blip() { QString result = configini->value("blank_blip", "false").value();