aboutsummaryrefslogtreecommitdiff
path: root/src/courtroom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/courtroom.cpp')
-rw-r--r--src/courtroom.cpp1481
1 files changed, 906 insertions, 575 deletions
diff --git a/src/courtroom.cpp b/src/courtroom.cpp
index 3bbf82a4..4b37e6f9 100644
--- a/src/courtroom.cpp
+++ b/src/courtroom.cpp
@@ -12,13 +12,16 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000));
keepalive_timer = new QTimer(this);
- keepalive_timer->start(60000);
+ keepalive_timer->start(45000);
chat_tick_timer = new QTimer(this);
text_delay_timer = new QTimer(this);
text_delay_timer->setSingleShot(true);
+ text_queue_timer = new QTimer(this);
+ text_queue_timer->setSingleShot(true);
+
sfx_delay_timer = new QTimer(this);
sfx_delay_timer->setSingleShot(true);
@@ -40,21 +43,22 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_background = new AOImage(this, ao_app);
ui_viewport = new QWidget(this);
- ui_vp_background = new AOScene(ui_viewport, ao_app);
- ui_vp_speedlines = new AOMovie(ui_viewport, ao_app);
- ui_vp_speedlines->set_play_once(false);
- ui_vp_player_char = new AOCharMovie(ui_viewport, ao_app);
- ui_vp_sideplayer_char = new AOCharMovie(ui_viewport, ao_app);
+ ui_vp_background = new BackgroundLayer(ui_viewport, ao_app);
+ ui_vp_speedlines = new ForegroundLayer(ui_viewport, ao_app);
+ ui_vp_player_char = new CharLayer(ui_viewport, ao_app);
+ ui_vp_sideplayer_char = new CharLayer(ui_viewport, ao_app);
ui_vp_sideplayer_char->hide();
- ui_vp_desk = new AOScene(ui_viewport, ao_app);
- ui_vp_legacy_desk = new AOScene(ui_viewport, ao_app);
+ ui_vp_desk = new BackgroundLayer(ui_viewport, ao_app);
+
+ ui_vp_effect = new EffectLayer(this, ao_app);
+ ui_vp_effect->setAttribute(Qt::WA_TransparentForMouseEvents);
ui_vp_evidence_display = new AOEvidenceDisplay(ui_viewport, ao_app);
ui_vp_chatbox = new AOImage(this, ao_app);
ui_vp_showname = new QLabel(ui_vp_chatbox);
ui_vp_showname->setAlignment(Qt::AlignLeft);
- ui_vp_chat_arrow = new AOMovie(ui_vp_chatbox, ao_app);
+ ui_vp_chat_arrow = new InterfaceLayer(this, ao_app);
ui_vp_chat_arrow->set_play_once(false);
ui_vp_message = new QTextEdit(this);
@@ -63,14 +67,13 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_vp_message->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui_vp_message->setReadOnly(true);
- ui_vp_testimony = new AOMovie(this, ao_app);
+ ui_vp_testimony = new InterfaceLayer(this, ao_app);
ui_vp_testimony->set_play_once(false);
ui_vp_testimony->setAttribute(Qt::WA_TransparentForMouseEvents);
- ui_vp_effect = new AOMovie(this, ao_app);
- ui_vp_effect->setAttribute(Qt::WA_TransparentForMouseEvents);
- ui_vp_wtce = new AOMovie(this, ao_app);
+ ui_vp_wtce = new InterjectionLayer(this, ao_app);
+ ui_vp_wtce->set_play_once(true);
ui_vp_wtce->setAttribute(Qt::WA_TransparentForMouseEvents);
- ui_vp_objection = new AOMovie(this, ao_app);
+ ui_vp_objection = new InterjectionLayer(this, ao_app);
ui_vp_objection->setAttribute(Qt::WA_TransparentForMouseEvents);
ui_ic_chatlog = new QTextEdit(this);
@@ -107,14 +110,22 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_music_list->header()->setStretchLastSection(false);
ui_music_list->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui_music_list->setContextMenuPolicy(Qt::CustomContextMenu);
+ ui_music_list->setUniformRowHeights(true);
+
- ui_music_display = new AOMovie(this, ao_app);
+ ui_music_display = new InterfaceLayer(this, ao_app);
ui_music_display->set_play_once(false);
ui_music_display->setAttribute(Qt::WA_TransparentForMouseEvents);
ui_music_name = new ScrollText(ui_music_display);
ui_music_name->setText(tr("None"));
ui_music_name->setAttribute(Qt::WA_TransparentForMouseEvents);
+
+ for (int i = 0; i < max_clocks; i++) {
+ ui_clock[i] = new AOClockLabel(this);
+ ui_clock[i]->setAttribute(Qt::WA_TransparentForMouseEvents);
+ ui_clock[i]->hide();
+ }
ui_ic_chat_name = new QLineEdit(this);
ui_ic_chat_name->setFrame(false);
@@ -129,6 +140,10 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
// todo: filter out \n from showing up as that commonly breaks the chatlog and
// can be spammed to hell
+ ui_vp_sticker = new StickerLayer(ui_viewport, ao_app);
+ ui_vp_sticker->set_play_once(false);
+ ui_vp_sticker->setAttribute(Qt::WA_TransparentForMouseEvents);
+
ui_muted = new AOImage(ui_ic_chat_message, ao_app);
ui_muted->hide();
@@ -211,7 +226,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_showname_enable->setText(tr("Shownames"));
ui_immediate = new QCheckBox(this);
- ui_immediate->setText(tr("No Interrupt"));
+ ui_immediate->setText(tr("Immediate"));
ui_immediate->hide();
ui_custom_objection = new AOButton(this, ao_app);
@@ -266,6 +281,8 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
connect(keepalive_timer, SIGNAL(timeout()), this, SLOT(ping_server()));
connect(ui_vp_objection, SIGNAL(done()), this, SLOT(objection_done()));
+ connect(ui_vp_effect, SIGNAL(done()), this, SLOT(effect_done()));
+ connect(ui_vp_wtce, SIGNAL(done()), this, SLOT(effect_done()));
connect(ui_vp_player_char, SIGNAL(done()), this, SLOT(preanim_done()));
connect(ui_vp_player_char, SIGNAL(shake()), this, SLOT(do_screenshake()));
connect(ui_vp_player_char, SIGNAL(flash()), this, SLOT(do_flash()));
@@ -274,6 +291,10 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
connect(text_delay_timer, SIGNAL(timeout()), this,
SLOT(start_chat_ticking()));
+
+ connect(text_queue_timer, SIGNAL(timeout()), this,
+ SLOT(chatmessage_dequeue()));
+
connect(sfx_delay_timer, SIGNAL(timeout()), this, SLOT(play_sfx()));
connect(chat_tick_timer, SIGNAL(timeout()), this, SLOT(chat_tick()));
@@ -290,6 +311,8 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
connect(ui_sfx_dropdown, SIGNAL(currentIndexChanged(int)), this,
SLOT(on_sfx_dropdown_changed(int)));
+ connect(ui_sfx_dropdown, SIGNAL(editTextChanged(QString)), this,
+ SLOT(on_sfx_dropdown_custom(QString)));
connect(ui_sfx_dropdown, SIGNAL(customContextMenuRequested(QPoint)), this,
SLOT(on_sfx_context_menu_requested(QPoint)));
connect(ui_sfx_remove, SIGNAL(clicked()), this,
@@ -521,14 +544,6 @@ void Courtroom::set_widgets()
ui_vp_desk->move(0, 0);
ui_vp_desk->combo_resize(ui_viewport->width(), ui_viewport->height());
- // the size of the ui_vp_legacy_desk element relies on various factors and is
- // set in set_scene()
-
- double y_modifier = 147.0 / 192.0;
- int final_y = static_cast<int>(y_modifier * ui_viewport->height());
- ui_vp_legacy_desk->move(0, final_y);
- ui_vp_legacy_desk->hide();
-
ui_vp_evidence_display->move(0, 0);
ui_vp_evidence_display->combo_resize(ui_viewport->width(),
ui_viewport->height());
@@ -542,11 +557,14 @@ void Courtroom::set_widgets()
ui_vp_chat_arrow->hide();
}
else {
- ui_vp_chat_arrow->move(design_ini_result.x, design_ini_result.y);
- ui_vp_chat_arrow->combo_resize(design_ini_result.width,
- design_ini_result.height);
+ ui_vp_chat_arrow->move(design_ini_result.x + ui_vp_chatbox->x(), design_ini_result.y + ui_vp_chatbox->y());
+ ui_vp_chat_arrow->combo_resize(design_ini_result.width, design_ini_result.height);
}
+ // layering shenanigans with ui_vp_chatbox prevent us from doing the sensible
+ // thing, which is to parent these to ui_viewport. instead, AOLayer handles
+ // masking so we don't overlap parts of the UI, and they become free floating
+ // widgets.
ui_vp_testimony->move(ui_viewport->x(), ui_viewport->y());
ui_vp_testimony->combo_resize(ui_viewport->width(), ui_viewport->height());
@@ -621,6 +639,17 @@ void Courtroom::set_widgets()
set_size_and_pos(ui_music_list, "music_list");
ui_music_list->header()->setMinimumSectionSize(ui_music_list->width());
+ QString music_list_indentation = ao_app->get_font_name("music_list_indent", "courtroom_design.ini");
+ if (music_list_indentation == "")
+ ui_music_list->resetIndentation();
+ else
+ ui_music_list->setIndentation(music_list_indentation.toInt());
+
+ QString music_list_animated = ao_app->get_font_name("music_list_animated", "courtroom_design.ini");
+ if (music_list_animated == "1")
+ ui_music_list->setAnimated(true);
+ else
+ ui_music_list->setAnimated(false);
set_size_and_pos(ui_music_name, "music_name");
@@ -629,7 +658,7 @@ void Courtroom::set_widgets()
ao_app->get_element_dimensions("music_display", "courtroom_design.ini");
if (design_ini_result.width < 0 || design_ini_result.height < 0) {
- qDebug() << "W: could not find \"music_name\" in courtroom_design.ini";
+ qDebug() << "W: could not find \"music_display\" in courtroom_design.ini";
ui_music_display->hide();
}
else {
@@ -637,18 +666,21 @@ void Courtroom::set_widgets()
ui_music_display->combo_resize(design_ini_result.width,
design_ini_result.height);
}
+ ui_music_display->load_image("music_display", "");
- ui_music_display->play("music_display");
- ui_music_display->set_play_once(false);
+
+ for (int i = 0; i < max_clocks; i++) {
+ set_size_and_pos(ui_clock[i], "clock_" + QString::number(i));
+ }
if (is_ao2_bg) {
set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message");
- set_size_and_pos(ui_vp_chatbox, "ao2_chatbox");
+ // set_size_and_pos(ui_vp_chatbox, "ao2_chatbox");
set_size_and_pos(ui_ic_chat_name, "ao2_ic_chat_name");
}
else {
set_size_and_pos(ui_ic_chat_message, "ic_chat_message");
- set_size_and_pos(ui_vp_chatbox, "chatbox");
+ // set_size_and_pos(ui_vp_chatbox, "chatbox");
set_size_and_pos(ui_ic_chat_name, "ic_chat_name");
}
@@ -671,6 +703,10 @@ void Courtroom::set_widgets()
ui_vp_message->y() + ui_vp_chatbox->y());
ui_vp_message->setTextInteractionFlags(Qt::NoTextInteraction);
+ ui_vp_sticker->move(0, 0);
+ ui_vp_sticker->combo_resize(ui_viewport->width(),
+ ui_viewport->height());
+
ui_muted->resize(ui_ic_chat_message->width(), ui_ic_chat_message->height());
ui_muted->set_image("muted");
ui_muted->setToolTip(tr("Oops, you're muted!"));
@@ -712,7 +748,7 @@ void Courtroom::set_widgets()
set_size_and_pos(ui_sfx_dropdown, "sfx_dropdown");
ui_sfx_dropdown->setEditable(true);
- ui_sfx_dropdown->setInsertPolicy(QComboBox::InsertAtBottom);
+ ui_sfx_dropdown->setInsertPolicy(QComboBox::NoInsert);
ui_sfx_dropdown->setToolTip(
tr("Set a sound effect to play on your next 'Preanim'. Leaving it on "
"Default will use the emote-defined sound (if any).\n"
@@ -844,7 +880,8 @@ void Courtroom::set_widgets()
"animation plays concurrently."));
design_ini_result =
- ao_app->get_element_dimensions("immediate", "courtroom_design.ini");
+ ao_app->get_element_dimensions("immediate", "courtroom_design.ini");
+
// If we don't have new-style naming, fall back to the old method
if (design_ini_result.width < 0 || design_ini_result.height < 0) {
set_size_and_pos(ui_immediate, "pre_no_interrupt");
@@ -989,6 +1026,9 @@ void Courtroom::set_fonts(QString p_char)
set_font(ui_area_list, "", "area_list", p_char);
set_font(ui_music_name, "", "music_name", p_char);
+ for (int i = 0; i < max_clocks; i++)
+ set_font(ui_clock[i], "", "clock_" + QString::number(i), p_char);
+
set_dropdowns();
}
@@ -1097,6 +1137,24 @@ void Courtroom::set_size_and_pos(QWidget *p_widget, QString p_identifier)
}
}
+void Courtroom::set_size_and_pos(QWidget *p_widget, QString p_identifier,
+ QString p_char)
+{
+ QString filename = "courtroom_design.ini";
+
+ pos_size_type design_ini_result =
+ ao_app->get_element_dimensions(p_identifier, filename, p_char);
+
+ if (design_ini_result.width < 0 || design_ini_result.height < 0) {
+ qDebug() << "W: could not find \"" << p_identifier << "\" in " << filename;
+ p_widget->hide();
+ }
+ else {
+ p_widget->move(design_ini_result.x, design_ini_result.y);
+ p_widget->resize(design_ini_result.width, design_ini_result.height);
+ }
+}
+
void Courtroom::set_taken(int n_char, bool p_taken)
{
if (n_char >= char_list.size()) {
@@ -1139,13 +1197,20 @@ void Courtroom::done_received()
objection_player->set_volume(0);
blip_player->set_volume(0);
- set_char_select_page();
+ if (char_list.size() > 0)
+ {
+ set_char_select_page();
+ set_char_select();
+ }
+ else
+ {
+ update_character(m_cid);
+ enter_courtroom();
+ }
set_mute_list();
set_pair_list();
- set_char_select();
-
show();
ui_spectator->show();
@@ -1189,11 +1254,11 @@ void Courtroom::set_background(QString p_background, bool display)
is_ao2_bg = true;
if (is_ao2_bg) {
- set_size_and_pos(ui_vp_chatbox, "ao2_chatbox");
+ // set_size_and_pos(ui_vp_chatbox, "ao2_chatbox");
set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message");
}
else {
- set_size_and_pos(ui_vp_chatbox, "chatbox");
+ // set_size_and_pos(ui_vp_chatbox, "chatbox");
set_size_and_pos(ui_ic_chat_message, "ic_chat_message");
}
@@ -1205,10 +1270,13 @@ void Courtroom::set_background(QString p_background, bool display)
ui_vp_effect->stop();
ui_vp_message->hide();
ui_vp_chatbox->hide();
-
// Stop the chat arrow from animating
ui_vp_chat_arrow->stop();
+ // Clear the message queue
+ text_queue_timer->stop();
+ chatmessage_queue.clear();
+
text_state = 2;
anim_state = 3;
ui_vp_objection->stop();
@@ -1256,8 +1324,6 @@ void Courtroom::set_pos_dropdown(QStringList pos_dropdowns)
ui_pos_dropdown->addItems(pos_dropdown_list);
// Unblock the signals so the element can be used for setting pos again
ui_pos_dropdown->blockSignals(false);
-
- qDebug() << pos_dropdown_list;
}
void Courtroom::update_character(int p_cid)
@@ -1300,7 +1366,6 @@ void Courtroom::update_character(int p_cid)
set_sfx_dropdown();
set_effects_dropdown();
- qDebug() << "update_character called";
if (newchar) // Avoid infinite loop of death and suffering
set_iniswap_dropdown();
@@ -1373,6 +1438,12 @@ void Courtroom::update_character(int p_cid)
}
}
}
+ if (is_ao2_bg) {
+ set_size_and_pos(ui_vp_chatbox, "ao2_chatbox", f_char);
+ }
+ else {
+ set_size_and_pos(ui_vp_chatbox, "chatbox", f_char);
+ }
if (m_cid != -1) // there is no name at char_list -1, and we crash if we try
// to find one
@@ -1598,7 +1669,7 @@ void Courtroom::on_chat_return_pressed()
return;
ui_ic_chat_message->blockSignals(true);
- QTimer::singleShot(600, this,
+ QTimer::singleShot(ao_app->get_chat_ratelimit(), this,
[=] { ui_ic_chat_message->blockSignals(false); });
// MS#
// deskmod#
@@ -1657,12 +1728,6 @@ void Courtroom::on_chat_return_pressed()
packet_contents.append(current_side);
packet_contents.append(get_char_sfx());
- if (ui_pre->isChecked() && !ao_app->is_stickysounds_enabled() && ui_sfx_dropdown->currentIndex() > 1) {
- ui_sfx_dropdown->blockSignals(true);
- ui_sfx_dropdown->setCurrentIndex(0);
- ui_sfx_dropdown->blockSignals(false);
- ui_sfx_remove->hide();
- }
int f_emote_mod = ao_app->get_emote_mod(current_char, current_emote);
@@ -1814,7 +1879,8 @@ void Courtroom::on_chat_return_pressed()
packet_contents.append(ui_additive->isChecked() ? "1" : "0");
}
if (ao_app->effects_enabled) {
- QString fx_sound = ao_app->get_effect_sound(effect, current_char);
+ QString fx_sound =
+ ao_app->get_effect_property(effect, current_char, "sound");
QString p_effect =
ao_app->read_char_ini(current_char, "effects", "Options");
packet_contents.append(effect + "|" + p_effect + "|" + fx_sound);
@@ -1829,17 +1895,6 @@ void Courtroom::on_chat_return_pressed()
ao_app->send_server_packet(new AOPacket("MS", packet_contents));
}
-void Courtroom::reset_ic()
-{
- ui_vp_chat_arrow->stop();
- text_state = 0;
- anim_state = 0;
- evidence_presented = false;
- ui_vp_objection->stop();
- chat_tick_timer->stop();
- ui_vp_evidence_display->reset();
-}
-
void Courtroom::reset_ui()
{
ui_ic_chat_message->clear();
@@ -1849,8 +1904,6 @@ void Courtroom::reset_ui()
realization_state = 0;
screenshake_state = 0;
is_presenting_evidence = false;
- if (!ao_app->is_stickypres_enabled())
- ui_pre->setChecked(false);
ui_hold_it->set_image("holdit");
ui_objection->set_image("objection");
ui_take_that->set_image("takethat");
@@ -1858,56 +1911,245 @@ void Courtroom::reset_ui()
ui_realization->set_image("realization");
ui_screenshake->set_image("screenshake");
ui_evidence_present->set_image("present");
+
+ if (ui_pre->isChecked() && !ao_app->is_stickysounds_enabled()) {
+ ui_sfx_dropdown->setCurrentIndex(0);
+ ui_sfx_remove->hide();
+ custom_sfx = "";
+ }
+ if (!ao_app->is_stickypres_enabled())
+ ui_pre->setChecked(false);
}
-void Courtroom::handle_chatmessage(QStringList *p_contents)
+void Courtroom::chatmessage_enqueue(QStringList p_contents)
{
// Instead of checking for whether a message has at least chatmessage_size
// amount of packages, we'll check if it has at least 15.
// That was the original chatmessage_size.
- if (p_contents->size() < MS_MINIMUM)
+ if (p_contents.size() < MS_MINIMUM)
+ return;
+
+ // Check the validity of the character ID we got
+ int f_char_id = p_contents[CHAR_ID].toInt();
+ if (f_char_id < -1 || f_char_id >= char_list.size())
+ return;
+
+ // We muted this char, gtfo
+ if (mute_map.value(f_char_id))
+ return;
+
+ // Reset input UI elements if the char ID matches our client's char ID (most likely, this is our message coming back to us)
+ if (f_char_id == m_cid) {
+ reset_ui();
+ }
+
+ // User-created blankpost
+ if (p_contents[MESSAGE].trimmed().isEmpty()) {
+ // Turn it into true blankpost
+ p_contents[MESSAGE] = "";
+ }
+
+ bool is_objection = false;
+ // If the user wants to clear queue on objection
+ if (ao_app->is_instant_objection_enabled())
+ {
+ int objection_mod = p_contents[OBJECTION_MOD].split("&")[0].toInt();
+ is_objection = objection_mod >= 1 && objection_mod <= 5;
+ // If this is an objection, nuke the queue
+ if (is_objection)
+ chatmessage_queue.clear();
+ }
+
+ // Record the log I/O, log files should be accurate.
+ // If desynced logs are on, display the log IC immediately.
+ LogMode log_mode = ao_app->is_desyncrhonized_logs_enabled() ? DISPLAY_AND_IO : IO_ONLY;
+ log_chatmessage(p_contents[MESSAGE], f_char_id, p_contents[SHOWNAME], p_contents[TEXT_COLOR].toInt(), log_mode);
+ // Send this boi into the queue
+ chatmessage_queue.enqueue(p_contents);
+
+ // Our settings disabled queue, or no message is being parsed right now and we're not waiting on one
+ bool start_queue = ao_app->stay_time() <= 0 || (text_state >= 2 && !text_queue_timer->isActive());
+ // Objections also immediately play the message
+ if (start_queue || is_objection)
+ chatmessage_dequeue(); // Process the message instantly
+ // Otherwise, since a message is being parsed, chat_tick() should be called which will call dequeue once it's done.
+}
+
+void Courtroom::chatmessage_dequeue()
+{
+ // Chat stopped being processed, indicate that the user can post their message now.
+ QString f_custom_theme;
+ if (ao_app->is_customchat_enabled()) {
+ QString f_char = m_chatmessage[CHAR_NAME];
+ f_custom_theme = ao_app->get_chat(f_char);
+ }
+ ui_vp_chat_arrow->load_image("chat_arrow", f_custom_theme);
+
+ // Nothing to parse in the queue
+ if (chatmessage_queue.isEmpty())
return;
- int prev_char_id = m_chatmessage[CHAR_ID].toInt();
+ // Stop the text queue timer
+ if (text_queue_timer->isActive())
+ text_queue_timer->stop();
+
+ unpack_chatmessage(chatmessage_queue.dequeue());
+}
+
+void Courtroom::unpack_chatmessage(QStringList p_contents)
+{
for (int n_string = 0; n_string < MS_MAXIMUM; ++n_string) {
// Note that we have added stuff that vanilla clients and servers simply
// won't send. So now, we have to check if the thing we want even exists
// amongst the packet's content. We also have to check if the server even
// supports CCCC's IC features, or if it's just japing us. Also, don't
// forget! A size 15 message will have indices from 0 to 14.
- if (n_string < p_contents->size() &&
+ if (n_string < p_contents.size() &&
(n_string < MS_MINIMUM || ao_app->cccc_ic_support_enabled)) {
- m_chatmessage[n_string] = p_contents->at(n_string);
+ m_chatmessage[n_string] = p_contents.at(n_string);
}
else {
m_chatmessage[n_string] = "";
}
}
- int f_char_id = m_chatmessage[CHAR_ID].toInt();
- const bool is_spectator = (f_char_id == -1);
+ if (!ao_app->is_desyncrhonized_logs_enabled()) {
+ // We have logs displaying as soon as we reach the message in our queue, which is a less confusing but also less accurate experience for the user.
+ log_chatmessage(m_chatmessage[MESSAGE], m_chatmessage[CHAR_ID].toInt(), m_chatmessage[SHOWNAME], m_chatmessage[TEXT_COLOR].toInt(), DISPLAY_ONLY);
+ }
- if (f_char_id < -1 || f_char_id >= char_list.size())
- return;
- if (mute_map.value(m_chatmessage[CHAR_ID].toInt()))
- return;
+ // Process the callwords for this message
+ handle_callwords();
- QString f_displayname;
- if (!is_spectator &&
- (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked())) {
- // If the users is not a spectator and showname is disabled, use the
- // character's name
- f_displayname = ao_app->get_showname(char_list.at(f_char_id).name);
+ // Reset the interface to make room for objection handling
+ ui_vp_chat_arrow->stop();
+ text_state = 0;
+ anim_state = 0;
+ evidence_presented = false;
+ ui_vp_objection->stop();
+ chat_tick_timer->stop();
+ ui_vp_evidence_display->reset();
+ // This chat msg is not objection so we're not waiting on the objection animation to finish to display the character.
+ if (!handle_objection())
+ handle_ic_message();
+}
+
+void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_showname, int f_color, LogMode f_log_mode)
+{
+ // Display name will use the showname
+ QString f_displayname = f_showname;
+ if (f_char_id != -1) {
+ // Grab the char.ini showname
+ f_showname = ao_app->get_showname(char_list.at(f_char_id).name);
+ // If custom serversided shownames are not enabled
+ if (!ui_showname_enable->isChecked()) {
+ // Set the display name to the char.ini showname
+ f_displayname = f_showname;
+ }
}
- else {
- // Otherwise, use the showname
- f_displayname = m_chatmessage[SHOWNAME];
+ // If display name is just whitespace, use the char.ini showname.
+ if (f_displayname.trimmed().isEmpty())
+ f_displayname = f_showname;
+
+ if (log_ic_actions) {
+ // Check if a custom objection is in use
+ int objection_mod = 0;
+ QString custom_objection = "";
+ if (m_chatmessage[OBJECTION_MOD].contains("4&")) {
+ objection_mod = 4;
+ custom_objection = m_chatmessage[OBJECTION_MOD].split(
+ "4&")[1]; // takes the name of custom objection.
+ }
+ else {
+ objection_mod = m_chatmessage[OBJECTION_MOD].toInt();
+ }
+
+ QString f_char = m_chatmessage[CHAR_NAME];
+ QString f_custom_theme = ao_app->get_char_shouts(f_char);
+ if (objection_mod <= 4 && objection_mod >= 1) {
+ QString shout_message;
+ switch (objection_mod) {
+ case 1:
+ shout_message = ao_app->read_char_ini(f_char, "holdit_message", "Shouts");
+ if (shout_message == "")
+ shout_message = tr("HOLD IT!");
+ break;
+ case 2:
+ shout_message = ao_app->read_char_ini(f_char, "objection_message", "Shouts");
+ if (shout_message == "")
+ shout_message = tr("OBJECTION!");
+ break;
+ case 3:
+ shout_message = ao_app->read_char_ini(f_char, "takethat_message", "Shouts");
+ if (shout_message == "")
+ shout_message = tr("TAKE THAT!");
+ break;
+ // case 4 is AO2 only
+ case 4:
+ if (custom_objection != "") {
+ shout_message = ao_app->read_char_ini(f_char, custom_objection.split('.')[0] + "_message", "Shouts");
+ if (shout_message == "")
+ shout_message = custom_objection.split('.')[0];
+ }
+ else {
+ shout_message = ao_app->read_char_ini(f_char, "custom_message", "Shouts");
+ if (shout_message == "")
+ shout_message = tr("CUSTOM OBJECTION!");
+ }
+ break;
+ }
+ switch (f_log_mode) {
+ case IO_ONLY:
+ log_ic_text(f_char, f_displayname, shout_message, tr("shouts"));
+ break;
+ case DISPLAY_AND_IO:
+ log_ic_text(f_char, f_displayname, shout_message, tr("shouts"));
+ [[fallthrough]];
+ case DISPLAY_ONLY:
+ append_ic_text(shout_message, f_displayname, tr("shouts"));
+ break;
+ }
+ }
+
+ // Obtain evidence ID we're trying to work with
+ int f_evi_id = m_chatmessage[EVIDENCE_ID].toInt();
+ // If the evidence ID is in the valid range
+ if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) {
+ // Obtain the evidence name
+ QString f_evi_name = local_evidence_list.at(f_evi_id - 1).name;
+ switch (f_log_mode) {
+ case IO_ONLY:
+ log_ic_text(f_showname, f_displayname, f_evi_name, tr("has presented evidence"));
+ break;
+ case DISPLAY_AND_IO:
+ log_ic_text(f_showname, f_displayname, f_evi_name, tr("has presented evidence"));
+ [[fallthrough]];
+ case DISPLAY_ONLY:
+ append_ic_text(f_evi_name, f_displayname, tr("has presented evidence"));
+ break;
+ }
+ }
}
- // If chatblank is enabled, use the character's name for logs
- if (f_displayname.trimmed().isEmpty())
- f_displayname = ao_app->get_showname(char_list.at(f_char_id).name);
+ // If the chat message isn't a blankpost, or the chatlog history is empty, or its last message isn't a blankpost
+ if (!f_message.isEmpty() ||
+ ic_chatlog_history.isEmpty() || ic_chatlog_history.last().get_message() != "") {
+ switch (f_log_mode) {
+ case IO_ONLY:
+ log_ic_text(f_showname, f_displayname, f_message, "",f_color);
+ break;
+ case DISPLAY_AND_IO:
+ log_ic_text(f_showname, f_displayname, f_message, "",f_color);
+ [[fallthrough]];
+ case DISPLAY_ONLY:
+ append_ic_text(f_message, f_displayname, "",f_color);
+ break;
+ }
+ }
+}
+bool Courtroom::handle_objection()
+{
// Check if a custom objection is in use
int objection_mod = 0;
QString custom_objection = "";
@@ -1920,103 +2162,109 @@ void Courtroom::handle_chatmessage(QStringList *p_contents)
objection_mod = m_chatmessage[OBJECTION_MOD].toInt();
}
- // Reset IC display
- reset_ic();
-
- // Reset UI elements after client message gets sent
- if (m_chatmessage[CHAR_ID].toInt() == m_cid) {
- reset_ui();
+ if (is_ao2_bg) {
+ set_size_and_pos(ui_vp_chatbox, "ao2_chatbox", m_chatmessage[CHAR_NAME]);
}
-
- QString f_charname = "";
- if (f_char_id >= 0)
- f_charname = ao_app->get_showname(char_list.at(f_char_id).name);
-
- if (m_chatmessage[MESSAGE].trimmed().isEmpty()) // User-created blankpost
- {
- m_chatmessage[MESSAGE] = ""; // Turn it into true blankpost
+ else {
+ set_size_and_pos(ui_vp_chatbox, "chatbox", m_chatmessage[CHAR_NAME]);
}
-
- QString f_char = m_chatmessage[CHAR_NAME];
- QString f_custom_theme = ao_app->get_char_shouts(f_char);
+ set_size_and_pos(ui_vp_showname, "showname", m_chatmessage[CHAR_NAME]);
+ set_size_and_pos(ui_vp_message, "message", m_chatmessage[CHAR_NAME]);
+ ui_vp_message->move(ui_vp_message->x() + ui_vp_chatbox->x(),
+ ui_vp_message->y() + ui_vp_chatbox->y());
+ ui_vp_message->setTextInteractionFlags(Qt::NoTextInteraction);
// if an objection is used
if (objection_mod <= 4 && objection_mod >= 1) {
- QString shout_message;
+ ui_vp_objection->set_static_duration(shout_static_time);
+ ui_vp_objection->set_max_duration(shout_max_time);
+ QString filename;
switch (objection_mod) {
case 1:
- ui_vp_objection->play("holdit_bubble", f_char, f_custom_theme, 724);
- objection_player->play("holdit", f_char, f_custom_theme);
- shout_message = ao_app->read_char_ini(f_char, "holdit_message", "Shouts");
- if (shout_message == "")
- shout_message = tr("HOLD IT!");
+ filename = "holdit_bubble";
+ objection_player->play("holdit", m_chatmessage[CHAR_NAME],
+ ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
break;
case 2:
- ui_vp_objection->play("objection_bubble", f_char, f_custom_theme, 724);
- objection_player->play("objection", f_char, f_custom_theme);
- shout_message = ao_app->read_char_ini(f_char, "objection_message", "Shouts");
- if (shout_message == "")
- shout_message = tr("OBJECTION!");
+ filename = "objection_bubble";
+ objection_player->play("objection", m_chatmessage[CHAR_NAME],
+ ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
if (ao_app->objection_stop_music())
music_player->stop();
break;
case 3:
- ui_vp_objection->play("takethat_bubble", f_char, f_custom_theme, 724);
- objection_player->play("takethat", f_char, f_custom_theme);
- shout_message = ao_app->read_char_ini(f_char, "takethat_message", "Shouts");
- if (shout_message == "")
- shout_message = tr("TAKE THAT!");
+ filename = "takethat_bubble";
+ objection_player->play("takethat", m_chatmessage[CHAR_NAME],
+ ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
break;
// case 4 is AO2 only
case 4:
if (custom_objection != "") {
- ui_vp_objection->play("custom_objections/" + custom_objection, f_char,
- f_custom_theme, shout_stay_time);
- objection_player->play("custom_objections/" +
- custom_objection.split('.')[0],
- f_char, f_custom_theme);
- shout_message = ao_app->read_char_ini(f_char, custom_objection.split('.')[0] + "_message", "Shouts");
- if (shout_message == "")
- shout_message = custom_objection.split('.')[0];
+ filename = "custom_objections/" + custom_objection;
+ objection_player->play(
+ "custom_objections/" + custom_objection.split('.')[0],
+ m_chatmessage[CHAR_NAME],
+ ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
}
else {
- ui_vp_objection->play("custom", f_char, f_custom_theme,
- shout_stay_time);
- objection_player->play("custom", f_char, f_custom_theme);
- shout_message = ao_app->read_char_ini(f_char, "custom_message", "Shouts");
- if (shout_message == "")
- shout_message = tr("CUSTOM OBJECTION!");
+ filename = "custom";
+ objection_player->play(
+ "custom", m_chatmessage[CHAR_NAME],
+ ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
}
+ break;
m_chatmessage[EMOTE_MOD] = 1;
- break;
}
- log_ic_text(f_char, f_displayname, shout_message,
- tr("shouts"),2);
- append_ic_text(shout_message, f_displayname, tr("shouts"));
+ ui_vp_objection->load_image(
+ filename, m_chatmessage[CHAR_NAME],
+ ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
sfx_player->clear(); // Objection played! Cut all sfx.
+ return true;
}
- else
- handle_chatmessage_2();
-
- if (!m_chatmessage[MESSAGE].isEmpty() || ic_chatlog_history.isEmpty() ||
- ic_chatlog_history.last().get_message() != "") {
- log_ic_text(f_charname, f_displayname, m_chatmessage[MESSAGE], "",
- m_chatmessage[TEXT_COLOR].toInt());
- append_ic_text(m_chatmessage[MESSAGE], f_displayname, "",
- m_chatmessage[TEXT_COLOR].toInt());
- }
+ display_character();
+ return false;
}
-void Courtroom::objection_done() { handle_chatmessage_2(); }
+void Courtroom::effect_done()
+{
+ ui_vp_effect->stop();
+ ui_vp_wtce->stop();
+}
-void Courtroom::handle_chatmessage_2()
+void Courtroom::display_character()
{
+ // Stop all previously playing animations, effects etc.
ui_vp_speedlines->stop();
ui_vp_player_char->stop();
ui_vp_effect->stop();
// Clear all looping sfx to prevent obnoxiousness
sfx_player->loop_clear();
+ // Hide the message and chatbox and handle the emotes
+ ui_vp_message->hide();
+ ui_vp_chatbox->hide();
+ // Hide the face sticker
+ ui_vp_sticker->stop();
+ // Initialize the correct pos (called SIDE here for some reason) with DESK_MOD to determine if we should hide the desk or not.
+ switch(m_chatmessage[DESK_MOD].toInt()) {
+ case 4:
+ set_self_offset(m_chatmessage[SELF_OFFSET]);
+ [[fallthrough]];
+ case 2:
+ set_scene("1", m_chatmessage[SIDE]);
+ break;
+ case 5:
+ ui_vp_sideplayer_char->hide();
+ ui_vp_player_char->move(0, 0);
+ [[fallthrough]];
+ case 3:
+ set_scene("0", m_chatmessage[SIDE]);
+ break;
+ default:
+ set_scene(m_chatmessage[DESK_MOD], m_chatmessage[SIDE]);
+ break;
+ }
+ // Arrange the netstrings of the frame SFX for the character to know about
if (!m_chatmessage[FRAME_SFX].isEmpty() &&
ao_app->is_frame_network_enabled()) {
// ORDER IS IMPORTANT!!
@@ -2028,249 +2276,145 @@ void Courtroom::handle_chatmessage_2()
else
ui_vp_player_char->network_strings.clear();
- int f_charid = m_chatmessage[CHAR_ID].toInt();
- if (f_charid >= 0 &&
- (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked())) {
- QString real_name = char_list.at(f_charid).name;
-
- QString f_showname = ao_app->get_showname(real_name);
-
- ui_vp_showname->setText(f_showname);
- }
- else {
- ui_vp_showname->setText(m_chatmessage[SHOWNAME]);
- }
-
- QString customchar;
- if (ao_app->is_customchat_enabled())
- customchar = m_chatmessage[CHAR_NAME];
- if (ui_vp_showname->text().trimmed().isEmpty()) // Whitespace showname
- {
- ui_vp_chatbox->set_image("chatblank");
- }
- else // Aw yeah dude do some showname magic
- {
- if (!ui_vp_chatbox->set_image("chat"))
- ui_vp_chatbox->set_image("chatbox");
-
- QFontMetrics fm(ui_vp_showname->font());
-// Gotta support the slow paced ubuntu 18 STUCK IN 5.9.5!!
-#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
- int fm_width = fm.horizontalAdvance(ui_vp_showname->text());
-#else
- int fm_width = fm.boundingRect((ui_vp_showname->text())).width();
-#endif
- QString chatbox_path = ao_app->get_theme_path("chat");
- QString chatbox = ao_app->get_chat(customchar);
-
- if (chatbox != "" && ao_app->is_customchat_enabled()) {
- chatbox_path = ao_app->get_base_path() + "misc/" + chatbox + "/chat";
- if (!ui_vp_chatbox->set_chatbox(chatbox_path))
- ui_vp_chatbox->set_chatbox(chatbox_path + "box");
- }
-
- // This should probably be called only if any change from the last chat
- // arrow was actually detected.
- pos_size_type design_ini_result = ao_app->get_element_dimensions(
- "chat_arrow", "courtroom_design.ini", customchar);
- if (design_ini_result.width < 0 || design_ini_result.height < 0) {
- qDebug() << "W: could not find \"chat_arrow\" in courtroom_design.ini";
- ui_vp_chat_arrow->hide();
- }
- else {
- ui_vp_chat_arrow->move(design_ini_result.x, design_ini_result.y);
- ui_vp_chat_arrow->combo_resize(design_ini_result.width,
- design_ini_result.height);
- }
+ // Determine if we should flip the character or not (what servers don't support flipping at this point?)
+ if (ao_app->flipping_enabled && m_chatmessage[FLIP].toInt() == 1)
+ ui_vp_player_char->set_flipped(true);
+ else
+ ui_vp_player_char->set_flipped(false);
- pos_size_type default_width = ao_app->get_element_dimensions(
- "showname", "courtroom_design.ini", customchar);
- int extra_width =
- ao_app
- ->get_design_element("showname_extra_width", "courtroom_design.ini",
- customchar)
- .toInt();
- QString align = ao_app
- ->get_design_element("showname_align",
- "courtroom_design.ini", customchar)
- .toLower();
- if (align == "right")
- ui_vp_showname->setAlignment(Qt::AlignRight);
- else if (align == "center")
- ui_vp_showname->setAlignment(Qt::AlignHCenter);
- else if (align == "justify")
- ui_vp_showname->setAlignment(Qt::AlignHCenter);
- else
- ui_vp_showname->setAlignment(Qt::AlignLeft);
+ // Parse the character X offset
+ QStringList offsets = m_chatmessage[SELF_OFFSET].split("&");
+ int offset_x = offsets[0].toInt();
+ // Y offset is 0 by default unless we find that the server sent us the Y position as well
+ int offset_y = 0;
+ if (offsets.length() > 1)
+ offset_y = offsets[1].toInt();
+ // Move the character on the viewport according to the offsets
+ ui_vp_player_char->move(ui_viewport->width() * offset_x / 100, ui_viewport->height() * offset_y / 100);
+}
- if (extra_width > 0) {
- if (fm_width > default_width.width &&
- ui_vp_chatbox->set_chatbox(
- chatbox_path +
- "med")) // This text be big. Let's do some shenanigans.
- {
- ui_vp_showname->resize(default_width.width + extra_width,
- ui_vp_showname->height());
- if (fm_width > ui_vp_showname->width() &&
- ui_vp_chatbox->set_chatbox(chatbox_path +
- "big")) // Biggest possible size for us.
- {
- ui_vp_showname->resize(
- static_cast<int>(default_width.width + (extra_width * 2)),
- ui_vp_showname->height());
- }
+void Courtroom::display_pair_character(QString other_charid, QString other_offset)
+{
+ // If pair information exists
+ if (!other_charid.isEmpty()) {
+ // Initialize the "ok" bool check to see if the toInt conversion succeeded
+ bool ok;
+ // Grab the charid of the pair
+ int charid = other_charid.split("^")[0].toInt(&ok);
+ // If the charid is an int and is valid...
+ if (ok && charid > -1) {
+ // Show the pair character
+ ui_vp_sideplayer_char->show();
+ // Obtain the offsets, splitting it up by & char
+ QStringList offsets = other_offset.split("&");
+ int offset_x;
+ int offset_y;
+ // If we only got one number...
+ if (offsets.length() <= 1) {
+ // That's just the X offset. Make Y offset 0.
+ offset_x = other_offset.toInt();
+ offset_y = 0;
}
+ else {
+ // We got two numbers, set x and y offsets!
+ offset_x = offsets[0].toInt();
+ offset_y = offsets[1].toInt();
+ }
+ // Move pair character according to the offsets
+ ui_vp_sideplayer_char->move(ui_viewport->width() * offset_x / 100,
+ ui_viewport->height() * offset_y / 100);
+
+ // Flip the pair character
+ if (ao_app->flipping_enabled && m_chatmessage[OTHER_FLIP].toInt() == 1)
+ ui_vp_sideplayer_char->set_flipped(true);
else
- ui_vp_showname->resize(default_width.width, ui_vp_showname->height());
+ ui_vp_sideplayer_char->set_flipped(false);
- set_font(ui_vp_showname, "", "showname", customchar);
- }
- else {
- ui_vp_showname->resize(default_width.width, ui_vp_showname->height());
+ // Play the other pair character's idle animation
+ QString filename = "(a)" + m_chatmessage[OTHER_EMOTE];
+ ui_vp_sideplayer_char->load_image(filename, m_chatmessage[OTHER_NAME],
+ 0, false);
+ }
}
- }
-
- ui_vp_message->hide();
- ui_vp_chatbox->hide();
-
- QString font_name;
- QString chatfont = ao_app->get_chat_font(m_chatmessage[CHAR_NAME]);
- if (chatfont != "")
- font_name = chatfont;
-
- int f_pointsize = 0;
- int chatsize = ao_app->get_chat_size(m_chatmessage[CHAR_NAME]);
- if (chatsize > 0)
- f_pointsize = chatsize;
- set_font(ui_vp_message, "", "message", customchar, font_name, f_pointsize);
+}
- int emote_mod = m_chatmessage[EMOTE_MOD].toInt();
+void Courtroom::handle_emote_mod(int emote_mod, bool p_immediate)
+{
// Deal with invalid emote modifiers
if (emote_mod != 0 && emote_mod != 1 && emote_mod != 2 && emote_mod != 5 &&
emote_mod != 6) {
+ // If emote mod is 4...
if (emote_mod == 4)
emote_mod = 6; // Addresses issue with an old bug that sent the wrong
// emote modifier for zoompre
else
- emote_mod = 0;
+ emote_mod = 0; // Reset emote mod to 0
}
- if (ao_app->flipping_enabled && m_chatmessage[FLIP].toInt() == 1)
- ui_vp_player_char->set_flipped(true);
- else
- ui_vp_player_char->set_flipped(false);
-
- QString side = m_chatmessage[SIDE];
-
- // Making the second character appear.
- if (m_chatmessage[OTHER_CHARID].isEmpty()) {
- // If there is no second character, hide 'em
- ui_vp_sideplayer_char->stop();
- ui_vp_sideplayer_char->move(0, 0);
- }
- else {
- bool ok;
- int got_other_charid = m_chatmessage[OTHER_CHARID].split("^")[0].toInt(&ok);
- if (ok) {
- if (got_other_charid > -1) {
- // If there is, show them!
- ui_vp_sideplayer_char->show();
- QStringList other_offsets = m_chatmessage[OTHER_OFFSET].split("&");
- int other_offset;
- int other_offset_v;
- if (other_offsets.length() <= 1) {
- other_offset = m_chatmessage[OTHER_OFFSET].toInt();
- other_offset_v = 0;
- }
- else {
- other_offset = other_offsets[0].toInt();
- other_offset_v = other_offsets[1].toInt();
- }
- ui_vp_sideplayer_char->move(ui_viewport->width() * other_offset / 100,
- ui_viewport->height() * other_offset_v /
- 100);
-
- QStringList args = m_chatmessage[OTHER_CHARID].split("^");
- if (args.size() >
- 1) // This ugly workaround is so we don't make an extra packet just
- // for this purpose. Rewrite pairing when?
- {
- // Change the order of appearance based on the pair order variable
- int order = args.at(1).toInt();
- switch (order) {
- case 0:
- ui_vp_sideplayer_char->stackUnder(ui_vp_player_char);
- break;
- case 1:
- ui_vp_player_char->stackUnder(ui_vp_sideplayer_char);
- break;
- default:
- break;
- }
- }
-
- // We should probably also play the other character's idle emote.
- if (ao_app->flipping_enabled && m_chatmessage[OTHER_FLIP].toInt() == 1)
- ui_vp_sideplayer_char->set_flipped(true);
- else
- ui_vp_sideplayer_char->set_flipped(false);
- ui_vp_sideplayer_char->play_idle(m_chatmessage[OTHER_NAME],
- m_chatmessage[OTHER_EMOTE]);
- }
- else {
- // If the server understands other characters, but there
- // really is no second character, hide 'em, and center the first.
- ui_vp_sideplayer_char->hide();
- ui_vp_sideplayer_char->move(0, 0);
- }
- }
- }
- // Set ourselves according to SELF_OFFSET
-
- QStringList self_offsets = m_chatmessage[SELF_OFFSET].split("&");
- int self_offset = self_offsets[0].toInt();
- int self_offset_v;
- if (self_offsets.length() <= 1)
- self_offset_v = 0;
- else
- self_offset_v = self_offsets[1].toInt();
- ui_vp_player_char->move(ui_viewport->width() * self_offset / 100,
- ui_viewport->height() * self_offset_v / 100);
-
- switch(m_chatmessage[DESK_MOD].toInt()) {
- case 4:
- ui_vp_sideplayer_char->hide();
- ui_vp_player_char->move(0, 0);
- [[fallthrough]];
- case 2:
- set_scene("0", m_chatmessage[SIDE]);
- break;
- case 5:
- case 3:
- set_scene("1", m_chatmessage[SIDE]);
- break;
- default:
- set_scene(m_chatmessage[DESK_MOD], m_chatmessage[SIDE]);
- break;
- }
+ // Handle the emote mod
switch (emote_mod) {
case 1:
case 2:
case 6:
+ // Emotes 1, 2 and 6 all play preanim that makes the chatbox wait for it to finish.
play_preanim(false);
break;
case 0:
case 5:
- if (m_chatmessage[IMMEDIATE].toInt() == 0)
- handle_chatmessage_3();
+ // If immediate is not ticked on...
+ if (!p_immediate)
+ {
+ // Skip preanim.
+ handle_ic_speaking();
+ }
else
+ {
+ // Emotes 0, 5 all play preanim alongside the chatbox, not waiting for the animation to finish.
play_preanim(true);
+ }
break;
default:
+ // This should never happen, but if it does anyway, yell in the console about it.
qDebug() << "W: invalid emote mod: " << QString::number(emote_mod);
}
}
+void Courtroom::objection_done() { handle_ic_message(); }
+
+void Courtroom::handle_ic_message()
+{
+ // Display our own character
+ display_character();
+
+ // Reset the pair character
+ ui_vp_sideplayer_char->stop();
+ ui_vp_sideplayer_char->move(0, 0);
+
+ // If the emote_mod is not zooming
+ int emote_mod = m_chatmessage[EMOTE_MOD].toInt();
+ if (emote_mod != 5 && emote_mod != 6) {
+ // Display the pair character
+ display_pair_character(m_chatmessage[OTHER_CHARID], m_chatmessage[OTHER_OFFSET]);
+ }
+
+ // Parse the emote_mod part of the chat message
+ handle_emote_mod(m_chatmessage[EMOTE_MOD].toInt(), m_chatmessage[IMMEDIATE].toInt() == 1);
+
+ // Update the chatbox information
+ initialize_chatbox();
+
+ // if we have instant objections disabled, and queue is not empty, check if next message after this is an objection.
+ if (!ao_app->is_instant_objection_enabled() && chatmessage_queue.size() > 0)
+ {
+ QStringList p_contents = chatmessage_queue.head();
+ int objection_mod = p_contents[OBJECTION_MOD].split("&")[0].toInt();
+ bool is_objection = objection_mod >= 1 && objection_mod <= 5;
+ // If this is an objection, we'll need to interrupt our current message.
+ if (is_objection)
+ text_queue_timer->start(objection_threshold);
+ }
+}
+
void Courtroom::do_screenshake()
{
if (!ao_app->is_shake_enabled())
@@ -2322,7 +2466,11 @@ void Courtroom::do_flash()
QString f_char = m_chatmessage[CHAR_NAME];
QString f_custom_theme = ao_app->get_char_shouts(f_char);
- ui_vp_effect->play("realizationflash", f_char, f_custom_theme, 60);
+ ui_vp_effect->stretch = true;
+ ui_vp_effect->set_static_duration(60);
+ ui_vp_effect->set_max_duration(60);
+ ui_vp_effect->load_image(
+ ao_app->get_effect("realization", f_char, f_custom_theme), false);
}
void Courtroom::do_effect(QString fx_name, QString fx_sound, QString p_char,
@@ -2339,131 +2487,231 @@ void Courtroom::do_effect(QString fx_name, QString fx_sound, QString p_char,
// Only check if effects are disabled after playing the sound if it exists
if (!ao_app->is_effects_enabled())
return;
-
+ ui_vp_effect->transform_mode = ao_app->get_scaling(
+ ao_app->get_effect_property(fx_name, p_char, "scaling"));
+ ui_vp_effect->stretch =
+ ao_app->get_effect_property(fx_name, p_char, "stretch")
+ .startsWith("true");
ui_vp_effect->set_play_once(
false); // The effects themselves dictate whether or not they're looping.
// Static effects will linger.
- ui_vp_effect->play(effect); // It will set_play_once to true if the filepath
- // provided is not designed to loop more than once
+ ui_vp_effect->set_static_duration(0);
+ ui_vp_effect->set_max_duration(0);
+ ui_vp_effect->load_image(effect, false);
}
void Courtroom::play_char_sfx(QString sfx_name)
{
sfx_player->play(sfx_name);
- // sfx_player->set_looping(false);
- // if (ao_app->get_looping_sfx())
- // sfx_player->set_looping(
- // ao_app->get_sfx_looping(current_char, current_emote) == "1");
}
-void Courtroom::handle_chatmessage_3()
+void Courtroom::initialize_chatbox()
{
- int f_evi_id = m_chatmessage[EVIDENCE_ID].toInt();
- QString f_side = m_chatmessage[SIDE];
-
- QString f_showname;
- int f_char_id = m_chatmessage[CHAR_ID].toInt();
- if (f_char_id > -1 &&
+ int f_charid = m_chatmessage[CHAR_ID].toInt();
+ if (f_charid >= 0 && f_charid < char_list.size() &&
(m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked())) {
- f_showname = ao_app->get_showname(char_list.at(f_char_id).name);
+ QString real_name = char_list.at(f_charid).name;
+ ui_vp_player_char->set_static_duration(0);
+ QString f_showname = ao_app->get_showname(real_name);
+
+ ui_vp_showname->setText(f_showname);
}
else {
- f_showname = m_chatmessage[SHOWNAME];
+ ui_vp_showname->setText(m_chatmessage[SHOWNAME]);
+ }
+
+ QString customchar;
+ if (ao_app->is_customchat_enabled())
+ customchar = m_chatmessage[CHAR_NAME];
+ if (ui_vp_showname->text().trimmed().isEmpty()) // Whitespace showname
+ {
+ ui_vp_chatbox->set_image("chatblank");
}
- if (f_showname.trimmed()
- .isEmpty()) // Pure whitespace showname, get outta here.
- f_showname = m_chatmessage[CHAR_NAME];
+ else // Aw yeah dude do some showname magic
+ {
+ if (!ui_vp_chatbox->set_image("chat"))
+ ui_vp_chatbox->set_image("chatbox");
+
+ QFontMetrics fm(ui_vp_showname->font());
+// Gotta support the slow paced ubuntu 18 STUCK IN 5.9.5!!
+#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
+ int fm_width = fm.horizontalAdvance(ui_vp_showname->text());
+#else
+ int fm_width = fm.boundingRect((ui_vp_showname->text())).width();
+#endif
+ QString chatbox_path = ao_app->get_theme_path("chat");
+ QString chatbox = ao_app->get_chat(customchar);
- if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size() &&
- !evidence_presented) {
+ if (chatbox != "" && ao_app->is_customchat_enabled()) {
+ chatbox_path = ao_app->get_theme_path("misc/" + chatbox + "/chat");
+ if (!ui_vp_chatbox->set_chatbox(chatbox_path)) {
+ chatbox_path = ao_app->get_base_path() + "misc/" + chatbox + "/chat";
+ if (!ui_vp_chatbox->set_chatbox(chatbox_path))
+ ui_vp_chatbox->set_chatbox(chatbox_path + "box");
+ }
+ }
+
+ // This should probably be called only if any change from the last chat
+ // arrow was actually detected.
+ if (current_misc != last_misc) {
+ pos_size_type design_ini_result = ao_app->get_element_dimensions(
+ "chat_arrow", "courtroom_design.ini", customchar);
+ if (design_ini_result.width < 0 || design_ini_result.height < 0) {
+ qDebug() << "W: could not find \"chat_arrow\" in courtroom_design.ini";
+ ui_vp_chat_arrow->hide();
+ }
+ else {
+ ui_vp_chat_arrow->move(design_ini_result.x + ui_vp_chatbox->x(), design_ini_result.y + ui_vp_chatbox->y());
+ ui_vp_chat_arrow->combo_resize(design_ini_result.width,
+ design_ini_result.height);
+ }
+ }
+
+ pos_size_type default_width = ao_app->get_element_dimensions(
+ "showname", "courtroom_design.ini", customchar);
+ int extra_width =
+ ao_app
+ ->get_design_element("showname_extra_width", "courtroom_design.ini",
+ customchar)
+ .toInt();
+ QString align = ao_app
+ ->get_design_element("showname_align",
+ "courtroom_design.ini", customchar)
+ .toLower();
+ if (align == "right")
+ ui_vp_showname->setAlignment(Qt::AlignRight);
+ else if (align == "center")
+ ui_vp_showname->setAlignment(Qt::AlignHCenter);
+ else if (align == "justify")
+ ui_vp_showname->setAlignment(Qt::AlignHCenter);
+ else
+ ui_vp_showname->setAlignment(Qt::AlignLeft);
+
+ if (extra_width > 0) {
+ if (fm_width > default_width.width &&
+ ui_vp_chatbox->set_chatbox(
+ chatbox_path +
+ "med")) // This text be big. Let's do some shenanigans.
+ {
+ ui_vp_showname->resize(default_width.width + extra_width,
+ ui_vp_showname->height());
+ if (fm_width > ui_vp_showname->width() &&
+ ui_vp_chatbox->set_chatbox(chatbox_path +
+ "big")) // Biggest possible size for us.
+ {
+ ui_vp_showname->resize(
+ static_cast<int>(default_width.width + (extra_width * 2)),
+ ui_vp_showname->height());
+ }
+ }
+ else
+ ui_vp_showname->resize(default_width.width, ui_vp_showname->height());
+
+ set_font(ui_vp_showname, "", "showname", customchar);
+ }
+ else {
+ ui_vp_showname->resize(default_width.width, ui_vp_showname->height());
+ }
+ }
+
+ QString font_name;
+ QString chatfont = ao_app->get_chat_font(m_chatmessage[CHAR_NAME]);
+ if (chatfont != "")
+ font_name = chatfont;
+
+ int f_pointsize = 0;
+ int chatsize = ao_app->get_chat_size(m_chatmessage[CHAR_NAME]);
+ if (chatsize > 0)
+ f_pointsize = chatsize;
+ set_font(ui_vp_message, "", "message", customchar, font_name, f_pointsize);
+}
+
+void Courtroom::handle_callwords()
+{
+ // Quickly check through the message for the word_call (callwords) sfx
+ QString f_message = m_chatmessage[MESSAGE];
+ // Obtain the current call words (Really? It does File I/O on every single message???)
+ QStringList call_words = ao_app->get_call_words();
+ // Loop through each word in the call words list
+ for (QString word : call_words) {
+ // If our message contains that specific call word
+ if (f_message.contains(word, Qt::CaseInsensitive)) {
+ // Play the call word sfx on the modcall_player sound container
+ modcall_player->play(ao_app->get_sfx("word_call"));
+ // Make the window flash
+ ao_app->alert(this);
+ // Break the loop so we don't spam sound effects
+ break;
+ }
+ }
+}
+
+void Courtroom::display_evidence_image()
+{
+ QString side = m_chatmessage[SIDE];
+ int f_evi_id = m_chatmessage[EVIDENCE_ID].toInt();
+ if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) {
// shifted by 1 because 0 is no evidence per legacy standards
QString f_image = local_evidence_list.at(f_evi_id - 1).image;
QString f_evi_name = local_evidence_list.at(f_evi_id - 1).name;
// def jud and hlp should display the evidence icon on the RIGHT side
- bool is_left_side = !(f_side == "def" || f_side == "hlp" ||
- f_side == "jud" || f_side == "jur");
+ bool is_left_side = !(side == "def" || side == "hlp" ||
+ side == "jud" || side == "jur");
ui_vp_evidence_display->show_evidence(f_image, is_left_side,
ui_sfx_slider->value());
- if (log_ic_actions) {
- log_ic_text(m_chatmessage[CHAR_NAME], m_chatmessage[SHOWNAME], f_evi_name,
- tr("has presented evidence"),
- m_chatmessage[TEXT_COLOR].toInt());
- append_ic_text(f_evi_name, f_showname, tr("has presented evidence"));
- }
- evidence_presented = true; // we're done presenting evidence, and we
- // don't want to do it twice
}
+}
- int emote_mod = m_chatmessage[EMOTE_MOD].toInt();
-
+void Courtroom::handle_ic_speaking()
+{
+ // Display the evidence
+ display_evidence_image();
QString side = m_chatmessage[SIDE];
-
- switch(m_chatmessage[DESK_MOD].toInt()) {
- case 4:
- set_self_offset(m_chatmessage[SELF_OFFSET]);
- [[fallthrough]];
- case 2:
- set_scene("1", m_chatmessage[SIDE]);
- break;
- case 5:
- ui_vp_sideplayer_char->hide();
- ui_vp_player_char->move(0, 0);
- [[fallthrough]];
- case 3:
- set_scene("0", m_chatmessage[SIDE]);
- break;
- default:
- set_scene(m_chatmessage[DESK_MOD], m_chatmessage[SIDE]);
- break;
- }
+ int emote_mod = m_chatmessage[EMOTE_MOD].toInt();
+ // emote_mod 5 is zoom and emote_mod 6 is zoom w/ preanim.
if (emote_mod == 5 || emote_mod == 6) {
+ // Hide the desks
ui_vp_desk->hide();
- ui_vp_legacy_desk->hide();
-
- // Since we're zooming, hide the second character, and centre the first.
- ui_vp_sideplayer_char->hide();
- ui_vp_player_char->move(0, 0);
- QString f_char = m_chatmessage[CHAR_NAME];
- QString f_custom_theme = ao_app->get_char_shouts(f_char);
+ // Obtain character information for our character
+ QString filename;
+ // I still hate this hardcoding. If we're on pos pro, hlp and wit, use prosecution_speedlines. Otherwise, defense_speedlines.
if (side == "pro" || side == "hlp" || side == "wit")
- ui_vp_speedlines->play("prosecution_speedlines", f_char, f_custom_theme);
+ filename = "prosecution_speedlines";
else
- ui_vp_speedlines->play("defense_speedlines", f_char, f_custom_theme);
+ filename = "defense_speedlines";
+ ui_vp_speedlines->load_image(filename, m_chatmessage[CHAR_NAME]);
}
- // If this color is talking
+ // Check if this is a talking color (white text, etc.)
color_is_talking =
color_markdown_talking_list.at(m_chatmessage[TEXT_COLOR].toInt());
-
+ QString filename;
+ // If color is talking, and our state isn't already talking
if (color_is_talking && text_state == 1 &&
- anim_state < 2) // Set it to talking as we're not on that already
+ anim_state < 2)
{
+ // Stop the previous animation and play the talking animation
ui_vp_player_char->stop();
- ui_vp_player_char->play_talking(m_chatmessage[CHAR_NAME],
- m_chatmessage[EMOTE]);
+ ui_vp_player_char->set_play_once(false);
+ filename = "(b)" + m_chatmessage[EMOTE];
+ ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, false);
+ // Set the anim state accordingly
anim_state = 2;
}
- else if (anim_state < 3) // Set it to idle as we're not on that already
+ else if (anim_state < 3 &&
+ anim_state != 3) // Set it to idle as we're not on that already
{
+ // Stop the previous animation and play the idle animation
ui_vp_player_char->stop();
- ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME],
- m_chatmessage[EMOTE]);
+ ui_vp_player_char->set_play_once(false);
+ filename = "(a)" + m_chatmessage[EMOTE];
+ ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, false);
+ // Set the anim state accordingly
anim_state = 3;
}
- QString f_message = m_chatmessage[MESSAGE];
- QStringList call_words = ao_app->get_call_words();
-
- for (QString word : call_words) {
- if (f_message.contains(word, Qt::CaseInsensitive)) {
- modcall_player->play(ao_app->get_sfx("word_call"));
- ao_app->alert(this);
-
- break;
- }
- }
-
+ // Begin parsing through the chatbox message
start_chat_ticking();
}
@@ -2715,7 +2963,7 @@ void Courtroom::log_ic_text(QString p_name, QString p_showname,
{
chatlogpiece log_entry(p_name, p_showname, p_message, p_action, p_color);
ic_chatlog_history.append(log_entry);
- if (ao_app->get_auto_logging_enabled())
+ if (ao_app->get_auto_logging_enabled() && !ao_app->log_filename.isEmpty())
ao_app->append_to_file(log_entry.get_full(), ao_app->log_filename, true);
while (ic_chatlog_history.size() > log_maximum_blocks &&
@@ -2769,8 +3017,16 @@ void Courtroom::append_ic_text(QString p_text, QString p_name, QString p_action,
// Make shout text bold
else if (p_action == tr("shouts") && log_ic_actions) {
ui_ic_chatlog->textCursor().insertText(" " + p_action + " ", normal);
- if (log_colors)
- ui_ic_chatlog->textCursor().insertHtml("<b>" + filter_ic_text(p_text, true, -1, 0) + "</b>");
+ if (log_colors) {
+ ui_ic_chatlog->textCursor().insertHtml(
+ "<b>" +
+ filter_ic_text(p_text, true, -1, 0)
+ .replace(
+ "$c0",
+ ao_app->get_color("ic_chatlog_color", "courtroom_fonts.ini")
+ .name(QColor::HexRgb)) +
+ "</b>");
+ }
else
ui_ic_chatlog->textCursor().insertText(" " + p_text, italics);
}
@@ -2849,11 +3105,10 @@ void Courtroom::play_preanim(bool immediate)
{
QString f_char = m_chatmessage[CHAR_NAME];
QString f_preanim = m_chatmessage[PRE_EMOTE];
-
// all time values in char.inis are multiplied by a constant(time_mod) to get
// the actual time
int ao2_duration = ao_app->get_ao2_preanim_duration(f_char, f_preanim);
- int text_delay = ao_app->get_text_delay(f_char, f_preanim) * time_mod;
+ int stay_time = ao_app->get_text_delay(f_char, f_preanim) * time_mod;
int sfx_delay = m_chatmessage[SFX_DELAY].toInt() * time_mod;
int preanim_duration;
@@ -2872,28 +3127,30 @@ void Courtroom::play_preanim(bool immediate)
else
anim_state = 1;
preanim_done();
- qDebug() << "could not find " + anim_to_find;
+ qDebug() << "W: could not find " + anim_to_find;
return;
}
-
- ui_vp_player_char->play_pre(f_char, f_preanim, preanim_duration);
+ ui_vp_player_char->set_static_duration(preanim_duration);
+ ui_vp_player_char->set_play_once(true);
+ ui_vp_player_char->load_image(f_preanim, f_char, preanim_duration, true);
if (immediate)
anim_state = 4;
else
anim_state = 1;
- if (text_delay >= 0)
- text_delay_timer->start(text_delay);
+ if (stay_time >= 0)
+ text_delay_timer->start(stay_time);
if (immediate)
- handle_chatmessage_3();
+ handle_ic_speaking();
}
void Courtroom::preanim_done()
{
anim_state = 1;
- handle_chatmessage_3();
+ qDebug() << "preanim over, anim_state set to 1";
+ handle_ic_speaking();
}
void Courtroom::start_chat_ticking()
@@ -2941,6 +3198,8 @@ void Courtroom::start_chat_ticking()
ui_vp_chatbox->show();
ui_vp_message->show();
+ ui_vp_sticker->load_image(m_chatmessage[CHAR_NAME]);
+
if (m_chatmessage[ADDITIVE] != "1") {
ui_vp_message->clear();
real_tick_pos = 0;
@@ -2964,6 +3223,8 @@ void Courtroom::start_chat_ticking()
// means text is currently ticking
text_state = 1;
+
+ c_played = false;
}
void Courtroom::chat_tick()
@@ -2975,13 +3236,30 @@ void Courtroom::chat_tick()
// Due to our new text speed system, we always need to stop the timer now.
chat_tick_timer->stop();
+ ui_vp_player_char->set_static_duration(0);
+ QString filename;
if (tick_pos >= f_message.size()) {
text_state = 2;
if (anim_state < 3) {
- anim_state = 3;
- ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME],
- m_chatmessage[EMOTE]);
+ QStringList c_paths = {
+ ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)" + m_chatmessage[EMOTE])),
+ ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)/" + m_chatmessage[EMOTE]))
+ };
+ // if there is a (c) animation for this emote and we haven't played it already
+ if (file_exists(ui_vp_player_char->find_image(c_paths)) &&(!c_played)) {
+ anim_state = 5;
+ ui_vp_player_char->set_play_once(true);
+ filename = "(c)" + m_chatmessage[EMOTE];
+ c_played = true;
+ }
+ else {
+ anim_state = 3;
+ ui_vp_player_char->set_play_once(false);
+ filename = "(a)" + m_chatmessage[EMOTE];
+ }
+ ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
+ false);
}
QString f_char;
QString f_custom_theme;
@@ -2989,15 +3267,33 @@ void Courtroom::chat_tick()
f_char = m_chatmessage[CHAR_NAME];
f_custom_theme = ao_app->get_chat(f_char);
}
- ui_vp_chat_arrow->play(
- "chat_arrow", f_char,
- f_custom_theme); // Chat stopped being processed, indicate that.
- QString f_message_filtered = filter_ic_text(f_message, true, -1, m_chatmessage[TEXT_COLOR].toInt());
+ ui_vp_chat_arrow->load_image("chat_arrow",f_custom_theme); // Chat stopped being processed, indicate that.
+ additive_previous =
+ additive_previous +
+ filter_ic_text(f_message, true, -1, m_chatmessage[TEXT_COLOR].toInt());
+ QString f_message_filtered = filter_ic_text(f_message, true, -1, m_chatmessage[TEXT_COLOR].toInt());
for (int c = 0; c < max_colors; ++c) {
f_message_filtered = f_message_filtered.replace("$c" + QString::number(c), char_color_rgb_list.at(c).name(QColor::HexRgb));
}
additive_previous = additive_previous + f_message_filtered;
real_tick_pos = ui_vp_message->toPlainText().size();
+
+
+ // If we're not already waiting on the next message, start the timer. We could be overriden if there's an objection planned.
+ int delay = ao_app->stay_time();
+ if (delay > 0 && !text_queue_timer->isActive())
+ text_queue_timer->start(delay);
+
+ // if we have instant objections disabled, and queue is not empty, check if next message after this is an objection.
+ if (!ao_app->is_instant_objection_enabled() && chatmessage_queue.size() > 0)
+ {
+ QStringList p_contents = chatmessage_queue.head();
+ int objection_mod = p_contents[OBJECTION_MOD].split("&")[0].toInt();
+ bool is_objection = objection_mod >= 1 && objection_mod <= 5;
+ // If this is an objection, we'll need to interrupt our current message.
+ if (is_objection)
+ chatmessage_dequeue();
+ }
return;
}
@@ -3171,16 +3467,20 @@ void Courtroom::chat_tick()
// to avoid interrupting a non-interrupted preanim)
{
ui_vp_player_char->stop();
- ui_vp_player_char->play_talking(m_chatmessage[CHAR_NAME],
- m_chatmessage[EMOTE]);
+ ui_vp_player_char->set_play_once(false);
+ filename = "(b)" + m_chatmessage[EMOTE];
+ ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
+ false);
anim_state = 2;
}
else if (!color_is_talking && anim_state < 3 &&
anim_state != 3) // Set it to idle as we're not on that already
{
ui_vp_player_char->stop();
- ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME],
- m_chatmessage[EMOTE]);
+ ui_vp_player_char->set_play_once(false);
+ filename = "(a)" + m_chatmessage[EMOTE];
+ ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
+ false);
anim_state = 3;
}
// Continue ticking
@@ -3265,19 +3565,15 @@ void Courtroom::set_scene(QString f_desk_mod, QString f_side)
f_background = f_side;
f_desk_image = f_side + "_overlay";
}
-
- ui_vp_background->set_image(f_background);
- ui_vp_desk->set_image(f_desk_image);
- ui_vp_legacy_desk->set_legacy_desk(f_desk_image);
+ ui_vp_background->load_image(f_background);
+ ui_vp_desk->load_image(f_desk_image);
if (f_desk_mod == "0" ||
(f_desk_mod != "1" &&
(f_side == "jud" || f_side == "hld" || f_side == "hlp"))) {
ui_vp_desk->hide();
- ui_vp_legacy_desk->hide();
}
else {
- ui_vp_legacy_desk->hide();
ui_vp_desk->show();
}
}
@@ -3402,13 +3698,11 @@ void Courtroom::handle_song(QStringList *p_contents)
if (!mute_map.value(n_char)) {
if (f_song == "~stop.mp3") {
- log_ic_text(str_char, str_show, "", tr("has stopped the music"),
- m_chatmessage[TEXT_COLOR].toInt());
+ log_ic_text(str_char, str_show, "", tr("has stopped the music"));
append_ic_text("", str_show, tr("has stopped the music"));
}
else {
- log_ic_text(str_char, str_show, f_song, tr("has played a song"),
- m_chatmessage[TEXT_COLOR].toInt());
+ log_ic_text(str_char, str_show, f_song, tr("has played a song"));
append_ic_text(f_song_clear, str_show, tr("has played a song"));
}
music_player->play(f_song, channel, looping, effect_flags);
@@ -3427,31 +3721,40 @@ void Courtroom::handle_song(QStringList *p_contents)
void Courtroom::handle_wtce(QString p_wtce, int variant)
{
QString sfx_file = "courtroom_sounds.ini";
-
+ QString sfx_name;
+ QString filename;
+ ui_vp_wtce->set_static_duration(wtce_static_time);
+ ui_vp_wtce->set_max_duration(wtce_max_time);
// witness testimony
if (p_wtce == "testimony1") {
- sfx_player->play(ao_app->get_sfx("witness_testimony"));
- ui_vp_wtce->play("witnesstestimony", "", "", 1500);
- ui_vp_testimony->play("testimony");
+ sfx_name = "witness_testimony";
+ filename = "witnesstestimony";
+ ui_vp_testimony->load_image("testimony", "");
}
// cross examination
else if (p_wtce == "testimony2") {
- sfx_player->play(ao_app->get_sfx("cross_examination"));
- ui_vp_wtce->play("crossexamination", "", "", 1500);
+ sfx_name = "cross_examination";
+ filename = "crossexamination";
ui_vp_testimony->stop();
}
else if (p_wtce == "judgeruling") {
+ ui_vp_wtce->set_static_duration(verdict_static_time);
+ ui_vp_wtce->set_max_duration(verdict_max_time);
if (variant == 0) {
- sfx_player->play(ao_app->get_sfx("not_guilty"));
- ui_vp_wtce->play("notguilty", "", "", 3000);
+ sfx_name = "not_guilty";
+ filename = "notguilty";
ui_vp_testimony->stop();
}
else if (variant == 1) {
- sfx_player->play(ao_app->get_sfx("guilty"));
- ui_vp_wtce->play("guilty", "", "", 3000);
+ sfx_name = "guilty";
+ filename = "guilty";
ui_vp_testimony->stop();
}
}
+ QString bg_misc = ao_app->read_design_ini("misc", ao_app->get_background_path("design.ini"));
+ sfx_player->play(ao_app->get_sfx(sfx_name, bg_misc));
+ ui_vp_wtce->load_image(filename, "", bg_misc);
+ ui_vp_wtce->set_play_once(true);
}
void Courtroom::set_hp_bar(int p_bar, int p_state)
@@ -3522,9 +3825,6 @@ void Courtroom::on_ooc_return_pressed()
{
QString ooc_message = ui_ooc_chat_message->text();
- if (ooc_message == "" || ui_ooc_chat_name->text() == "")
- return;
-
if (ooc_message.startsWith("/pos")) {
if (ooc_message == "/pos jud") {
toggle_judge_buttons(true);
@@ -4049,28 +4349,28 @@ void Courtroom::set_sfx_dropdown()
ui_sfx_remove->hide();
return;
}
- QStringList soundlist = ao_app->get_list_file(
+ // Initialzie character sound list first. Will be empty if not found.
+ sound_list = ao_app->get_list_file(
ao_app->get_character_path(current_char, "soundlist.ini"));
- if (soundlist.size() <= 0) {
- soundlist = ao_app->get_list_file(
- ao_app->get_theme_path("character_soundlist.ini"));
- if (soundlist.size() <= 0) {
- soundlist = ao_app->get_list_file(
- ao_app->get_default_theme_path("character_soundlist.ini"));
- }
- }
+ // Append default sound list after the character sound list.
+ sound_list += ao_app->get_list_file(
+ ao_app->get_base_path() + "soundlist.ini");
- if (soundlist.size() <= 0) {
- ui_sfx_dropdown->hide();
- ui_sfx_remove->hide();
- return;
+ QStringList display_sounds;
+ for (QString sound : sound_list) {
+ QStringList unpacked = sound.split("=");
+ QString display = unpacked[0].trimmed();
+ if (unpacked.size() > 1)
+ display = unpacked[1].trimmed();
+
+ display_sounds.append(display);
}
- soundlist.prepend("Nothing");
- soundlist.prepend("Default");
+ display_sounds.prepend("Nothing");
+ display_sounds.prepend("Default");
ui_sfx_dropdown->show();
- ui_sfx_dropdown->addItems(soundlist);
+ ui_sfx_dropdown->addItems(display_sounds);
ui_sfx_dropdown->setCurrentIndex(0);
ui_sfx_remove->hide();
ui_sfx_dropdown->blockSignals(false);
@@ -4078,37 +4378,16 @@ void Courtroom::set_sfx_dropdown()
void Courtroom::on_sfx_dropdown_changed(int p_index)
{
+ UNUSED(p_index);
ui_ic_chat_message->setFocus();
+ ui_sfx_remove->hide();
+ custom_sfx = "";
+}
- QStringList soundlist;
- for (int i = 2; i < ui_sfx_dropdown->count(); ++i) {
- QString entry = ui_sfx_dropdown->itemText(i);
- if (!soundlist.contains(entry))
- soundlist.append(entry);
- }
-
- QStringList defaultlist =
- ao_app->get_list_file(ao_app->get_theme_path("character_soundlist.ini"));
- if (defaultlist.size() <= 0) {
- defaultlist = ao_app->get_list_file(
- ao_app->get_default_theme_path("character_soundlist.ini"));
- }
-
- if (defaultlist.size() > 0 &&
- defaultlist.toSet().subtract(soundlist.toSet()).size() >
- 0) // There's a difference from the default configuration
- ao_app->write_to_file(
- soundlist.join("\n"),
- ao_app->get_character_path(current_char,
- "soundlist.ini")); // Create a new sound list
-
- ui_sfx_dropdown->blockSignals(true);
- ui_sfx_dropdown->setCurrentIndex(p_index);
- ui_sfx_dropdown->blockSignals(false);
- if (p_index > 1)
- ui_sfx_remove->show();
- else
- ui_sfx_remove->hide();
+void Courtroom::on_sfx_dropdown_custom(QString p_sfx)
+{
+ ui_sfx_remove->show();
+ custom_sfx = p_sfx;
}
void Courtroom::on_sfx_context_menu_requested(const QPoint &pos)
@@ -4121,40 +4400,27 @@ void Courtroom::on_sfx_context_menu_requested(const QPoint &pos)
menu->addAction(QString("Edit " + current_char + "/soundlist.ini"), this,
SLOT(on_sfx_edit_requested()));
else
- menu->addAction(QString("Edit theme's character_soundlist.ini"), this,
+ menu->addAction(QString("Edit global soundlist.ini"), this,
SLOT(on_sfx_edit_requested()));
- if (ui_sfx_dropdown->currentIndex() > 1)
- menu->addAction(QString("Remove " + ui_sfx_dropdown->itemText(
- ui_sfx_dropdown->currentIndex())),
- this, SLOT(on_sfx_remove_clicked()));
+ if (!custom_sfx.isEmpty())
+ menu->addAction(QString("Clear Edit Text"), this, SLOT(on_sfx_remove_clicked()));
menu->popup(ui_sfx_dropdown->mapToGlobal(pos));
}
+
void Courtroom::on_sfx_edit_requested()
{
QString p_path = ao_app->get_character_path(current_char, "soundlist.ini");
if (!file_exists(p_path)) {
- p_path = ao_app->get_theme_path("character_soundlist.ini");
- if (!file_exists(p_path)) {
- p_path = ao_app->get_default_theme_path("character_soundlist.ini");
- if (!file_exists(p_path)) {
- return;
- }
+ p_path = ao_app->get_base_path() + "soundlist.ini";
}
- }
QDesktopServices::openUrl(QUrl::fromLocalFile(p_path));
}
void Courtroom::on_sfx_remove_clicked()
{
- if (ui_sfx_dropdown->count() <= 0) {
- ui_sfx_remove->hide(); // We're not supposed to see it. Do this or the
- // client will crash
- return;
- }
- if (ui_sfx_dropdown->currentIndex() > 1) {
- ui_sfx_dropdown->removeItem(ui_sfx_dropdown->currentIndex());
- on_sfx_dropdown_changed(0); // Reset back to original
- }
+ ui_sfx_remove->hide();
+ ui_sfx_dropdown->setCurrentIndex(0);
+ custom_sfx = "";
}
void Courtroom::set_effects_dropdown()
@@ -4257,19 +4523,21 @@ bool Courtroom::effects_dropdown_find_and_set(QString effect)
QString Courtroom::get_char_sfx()
{
- QString sfx = ui_sfx_dropdown->itemText(ui_sfx_dropdown->currentIndex());
- if (sfx == "Nothing")
- return "1";
- if (sfx != "" && sfx != "Default")
- return sfx;
- return ao_app->get_sfx_name(current_char, current_emote);
+ if (!custom_sfx.isEmpty())
+ return custom_sfx;
+ int index = ui_sfx_dropdown->currentIndex();
+ if (index == 0) // Default
+ return ao_app->get_sfx_name(current_char, current_emote);
+ if (index == 1) // Nothing
+ return "1";
+ QString sfx = sound_list[index-2].split("=")[0].trimmed();
+ if (sfx == "")
+ return "1";
+ return sfx;
}
int Courtroom::get_char_sfx_delay()
{
- // QString sfx = ui_sfx_dropdown->itemText(ui_sfx_dropdown->currentIndex());
- // if (sfx != "" && sfx != "Default")
- // return 0; //todo: a way to define this
return ao_app->get_sfx_delay(current_char, current_emote);
}
@@ -4472,12 +4740,12 @@ void Courtroom::music_stop()
void Courtroom::on_area_list_double_clicked(QTreeWidgetItem *p_item, int column)
{
column = 0; // The metadata
+ UNUSED(column); // so gcc shuts up
QString p_area = p_item->text(0);
QStringList packet_contents;
packet_contents.append(p_area);
packet_contents.append(QString::number(m_cid));
- qDebug() << packet_contents;
ao_app->send_server_packet(new AOPacket("MC", packet_contents), false);
}
@@ -4709,18 +4977,18 @@ void Courtroom::set_text_color_dropdown()
QColor color =
ao_app->get_chat_color("c" + QString::number(c), current_char);
color_rgb_list.append(color);
- color_markdown_start_list.append(ao_app->get_chat_markdown(
+ color_markdown_start_list.append(ao_app->get_chat_markup(
"c" + QString::number(c) + "_start", current_char));
- color_markdown_end_list.append(ao_app->get_chat_markdown(
+ color_markdown_end_list.append(ao_app->get_chat_markup(
"c" + QString::number(c) + "_end", current_char));
color_markdown_remove_list.append(
- ao_app->get_chat_markdown("c" + QString::number(c) + "_remove",
- current_char) == "1");
+ ao_app->get_chat_markup("c" + QString::number(c) + "_remove",
+ current_char) == "1");
color_markdown_talking_list.append(
- ao_app->get_chat_markdown("c" + QString::number(c) + "_talking",
- current_char) != "0");
+ ao_app->get_chat_markup("c" + QString::number(c) + "_talking",
+ current_char) != "0");
- QString color_name = ao_app->get_chat_markdown(
+ QString color_name = ao_app->get_chat_markup(
"c" + QString::number(c) + "_name", current_char);
if (color_name.isEmpty()) // Not defined
{
@@ -4971,12 +5239,16 @@ void Courtroom::on_showname_enable_clicked()
void Courtroom::regenerate_ic_chatlog()
{
ui_ic_chatlog->clear();
+ last_ic_message = "";
foreach (chatlogpiece item, ic_chatlog_history) {
- append_ic_text(item.get_message(),
- ui_showname_enable->isChecked() ? item.get_showname()
- : item.get_name(),
+ QString message = item.get_message();
+ QString name = ui_showname_enable->isChecked() ? item.get_showname()
+ : item.get_name();
+ append_ic_text(message,
+ name,
item.get_action(), item.get_chat_color(),
item.get_datetime().toLocalTime());
+ last_ic_message = name + ":" + message;
}
}
@@ -5007,10 +5279,21 @@ void Courtroom::on_switch_area_music_clicked()
void Courtroom::ping_server()
{
+ ping_timer.start();
+ is_pinging = true;
ao_app->send_server_packet(
new AOPacket("CH#" + QString::number(m_cid) + "#%"));
}
+qint64 Courtroom::pong()
+{
+ if (!is_pinging)
+ return -1;
+
+ is_pinging = false;
+ return ping_timer.elapsed();
+}
+
void Courtroom::on_casing_clicked()
{
if (ao_app->casing_alerts_enabled) {
@@ -5050,6 +5333,54 @@ void Courtroom::announce_case(QString title, bool def, bool pro, bool jud,
}
}
+void Courtroom::start_clock(int id)
+{
+ if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
+ {
+ ui_clock[id]->start();
+ }
+}
+
+void Courtroom::start_clock(int id, qint64 msecs)
+{
+ if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
+ {
+ ui_clock[id]->start(static_cast<int>(msecs));
+ }
+}
+
+void Courtroom::set_clock(int id, qint64 msecs)
+{
+ if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
+ {
+ ui_clock[id]->set(static_cast<int>(msecs), true);
+ }
+}
+
+void Courtroom::pause_clock(int id)
+{
+ if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
+ {
+ ui_clock[id]->pause();
+ }
+}
+
+void Courtroom::stop_clock(int id)
+{
+ if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
+ {
+ ui_clock[id]->stop();
+ }
+}
+
+void Courtroom::set_clock_visibility(int id, bool visible)
+{
+ if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
+ {
+ ui_clock[id]->setVisible(visible);
+ }
+}
+
void Courtroom::truncate_label_text(QWidget *p_widget, QString p_identifier)
{
QString filename = "courtroom_design.ini";