Merge branch 'master' into crystalwarrior/demo-reload
This commit is contained in:
		
						commit
						de4115e20a
					
				@ -1 +1 @@
 | 
				
			|||||||
Subproject commit c9acb90137361ea8c29bc4cf2bf530d14b52b23a
 | 
					Subproject commit 7c036c09ddfadc2680a2c5dbfa188dc98142a427
 | 
				
			||||||
@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class AOImage : public QLabel {
 | 
					class AOImage : public QLabel {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  AOImage(QWidget *parent, AOApplication *p_ao_app);
 | 
					  AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static = false);
 | 
				
			||||||
  ~AOImage();
 | 
					  ~AOImage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QWidget *m_parent;
 | 
					  QWidget *m_parent;
 | 
				
			||||||
@ -20,6 +20,8 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  QString path;
 | 
					  QString path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool is_static = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool set_image(QString p_image, QString p_misc = "");
 | 
					  bool set_image(QString p_image, QString p_misc = "");
 | 
				
			||||||
  void set_size_and_pos(QString identifier);
 | 
					  void set_size_and_pos(QString identifier);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,7 @@ public:
 | 
				
			|||||||
  bool force_continuous = false;
 | 
					  bool force_continuous = false;
 | 
				
			||||||
  Qt::TransformationMode transform_mode = Qt::FastTransformation; // transformation mode to use for this image
 | 
					  Qt::TransformationMode transform_mode = Qt::FastTransformation; // transformation mode to use for this image
 | 
				
			||||||
  bool stretch = false; // Should we stretch/squash this image to fill the screen?
 | 
					  bool stretch = false; // Should we stretch/squash this image to fill the screen?
 | 
				
			||||||
 | 
					  bool masked = true; // Set a mask to the dimensions of the widget?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Set the movie's image to provided paths, preparing for playback.
 | 
					  // Set the movie's image to provided paths, preparing for playback.
 | 
				
			||||||
  void start_playback(QString p_image);
 | 
					  void start_playback(QString p_image);
 | 
				
			||||||
 | 
				
			|||||||
@ -235,7 +235,7 @@ public:
 | 
				
			|||||||
    DISPLAY_AND_IO
 | 
					    DISPLAY_AND_IO
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  // Log the message contents and information such as evidence presenting etc. into the log file, the IC log, or both.
 | 
					  // Log the message contents and information such as evidence presenting etc. into the log file, the IC log, or both.
 | 
				
			||||||
  void log_chatmessage(QString f_message, int f_char_id, QString f_showname = "", int f_color = 0, LogMode f_log_mode=IO_ONLY);
 | 
					  void log_chatmessage(QString f_message, int f_char_id, QString f_showname = "", QString f_char = "", QString f_objection_mod = "", int f_evi_id = 0, int f_color = 0, LogMode f_log_mode=IO_ONLY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Log the message contents and information such as evidence presenting etc. into the IC logs
 | 
					  // Log the message contents and information such as evidence presenting etc. into the IC logs
 | 
				
			||||||
  void handle_callwords();
 | 
					  void handle_callwords();
 | 
				
			||||||
@ -755,7 +755,6 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  QVector<AOCharButton *> ui_char_button_list;
 | 
					  QVector<AOCharButton *> ui_char_button_list;
 | 
				
			||||||
  QVector<AOCharButton *> ui_char_button_list_filtered;
 | 
					  QVector<AOCharButton *> ui_char_button_list_filtered;
 | 
				
			||||||
  AOImage *ui_selector;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  AOButton *ui_back_to_lobby;
 | 
					  AOButton *ui_back_to_lobby;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@
 | 
				
			|||||||
#include <QTcpSocket>
 | 
					#include <QTcpSocket>
 | 
				
			||||||
#include <QTimer>
 | 
					#include <QTimer>
 | 
				
			||||||
#include <QFileDialog>
 | 
					#include <QFileDialog>
 | 
				
			||||||
 | 
					#include <QMessageBox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DemoServer : public QObject
 | 
					class DemoServer : public QObject
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -15,19 +15,19 @@ AOCharButton::AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos,
 | 
				
			|||||||
  this->resize(60, 60);
 | 
					  this->resize(60, 60);
 | 
				
			||||||
  this->move(x_pos, y_pos);
 | 
					  this->move(x_pos, y_pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_taken = new AOImage(this, ao_app);
 | 
					  ui_taken = new AOImage(this, ao_app, true);
 | 
				
			||||||
  ui_taken->resize(60, 60);
 | 
					  ui_taken->resize(60, 60);
 | 
				
			||||||
  ui_taken->set_image("char_taken");
 | 
					  ui_taken->set_image("char_taken");
 | 
				
			||||||
  ui_taken->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
					  ui_taken->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
				
			||||||
  ui_taken->hide();
 | 
					  ui_taken->hide();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_passworded = new AOImage(this, ao_app);
 | 
					  ui_passworded = new AOImage(this, ao_app, true);
 | 
				
			||||||
  ui_passworded->resize(60, 60);
 | 
					  ui_passworded->resize(60, 60);
 | 
				
			||||||
  ui_passworded->set_image("char_passworded");
 | 
					  ui_passworded->set_image("char_passworded");
 | 
				
			||||||
  ui_passworded->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
					  ui_passworded->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
				
			||||||
  ui_passworded->hide();
 | 
					  ui_passworded->hide();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_selector = new AOImage(parent, ao_app);
 | 
					  ui_selector = new AOImage(parent, ao_app, true);
 | 
				
			||||||
  ui_selector->resize(62, 62);
 | 
					  ui_selector->resize(62, 62);
 | 
				
			||||||
  ui_selector->move(x_pos - 1, y_pos - 1);
 | 
					  ui_selector->move(x_pos - 1, y_pos - 1);
 | 
				
			||||||
  ui_selector->set_image("char_selector");
 | 
					  ui_selector->set_image("char_selector");
 | 
				
			||||||
 | 
				
			|||||||
@ -9,14 +9,14 @@ AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app,
 | 
				
			|||||||
  ao_app = p_ao_app;
 | 
					  ao_app = p_ao_app;
 | 
				
			||||||
  m_parent = p_parent;
 | 
					  m_parent = p_parent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_selected = new AOImage(this, ao_app);
 | 
					  ui_selected = new AOImage(this, ao_app, true);
 | 
				
			||||||
  ui_selected->resize(p_w, p_h);
 | 
					  ui_selected->resize(p_w, p_h);
 | 
				
			||||||
  //  ui_selected->move(p_x, p_y);
 | 
					  //  ui_selected->move(p_x, p_y);
 | 
				
			||||||
  ui_selected->set_image("evidence_selected");
 | 
					  ui_selected->set_image("evidence_selected");
 | 
				
			||||||
  ui_selected->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
					  ui_selected->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
				
			||||||
  ui_selected->hide();
 | 
					  ui_selected->hide();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_selector = new AOImage(this, ao_app);
 | 
					  ui_selector = new AOImage(this, ao_app, true);
 | 
				
			||||||
  ui_selector->resize(p_w, p_h);
 | 
					  ui_selector->resize(p_w, p_h);
 | 
				
			||||||
  //  ui_selector->move(p_x - 1, p_y - 1);
 | 
					  //  ui_selector->move(p_x - 1, p_y - 1);
 | 
				
			||||||
  ui_selector->set_image("evidence_selector");
 | 
					  ui_selector->set_image("evidence_selector");
 | 
				
			||||||
 | 
				
			|||||||
@ -4,18 +4,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <QBitmap>
 | 
					#include <QBitmap>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent)
 | 
					AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static) : QLabel(parent)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  m_parent = parent;
 | 
					  m_parent = parent;
 | 
				
			||||||
  ao_app = p_ao_app;
 | 
					  ao_app = p_ao_app;
 | 
				
			||||||
  movie = new QMovie();
 | 
					  is_static = make_static;
 | 
				
			||||||
  connect(movie, &QMovie::frameChanged, [=]{
 | 
					  if (!is_static) // Only create the QMovie if we're non-static
 | 
				
			||||||
    QPixmap f_pixmap = movie->currentPixmap();
 | 
					  {
 | 
				
			||||||
    f_pixmap =
 | 
					    movie = new QMovie(this);
 | 
				
			||||||
        f_pixmap.scaled(this->size(), Qt::IgnoreAspectRatio);
 | 
					    connect(movie, &QMovie::frameChanged, [=]{
 | 
				
			||||||
    this->setPixmap(f_pixmap);
 | 
					      QPixmap f_pixmap = movie->currentPixmap();
 | 
				
			||||||
    this->setMask(f_pixmap.mask());
 | 
					      f_pixmap =
 | 
				
			||||||
  });
 | 
					          f_pixmap.scaled(this->size(), Qt::IgnoreAspectRatio);
 | 
				
			||||||
 | 
					      this->setPixmap(f_pixmap);
 | 
				
			||||||
 | 
					      this->setMask(f_pixmap.mask());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AOImage::~AOImage() {}
 | 
					AOImage::~AOImage() {}
 | 
				
			||||||
@ -23,7 +27,7 @@ AOImage::~AOImage() {}
 | 
				
			|||||||
bool AOImage::set_image(QString p_path, QString p_misc)
 | 
					bool AOImage::set_image(QString p_path, QString p_misc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // Check if the user wants animated themes
 | 
					  // Check if the user wants animated themes
 | 
				
			||||||
  if (ao_app->get_animated_theme())
 | 
					  if (!is_static && ao_app->get_animated_theme())
 | 
				
			||||||
    // We want an animated image
 | 
					    // We want an animated image
 | 
				
			||||||
    p_path = ao_app->get_image(p_path, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_misc);
 | 
					    p_path = ao_app->get_image(p_path, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_misc);
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
@ -35,12 +39,14 @@ bool AOImage::set_image(QString p_path, QString p_misc)
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  path = p_path;
 | 
					  path = p_path;
 | 
				
			||||||
  movie->stop();
 | 
					  if (!is_static) {
 | 
				
			||||||
  movie->setFileName(path);
 | 
					    movie->stop();
 | 
				
			||||||
  if (ao_app->get_animated_theme() && movie->frameCount() > 1) {
 | 
					    movie->setFileName(path);
 | 
				
			||||||
    movie->start();
 | 
					    if (ao_app->get_animated_theme() && movie->frameCount() > 1) {
 | 
				
			||||||
 | 
					      movie->start();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  if (is_static || !ao_app->get_animated_theme() || movie->frameCount() <= 1) {
 | 
				
			||||||
    QPixmap f_pixmap(path);
 | 
					    QPixmap f_pixmap(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    f_pixmap =
 | 
					    f_pixmap =
 | 
				
			||||||
 | 
				
			|||||||
@ -98,9 +98,10 @@ void AOLayer::center_pixmap(QPixmap f_pixmap) {
 | 
				
			|||||||
      x + (f_w - f_pixmap.width()) / 2,
 | 
					      x + (f_w - f_pixmap.width()) / 2,
 | 
				
			||||||
      y + (f_h - f_pixmap.height())); // Always center horizontally, always put
 | 
					      y + (f_h - f_pixmap.height())); // Always center horizontally, always put
 | 
				
			||||||
                                      // at the bottom vertically
 | 
					                                      // at the bottom vertically
 | 
				
			||||||
  this->setMask(
 | 
					  if (masked)
 | 
				
			||||||
      QRegion((f_pixmap.width() - f_w) / 2, (f_pixmap.height() - f_h) / 2, f_w,
 | 
					      this->setMask(
 | 
				
			||||||
              f_h)); // make sure we don't escape the area we've been given
 | 
					          QRegion((f_pixmap.width() - f_w) / 2, (f_pixmap.height() - f_h) / 2, f_w,
 | 
				
			||||||
 | 
					                  f_h)); // make sure we don't escape the area we've been given
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AOLayer::combo_resize(int w, int h)
 | 
					void AOLayer::combo_resize(int w, int h)
 | 
				
			||||||
@ -196,20 +197,20 @@ void CharLayer::load_image(QString p_filename, QString p_charname,
 | 
				
			|||||||
           << " continuous: " << continuous;
 | 
					           << " continuous: " << continuous;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
  QStringList pathlist = {
 | 
					  QStringList pathlist = {
 | 
				
			||||||
      ao_app->get_image_suffix(ao_app->get_character_path(
 | 
					      ao_app->get_character_path(
 | 
				
			||||||
          p_charname, prefix + current_emote)), // Default path
 | 
					          p_charname, prefix + current_emote), // Default path
 | 
				
			||||||
      ao_app->get_image_suffix(ao_app->get_character_path(
 | 
					      ao_app->get_character_path(
 | 
				
			||||||
          p_charname,
 | 
					          p_charname,
 | 
				
			||||||
          prefix + "/" + current_emote)), // Path check if it's categorized
 | 
					          prefix + "/" + current_emote), // Path check if it's categorized
 | 
				
			||||||
                                          // into a folder
 | 
					                                          // into a folder
 | 
				
			||||||
      ao_app->get_image_suffix(ao_app->get_character_path(
 | 
					      ao_app->get_character_path(
 | 
				
			||||||
          p_charname,
 | 
					          p_charname,
 | 
				
			||||||
          current_emote)), // Just use the non-prefixed image, animated or not
 | 
					          current_emote), // Just use the non-prefixed image, animated or not
 | 
				
			||||||
      ao_app->get_image_suffix(
 | 
					      current_emote, // The path by itself after the above fail
 | 
				
			||||||
          ao_app->get_theme_path("placeholder")), // Theme placeholder path
 | 
					      ao_app->get_theme_path("placeholder"), // Theme placeholder path
 | 
				
			||||||
      ao_app->get_image_suffix(ao_app->get_theme_path(
 | 
					      ao_app->get_theme_path(
 | 
				
			||||||
          "placeholder", ao_app->default_theme))}; // Default theme placeholder path
 | 
					          "placeholder", ao_app->default_theme)}; // Default theme placeholder path
 | 
				
			||||||
  start_playback(find_image(pathlist));
 | 
					  start_playback(ao_app->get_image_path(pathlist));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SplashLayer::load_image(QString p_filename, QString p_charname,
 | 
					void SplashLayer::load_image(QString p_filename, QString p_charname,
 | 
				
			||||||
 | 
				
			|||||||
@ -21,10 +21,6 @@ void Courtroom::construct_char_select()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  ui_char_buttons = new QWidget(ui_char_select_background);
 | 
					  ui_char_buttons = new QWidget(ui_char_select_background);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_selector = new AOImage(ui_char_select_background, ao_app);
 | 
					 | 
				
			||||||
  ui_selector->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
					 | 
				
			||||||
  ui_selector->resize(62, 62);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ui_back_to_lobby = new AOButton(ui_char_select_background, ao_app);
 | 
					  ui_back_to_lobby = new AOButton(ui_char_select_background, ao_app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_char_password = new QLineEdit(ui_char_select_background);
 | 
					  ui_char_password = new QLineEdit(ui_char_select_background);
 | 
				
			||||||
 | 
				
			|||||||
@ -46,7 +46,9 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
 | 
				
			|||||||
  ui_vp_background = new BackgroundLayer(ui_viewport, ao_app);
 | 
					  ui_vp_background = new BackgroundLayer(ui_viewport, ao_app);
 | 
				
			||||||
  ui_vp_speedlines = new SplashLayer(ui_viewport, ao_app);
 | 
					  ui_vp_speedlines = new SplashLayer(ui_viewport, ao_app);
 | 
				
			||||||
  ui_vp_player_char = new CharLayer(ui_viewport, ao_app);
 | 
					  ui_vp_player_char = new CharLayer(ui_viewport, ao_app);
 | 
				
			||||||
 | 
					  ui_vp_player_char->masked = false;
 | 
				
			||||||
  ui_vp_sideplayer_char = new CharLayer(ui_viewport, ao_app);
 | 
					  ui_vp_sideplayer_char = new CharLayer(ui_viewport, ao_app);
 | 
				
			||||||
 | 
					  ui_vp_sideplayer_char->masked = false;
 | 
				
			||||||
  ui_vp_sideplayer_char->hide();
 | 
					  ui_vp_sideplayer_char->hide();
 | 
				
			||||||
  ui_vp_desk = new BackgroundLayer(ui_viewport, ao_app);
 | 
					  ui_vp_desk = new BackgroundLayer(ui_viewport, ao_app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -976,9 +978,6 @@ void Courtroom::set_widgets()
 | 
				
			|||||||
  set_size_and_pos(ui_sfx_slider, "sfx_slider");
 | 
					  set_size_and_pos(ui_sfx_slider, "sfx_slider");
 | 
				
			||||||
  set_size_and_pos(ui_blip_slider, "blip_slider");
 | 
					  set_size_and_pos(ui_blip_slider, "blip_slider");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_selector->set_image("char_selector");
 | 
					 | 
				
			||||||
  ui_selector->hide();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  set_size_and_pos(ui_back_to_lobby, "back_to_lobby");
 | 
					  set_size_and_pos(ui_back_to_lobby, "back_to_lobby");
 | 
				
			||||||
  ui_back_to_lobby->setText(tr("Back to Lobby"));
 | 
					  ui_back_to_lobby->setText(tr("Back to Lobby"));
 | 
				
			||||||
  ui_back_to_lobby->setToolTip(tr("Return back to the server list."));
 | 
					  ui_back_to_lobby->setToolTip(tr("Return back to the server list."));
 | 
				
			||||||
@ -1645,6 +1644,11 @@ void Courtroom::append_server_chatmessage(QString p_name, QString p_message,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_server_chatlog->append_chatmessage(p_name, p_message, color);
 | 
					  ui_server_chatlog->append_chatmessage(p_name, p_message, color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (ao_app->get_auto_logging_enabled() && !ao_app->log_filename.isEmpty()) {
 | 
				
			||||||
 | 
					    QString full = "[OOC][" + QDateTime::currentDateTime().toUTC().toString() + "] " + p_name + ": " + p_message;
 | 
				
			||||||
 | 
					    ao_app->append_to_file(full, ao_app->log_filename, true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Courtroom::on_authentication_state_received(int p_state)
 | 
					void Courtroom::on_authentication_state_received(int p_state)
 | 
				
			||||||
@ -1667,7 +1671,7 @@ void Courtroom::on_chat_return_pressed()
 | 
				
			|||||||
  if (is_muted)
 | 
					  if (is_muted)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((anim_state < 3 || text_state < 2) && objection_state == 0)
 | 
					  if (text_state < 2 && objection_state == 0)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ui_ic_chat_message->blockSignals(true);
 | 
					  ui_ic_chat_message->blockSignals(true);
 | 
				
			||||||
@ -1980,7 +1984,7 @@ void Courtroom::chatmessage_enqueue(QStringList p_contents)
 | 
				
			|||||||
  if (SHOWNAME < p_contents.size())
 | 
					  if (SHOWNAME < p_contents.size())
 | 
				
			||||||
    showname = p_contents[SHOWNAME];
 | 
					    showname = p_contents[SHOWNAME];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  log_chatmessage(p_contents[MESSAGE], f_char_id, showname, p_contents[TEXT_COLOR].toInt(), log_mode);
 | 
					  log_chatmessage(p_contents[MESSAGE], f_char_id, showname, p_contents[CHAR_NAME], p_contents[OBJECTION_MOD], p_contents[EVIDENCE_ID].toInt(), p_contents[TEXT_COLOR].toInt(), log_mode);
 | 
				
			||||||
  // Send this boi into the queue
 | 
					  // Send this boi into the queue
 | 
				
			||||||
  chatmessage_queue.enqueue(p_contents);
 | 
					  chatmessage_queue.enqueue(p_contents);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2014,7 +2018,7 @@ void Courtroom::skip_chatmessage_queue()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  while (!chatmessage_queue.isEmpty()) {
 | 
					  while (!chatmessage_queue.isEmpty()) {
 | 
				
			||||||
    QStringList p_contents = chatmessage_queue.dequeue();
 | 
					    QStringList p_contents = chatmessage_queue.dequeue();
 | 
				
			||||||
    log_chatmessage(p_contents[MESSAGE], p_contents[CHAR_ID].toInt(), p_contents[SHOWNAME], p_contents[TEXT_COLOR].toInt(), DISPLAY_ONLY);
 | 
					    log_chatmessage(p_contents[MESSAGE], p_contents[CHAR_ID].toInt(), p_contents[SHOWNAME], p_contents[CHAR_NAME], p_contents[OBJECTION_MOD], p_contents[EVIDENCE_ID].toInt(), p_contents[TEXT_COLOR].toInt(), DISPLAY_ONLY);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2037,7 +2041,7 @@ void Courtroom::unpack_chatmessage(QStringList p_contents)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (!ao_app->is_desyncrhonized_logs_enabled()) {
 | 
					  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.
 | 
					    // 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);
 | 
					    log_chatmessage(m_chatmessage[MESSAGE], m_chatmessage[CHAR_ID].toInt(), m_chatmessage[SHOWNAME], m_chatmessage[CHAR_NAME], m_chatmessage[OBJECTION_MOD], m_chatmessage[EVIDENCE_ID].toInt(), m_chatmessage[TEXT_COLOR].toInt(), DISPLAY_ONLY);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Process the callwords for this message
 | 
					  // Process the callwords for this message
 | 
				
			||||||
@ -2056,18 +2060,13 @@ void Courtroom::unpack_chatmessage(QStringList p_contents)
 | 
				
			|||||||
    handle_ic_message();
 | 
					    handle_ic_message();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_showname, int f_color, LogMode f_log_mode)
 | 
					void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_showname, QString f_char, QString f_objection_mod, int f_evi_id, int f_color, LogMode f_log_mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // Display name will use the showname
 | 
					  // Display name will use the showname
 | 
				
			||||||
  QString f_displayname = f_showname;
 | 
					  QString f_displayname = f_showname;
 | 
				
			||||||
  if (f_char_id != -1) {
 | 
					  if (f_char_id != -1) {
 | 
				
			||||||
    // Grab the char.ini showname
 | 
					    // Grab the char.ini showname
 | 
				
			||||||
    f_showname = ao_app->get_showname(char_list.at(f_char_id).name);
 | 
					    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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // If display name is just whitespace, use the char.ini showname.
 | 
					  // If display name is just whitespace, use the char.ini showname.
 | 
				
			||||||
  if (f_displayname.trimmed().isEmpty())
 | 
					  if (f_displayname.trimmed().isEmpty())
 | 
				
			||||||
@ -2077,16 +2076,15 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show
 | 
				
			|||||||
    // Check if a custom objection is in use
 | 
					    // Check if a custom objection is in use
 | 
				
			||||||
    int objection_mod = 0;
 | 
					    int objection_mod = 0;
 | 
				
			||||||
    QString custom_objection = "";
 | 
					    QString custom_objection = "";
 | 
				
			||||||
    if (m_chatmessage[OBJECTION_MOD].contains("4&")) {
 | 
					    if (f_objection_mod.contains("4&")) {
 | 
				
			||||||
      objection_mod = 4;
 | 
					      objection_mod = 4;
 | 
				
			||||||
      custom_objection = m_chatmessage[OBJECTION_MOD].split(
 | 
					      custom_objection = f_objection_mod.split(
 | 
				
			||||||
          "4&")[1]; // takes the name of custom objection.
 | 
					          "4&")[1]; // takes the name of custom objection.
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      objection_mod = m_chatmessage[OBJECTION_MOD].toInt();
 | 
					      objection_mod = f_objection_mod.toInt();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString f_char = m_chatmessage[CHAR_NAME];
 | 
					 | 
				
			||||||
    QString f_custom_theme = ao_app->get_chat(f_char);
 | 
					    QString f_custom_theme = ao_app->get_chat(f_char);
 | 
				
			||||||
    if (objection_mod <= 4 && objection_mod >= 1) {
 | 
					    if (objection_mod <= 4 && objection_mod >= 1) {
 | 
				
			||||||
      QString shout_message;
 | 
					      QString shout_message;
 | 
				
			||||||
@ -2133,8 +2131,6 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 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 the evidence ID is in the valid range
 | 
				
			||||||
    if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) {
 | 
					    if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) {
 | 
				
			||||||
      // Obtain the evidence name
 | 
					      // Obtain the evidence name
 | 
				
			||||||
@ -2170,6 +2166,8 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show
 | 
				
			|||||||
      append_ic_text(f_message, f_displayname, "",f_color);
 | 
					      append_ic_text(f_message, f_displayname, "",f_color);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  if (!ui_showname_enable->isChecked())
 | 
				
			||||||
 | 
					      regenerate_ic_chatlog();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Courtroom::handle_objection()
 | 
					bool Courtroom::handle_objection()
 | 
				
			||||||
@ -2186,8 +2184,6 @@ bool Courtroom::handle_objection()
 | 
				
			|||||||
    objection_mod = m_chatmessage[OBJECTION_MOD].toInt();
 | 
					    objection_mod = m_chatmessage[OBJECTION_MOD].toInt();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // if an objection is used
 | 
					  // if an objection is used
 | 
				
			||||||
  if (objection_mod <= 4 && objection_mod >= 1) {
 | 
					  if (objection_mod <= 4 && objection_mod >= 1) {
 | 
				
			||||||
    ui_vp_objection->set_static_duration(shout_static_time);
 | 
					    ui_vp_objection->set_static_duration(shout_static_time);
 | 
				
			||||||
@ -2231,8 +2227,10 @@ bool Courtroom::handle_objection()
 | 
				
			|||||||
        filename, m_chatmessage[CHAR_NAME],
 | 
					        filename, m_chatmessage[CHAR_NAME],
 | 
				
			||||||
        ao_app->get_chat(m_chatmessage[CHAR_NAME]));
 | 
					        ao_app->get_chat(m_chatmessage[CHAR_NAME]));
 | 
				
			||||||
    sfx_player->clear(); // Objection played! Cut all sfx.
 | 
					    sfx_player->clear(); // Objection played! Cut all sfx.
 | 
				
			||||||
 | 
					    ui_vp_player_char->set_play_once(true);
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  if (m_chatmessage[EMOTE] != "")
 | 
				
			||||||
    display_character();
 | 
					    display_character();
 | 
				
			||||||
  return false;
 | 
					  return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -2391,22 +2389,31 @@ void Courtroom::handle_ic_message()
 | 
				
			|||||||
  // Update the chatbox information
 | 
					  // Update the chatbox information
 | 
				
			||||||
  initialize_chatbox();
 | 
					  initialize_chatbox();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // 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();
 | 
					  int emote_mod = m_chatmessage[EMOTE_MOD].toInt();
 | 
				
			||||||
  if (emote_mod != 5 && emote_mod != 6) {
 | 
					  bool immediate = m_chatmessage[IMMEDIATE].toInt() == 1;
 | 
				
			||||||
    // Display the pair character
 | 
					  if (m_chatmessage[EMOTE] != "") {
 | 
				
			||||||
    display_pair_character(m_chatmessage[OTHER_CHARID], m_chatmessage[OTHER_OFFSET]);
 | 
					    // Display our own character
 | 
				
			||||||
  }
 | 
					    display_character();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Parse the emote_mod part of the chat message
 | 
					    // Reset the pair character
 | 
				
			||||||
  handle_emote_mod(m_chatmessage[EMOTE_MOD].toInt(), m_chatmessage[IMMEDIATE].toInt() == 1);
 | 
					    ui_vp_sideplayer_char->stop();
 | 
				
			||||||
 | 
					    ui_vp_sideplayer_char->move(0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If the emote_mod is not zooming
 | 
				
			||||||
 | 
					    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(emote_mod, immediate);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    start_chat_ticking();
 | 
				
			||||||
 | 
					    if (emote_mod == 1 || emote_mod == 2 || emote_mod == 6 || immediate)
 | 
				
			||||||
 | 
					      play_sfx();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // if we have instant objections disabled, and queue is not empty, check if next message after this is an objection.
 | 
					  // 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)
 | 
					  if (!ao_app->is_instant_objection_enabled() && chatmessage_queue.size() > 0)
 | 
				
			||||||
@ -2523,7 +2530,6 @@ void Courtroom::initialize_chatbox()
 | 
				
			|||||||
  if (f_charid >= 0 && f_charid < char_list.size() &&
 | 
					  if (f_charid >= 0 && f_charid < char_list.size() &&
 | 
				
			||||||
      (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked())) {
 | 
					      (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked())) {
 | 
				
			||||||
    QString real_name = char_list.at(f_charid).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);
 | 
					    QString f_showname = ao_app->get_showname(real_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ui_vp_showname->setText(f_showname);
 | 
					    ui_vp_showname->setText(f_showname);
 | 
				
			||||||
@ -2671,8 +2677,6 @@ void Courtroom::display_evidence_image()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Courtroom::handle_ic_speaking()
 | 
					void Courtroom::handle_ic_speaking()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // Display the evidence
 | 
					 | 
				
			||||||
  display_evidence_image();
 | 
					 | 
				
			||||||
  QString side = m_chatmessage[SIDE];
 | 
					  QString side = m_chatmessage[SIDE];
 | 
				
			||||||
  int emote_mod = m_chatmessage[EMOTE_MOD].toInt();
 | 
					  int emote_mod = m_chatmessage[EMOTE_MOD].toInt();
 | 
				
			||||||
  // emote_mod 5 is zoom and emote_mod 6 is zoom w/ preanim.
 | 
					  // emote_mod 5 is zoom and emote_mod 6 is zoom w/ preanim.
 | 
				
			||||||
@ -3182,6 +3186,9 @@ void Courtroom::play_preanim(bool immediate)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Courtroom::preanim_done()
 | 
					void Courtroom::preanim_done()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  // Currently, someone's talking over us mid-preanim...
 | 
				
			||||||
 | 
					  if (anim_state != 1 && anim_state != 4)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
  anim_state = 1;
 | 
					  anim_state = 1;
 | 
				
			||||||
  switch(m_chatmessage[DESK_MOD].toInt()) {
 | 
					  switch(m_chatmessage[DESK_MOD].toInt()) {
 | 
				
			||||||
    case 4:
 | 
					    case 4:
 | 
				
			||||||
@ -3211,6 +3218,9 @@ void Courtroom::start_chat_ticking()
 | 
				
			|||||||
  if (text_state != 0)
 | 
					  if (text_state != 0)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Display the evidence
 | 
				
			||||||
 | 
					  display_evidence_image();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (m_chatmessage[EFFECTS] != "") {
 | 
					  if (m_chatmessage[EFFECTS] != "") {
 | 
				
			||||||
    QStringList fx_list = m_chatmessage[EFFECTS].split("|");
 | 
					    QStringList fx_list = m_chatmessage[EFFECTS].split("|");
 | 
				
			||||||
    QString fx = fx_list[0];
 | 
					    QString fx = fx_list[0];
 | 
				
			||||||
@ -3242,6 +3252,10 @@ void Courtroom::start_chat_ticking()
 | 
				
			|||||||
      ui_vp_chatbox->show();
 | 
					      ui_vp_chatbox->show();
 | 
				
			||||||
      ui_vp_message->show();
 | 
					      ui_vp_message->show();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      ui_vp_chatbox->hide();
 | 
				
			||||||
 | 
					      ui_vp_message->hide();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    // If we're not already waiting on the next message, start the timer. We could be overriden if there's an objection planned.
 | 
					    // 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();
 | 
					    int delay = ao_app->stay_time();
 | 
				
			||||||
    if (delay > 0 && !text_queue_timer->isActive())
 | 
					    if (delay > 0 && !text_queue_timer->isActive())
 | 
				
			||||||
@ -3299,26 +3313,31 @@ void Courtroom::chat_tick()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (tick_pos >= f_message.size()) {
 | 
					  if (tick_pos >= f_message.size()) {
 | 
				
			||||||
    text_state = 2;
 | 
					    text_state = 2;
 | 
				
			||||||
    if (anim_state < 3) {
 | 
					    // Check if we're a narrator msg
 | 
				
			||||||
      QStringList c_paths = {
 | 
					    if (m_chatmessage[EMOTE] != "") {
 | 
				
			||||||
        ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)" + m_chatmessage[EMOTE])),
 | 
					      if (anim_state < 3) {
 | 
				
			||||||
        ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)/" + m_chatmessage[EMOTE]))
 | 
					        QStringList c_paths = {
 | 
				
			||||||
        };
 | 
					          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
 | 
					          ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)/" + m_chatmessage[EMOTE]))
 | 
				
			||||||
      if (file_exists(ui_vp_player_char->find_image(c_paths)) &&(!c_played)) {
 | 
					          };
 | 
				
			||||||
        anim_state = 5;
 | 
					        // if there is a (c) animation for this emote and we haven't played it already
 | 
				
			||||||
        ui_vp_player_char->set_play_once(true);
 | 
					        if (file_exists(ui_vp_player_char->find_image(c_paths)) &&(!c_played)) {
 | 
				
			||||||
        filename = "(c)" + m_chatmessage[EMOTE];
 | 
					          anim_state = 5;
 | 
				
			||||||
        c_played = true;
 | 
					          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);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      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);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else // We're a narrator msg
 | 
				
			||||||
 | 
					      anim_state = 3;
 | 
				
			||||||
    QString f_char;
 | 
					    QString f_char;
 | 
				
			||||||
    QString f_custom_theme;
 | 
					    QString f_custom_theme;
 | 
				
			||||||
    if (ao_app->is_customchat_enabled()) {
 | 
					    if (ao_app->is_customchat_enabled()) {
 | 
				
			||||||
@ -3361,21 +3380,8 @@ void Courtroom::chat_tick()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Alignment characters
 | 
					  // Alignment characters
 | 
				
			||||||
  if (tick_pos < 2) {
 | 
					  if (tick_pos < 2) {
 | 
				
			||||||
    if (f_rest.startsWith("~~")) {
 | 
					    if (f_rest.startsWith("~~") || f_rest.startsWith("~>") || f_rest.startsWith("<>"))
 | 
				
			||||||
      tick_pos = f_rest.indexOf("~~");
 | 
					 | 
				
			||||||
      f_rest.remove(tick_pos, 2);
 | 
					 | 
				
			||||||
      tick_pos += 2;
 | 
					      tick_pos += 2;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (f_rest.startsWith("~>")) {
 | 
					 | 
				
			||||||
      tick_pos = f_rest.indexOf("~>");
 | 
					 | 
				
			||||||
      f_rest.remove(tick_pos, 2);
 | 
					 | 
				
			||||||
      tick_pos += 2;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (f_rest.startsWith("<>")) {
 | 
					 | 
				
			||||||
      tick_pos = f_rest.indexOf("<>");
 | 
					 | 
				
			||||||
      f_rest.remove(tick_pos, 2);
 | 
					 | 
				
			||||||
      tick_pos += 2;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  f_rest.remove(0, tick_pos);
 | 
					  f_rest.remove(0, tick_pos);
 | 
				
			||||||
  QTextBoundaryFinder tbf(QTextBoundaryFinder::Grapheme, f_rest);
 | 
					  QTextBoundaryFinder tbf(QTextBoundaryFinder::Grapheme, f_rest);
 | 
				
			||||||
@ -3519,28 +3525,30 @@ void Courtroom::chat_tick()
 | 
				
			|||||||
      msg_delay = qMin(max_delay, msg_delay * punctuation_modifier);
 | 
					      msg_delay = qMin(max_delay, msg_delay * punctuation_modifier);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If this color is talking
 | 
					    if (m_chatmessage[EMOTE] != "") {
 | 
				
			||||||
    if (color_is_talking && anim_state != 2 &&
 | 
					      // If this color is talking
 | 
				
			||||||
        anim_state <
 | 
					      if (color_is_talking && anim_state != 2 &&
 | 
				
			||||||
            4) // Set it to talking as we're not on that already (though we have
 | 
					          anim_state <
 | 
				
			||||||
               // to avoid interrupting a non-interrupted preanim)
 | 
					          4) // Set it to talking as we're not on that already (though we have
 | 
				
			||||||
    {
 | 
					        // to avoid interrupting a non-interrupted preanim)
 | 
				
			||||||
      ui_vp_player_char->stop();
 | 
					      {
 | 
				
			||||||
      ui_vp_player_char->set_play_once(false);
 | 
					        ui_vp_player_char->stop();
 | 
				
			||||||
      filename = "(b)" + m_chatmessage[EMOTE];
 | 
					        ui_vp_player_char->set_play_once(false);
 | 
				
			||||||
      ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
 | 
					        filename = "(b)" + m_chatmessage[EMOTE];
 | 
				
			||||||
                                    false);
 | 
					        ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
 | 
				
			||||||
      anim_state = 2;
 | 
					                                      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
 | 
					      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->set_play_once(false);
 | 
					        ui_vp_player_char->stop();
 | 
				
			||||||
      filename = "(a)" + m_chatmessage[EMOTE];
 | 
					        ui_vp_player_char->set_play_once(false);
 | 
				
			||||||
      ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
 | 
					        filename = "(a)" + m_chatmessage[EMOTE];
 | 
				
			||||||
                                    false);
 | 
					        ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
 | 
				
			||||||
      anim_state = 3;
 | 
					                                      false);
 | 
				
			||||||
 | 
					        anim_state = 3;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // Continue ticking
 | 
					    // Continue ticking
 | 
				
			||||||
    chat_tick_timer->start(msg_delay);
 | 
					    chat_tick_timer->start(msg_delay);
 | 
				
			||||||
@ -3891,14 +3899,8 @@ void Courtroom::case_called(QString msg, bool def, bool pro, bool jud, bool jur,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  if (ui_casing->isChecked()) {
 | 
					  if (ui_casing->isChecked()) {
 | 
				
			||||||
    ui_server_chatlog->append(msg);
 | 
					    ui_server_chatlog->append(msg);
 | 
				
			||||||
    if ((ao_app->get_casing_defence_enabled() && def) ||
 | 
					    modcall_player->play(ao_app->get_court_sfx("case_call"));
 | 
				
			||||||
        (ao_app->get_casing_prosecution_enabled() && pro) ||
 | 
					    ao_app->alert(this);
 | 
				
			||||||
        (ao_app->get_casing_judge_enabled() && jud) ||
 | 
					 | 
				
			||||||
        (ao_app->get_casing_juror_enabled() && jur) ||
 | 
					 | 
				
			||||||
        (ao_app->get_casing_steno_enabled() && steno)) {
 | 
					 | 
				
			||||||
      modcall_player->play(ao_app->get_court_sfx("case_call"));
 | 
					 | 
				
			||||||
      ao_app->alert(this);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -5260,8 +5262,6 @@ void Courtroom::on_reload_theme_clicked()
 | 
				
			|||||||
  enter_courtroom();
 | 
					  enter_courtroom();
 | 
				
			||||||
  gen_char_rgb_list(ao_app->get_chat(current_char));
 | 
					  gen_char_rgb_list(ao_app->get_chat(current_char));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  anim_state = 4;
 | 
					 | 
				
			||||||
  text_state = 3;
 | 
					 | 
				
			||||||
  objection_custom = "";
 | 
					  objection_custom = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // to update status on the background
 | 
					  // to update status on the background
 | 
				
			||||||
 | 
				
			|||||||
@ -275,6 +275,56 @@ void DemoServer::load_demo(QString filename)
 | 
				
			|||||||
        demo_data.enqueue(line);
 | 
					        demo_data.enqueue(line);
 | 
				
			||||||
        line = demo_stream.readLine();
 | 
					        line = demo_stream.readLine();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    demo_file.flush();
 | 
				
			||||||
 | 
					    demo_file.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // No-shenanigans 2.9.0 demo file with the dreaded demo desync bug detected https://github.com/AttorneyOnline/AO2-Client/pull/496
 | 
				
			||||||
 | 
					    // If we don't start with the SC packet this means user-edited weirdo shenanigans. Don't screw around with those.
 | 
				
			||||||
 | 
					    if (demo_data.head().startsWith("SC#") && demo_data.last().startsWith("wait#")) {
 | 
				
			||||||
 | 
					      qDebug() << "Loaded a broken pre-2.9.1 demo file, with the wait desync issue!";
 | 
				
			||||||
 | 
					      QMessageBox *msgBox = new QMessageBox;
 | 
				
			||||||
 | 
					      msgBox->setAttribute(Qt::WA_DeleteOnClose);
 | 
				
			||||||
 | 
					      msgBox->setTextFormat(Qt::RichText);
 | 
				
			||||||
 | 
					      msgBox->setText("This appears to be a <b>broken</b> pre-2.9.1 demo file with the <a href=https://github.com/AttorneyOnline/AO2-Client/pull/496>wait desync issue</a>!<br>Do you want to correct this file? <i>If you refuse, this demo will be desynchronized!</i>");
 | 
				
			||||||
 | 
					      msgBox->setWindowTitle("Pre-2.9.1 demo detected!");
 | 
				
			||||||
 | 
					      msgBox->setStandardButtons(QMessageBox::NoButton);
 | 
				
			||||||
 | 
					      QTimer::singleShot(2000, msgBox, std::bind(&QMessageBox::setStandardButtons,msgBox,QMessageBox::Yes|QMessageBox::No));
 | 
				
			||||||
 | 
					      int ret = msgBox->exec();
 | 
				
			||||||
 | 
					      QQueue <QString> p_demo_data;
 | 
				
			||||||
 | 
					      switch (ret) {
 | 
				
			||||||
 | 
					        case QMessageBox::Yes:
 | 
				
			||||||
 | 
					          qDebug() << "Making a backup of the broken demo...";
 | 
				
			||||||
 | 
					          QFile::copy(filename, filename + ".backup");
 | 
				
			||||||
 | 
					          while (!demo_data.isEmpty()) {
 | 
				
			||||||
 | 
					            QString current_packet = demo_data.dequeue();
 | 
				
			||||||
 | 
					            // TODO: faster way of doing this, maybe with QtConcurrent's MapReduce methods?
 | 
				
			||||||
 | 
					            if (!current_packet.startsWith("SC#") && current_packet.startsWith("wait#")) {
 | 
				
			||||||
 | 
					              p_demo_data.insert(qMax(1, p_demo_data.size()-1), current_packet);
 | 
				
			||||||
 | 
					              continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            p_demo_data.enqueue(current_packet);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (demo_file.open(QIODevice::WriteOnly | QIODevice::Text |
 | 
				
			||||||
 | 
					                         QIODevice::Truncate)) {
 | 
				
			||||||
 | 
					            QTextStream out(&demo_file);
 | 
				
			||||||
 | 
					            out.setCodec("UTF-8");
 | 
				
			||||||
 | 
					            out << p_demo_data.dequeue();
 | 
				
			||||||
 | 
					            for (QString line : p_demo_data) {
 | 
				
			||||||
 | 
					              out << "\n" << line;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            demo_file.flush();
 | 
				
			||||||
 | 
					            demo_file.close();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          load_demo(filename);
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case QMessageBox::No:
 | 
				
			||||||
 | 
					          // No was clicked
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					          // should never be reached
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DemoServer::reset_all_timers()
 | 
					void DemoServer::reset_all_timers()
 | 
				
			||||||
@ -301,22 +351,26 @@ void DemoServer::playback()
 | 
				
			|||||||
    if (current_packet.startsWith("MS#"))
 | 
					    if (current_packet.startsWith("MS#"))
 | 
				
			||||||
      elapsed_time = 0;
 | 
					      elapsed_time = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (!current_packet.startsWith("wait") && !demo_data.isEmpty()) {
 | 
					    while (!current_packet.startsWith("wait#")) {
 | 
				
			||||||
        client_sock->write(current_packet.toUtf8());
 | 
					        client_sock->write(current_packet.toUtf8());
 | 
				
			||||||
 | 
					        if (demo_data.isEmpty())
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
        current_packet = demo_data.dequeue();
 | 
					        current_packet = demo_data.dequeue();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!demo_data.isEmpty()) {
 | 
					    if (!demo_data.isEmpty()) {
 | 
				
			||||||
        AOPacket wait_packet = AOPacket(current_packet);
 | 
					        AOPacket wait_packet = AOPacket(current_packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int duration = wait_packet.get_contents().at(0).toInt();
 | 
					        int duration = wait_packet.get_contents().at(0).toInt();
 | 
				
			||||||
        if (max_wait != -1 && duration + elapsed_time > max_wait) {
 | 
					        if (max_wait != -1) {
 | 
				
			||||||
          duration = qMax(0, max_wait - elapsed_time);
 | 
					          if (duration + elapsed_time > max_wait) {
 | 
				
			||||||
          // Skip the difference on the timers
 | 
					            duration = qMax(0, max_wait - elapsed_time);
 | 
				
			||||||
          emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration);
 | 
					            // Skip the difference on the timers
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (timer->interval() != 0 && duration + elapsed_time > timer->interval()) {
 | 
					 | 
				
			||||||
            duration = qMax(0, timer->interval() - elapsed_time);
 | 
					 | 
				
			||||||
            emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration);
 | 
					            emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          else if (timer->interval() != 0 && duration + elapsed_time > timer->interval()) {
 | 
				
			||||||
 | 
					              duration = qMax(0, timer->interval() - elapsed_time);
 | 
				
			||||||
 | 
					              emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elapsed_time += duration;
 | 
					        elapsed_time += duration;
 | 
				
			||||||
        timer->start(duration);
 | 
					        timer->start(duration);
 | 
				
			||||||
 | 
				
			|||||||
@ -308,7 +308,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
				
			|||||||
      this->log_filename = QDateTime::currentDateTime().toUTC().toString(
 | 
					      this->log_filename = QDateTime::currentDateTime().toUTC().toString(
 | 
				
			||||||
          "'logs/" + server_name.remove(QRegExp("[\\\\/:*?\"<>|\']")) +
 | 
					          "'logs/" + server_name.remove(QRegExp("[\\\\/:*?\"<>|\']")) +
 | 
				
			||||||
          "/'yyyy-MM-dd hh-mm-ss t'.log'");
 | 
					          "/'yyyy-MM-dd hh-mm-ss t'.log'");
 | 
				
			||||||
      this->write_to_file("Joined server " + server_name + " on address " +
 | 
					      this->write_to_file("Joined server " + server_name + " hosted on address " +
 | 
				
			||||||
                              server_address + " on " +
 | 
					                              server_address + " on " +
 | 
				
			||||||
                              QDateTime::currentDateTime().toUTC().toString(),
 | 
					                              QDateTime::currentDateTime().toUTC().toString(),
 | 
				
			||||||
                          log_filename, true);
 | 
					                          log_filename, true);
 | 
				
			||||||
 | 
				
			|||||||
@ -105,7 +105,6 @@ QString AOApplication::get_evidence_path(QString p_file)
 | 
				
			|||||||
QStringList AOApplication::get_asset_paths(QString p_element, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc, QString p_character, QString p_placeholder)
 | 
					QStringList AOApplication::get_asset_paths(QString p_element, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc, QString p_character, QString p_placeholder)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QStringList pathlist;
 | 
					    QStringList pathlist;
 | 
				
			||||||
    pathlist += p_element; // The path by itself
 | 
					 | 
				
			||||||
    if (p_character != "")
 | 
					    if (p_character != "")
 | 
				
			||||||
      pathlist += get_character_path(p_character, p_element); // Character folder
 | 
					      pathlist += get_character_path(p_character, p_element); // Character folder
 | 
				
			||||||
    if (p_misc != "" && p_theme != "" && p_subtheme != "")
 | 
					    if (p_misc != "" && p_theme != "" && p_subtheme != "")
 | 
				
			||||||
@ -120,6 +119,7 @@ QStringList AOApplication::get_asset_paths(QString p_element, QString p_theme, Q
 | 
				
			|||||||
      pathlist += get_theme_path(p_element, p_theme); // Theme path
 | 
					      pathlist += get_theme_path(p_element, p_theme); // Theme path
 | 
				
			||||||
    if (p_default_theme != "")
 | 
					    if (p_default_theme != "")
 | 
				
			||||||
      pathlist += get_theme_path(p_element, p_default_theme); // Default theme path
 | 
					      pathlist += get_theme_path(p_element, p_default_theme); // Default theme path
 | 
				
			||||||
 | 
					    pathlist += p_element; // The path by itself
 | 
				
			||||||
    if (p_placeholder != "" && p_theme != "")
 | 
					    if (p_placeholder != "" && p_theme != "")
 | 
				
			||||||
      pathlist += get_theme_path(p_placeholder, p_theme); // Placeholder path
 | 
					      pathlist += get_theme_path(p_placeholder, p_theme); // Placeholder path
 | 
				
			||||||
    if (p_placeholder != "" && p_default_theme != "")
 | 
					    if (p_placeholder != "" && p_default_theme != "")
 | 
				
			||||||
@ -173,6 +173,7 @@ QString AOApplication::get_config_value(QString p_identifier, QString p_config,
 | 
				
			|||||||
        p = get_case_sensitive_path(p);
 | 
					        p = get_case_sensitive_path(p);
 | 
				
			||||||
        if (file_exists(p)) {
 | 
					        if (file_exists(p)) {
 | 
				
			||||||
            QSettings settings(p, QSettings::IniFormat);
 | 
					            QSettings settings(p, QSettings::IniFormat);
 | 
				
			||||||
 | 
					            settings.setIniCodec("UTF-8");
 | 
				
			||||||
            QVariant value = settings.value(p_identifier);
 | 
					            QVariant value = settings.value(p_identifier);
 | 
				
			||||||
            if (value.type() == QVariant::StringList) {
 | 
					            if (value.type() == QVariant::StringList) {
 | 
				
			||||||
//              qDebug() << "got" << p << "is a string list, returning" << value.toStringList().join(",");
 | 
					//              qDebug() << "got" << p << "is a string list, returning" << value.toStringList().join(",");
 | 
				
			||||||
 | 
				
			|||||||
@ -277,6 +277,7 @@ QString AOApplication::read_design_ini(QString p_identifier,
 | 
				
			|||||||
                                       QString p_design_path)
 | 
					                                       QString p_design_path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  QSettings settings(p_design_path, QSettings::IniFormat);
 | 
					  QSettings settings(p_design_path, QSettings::IniFormat);
 | 
				
			||||||
 | 
					  settings.setIniCodec("UTF-8");
 | 
				
			||||||
  QVariant value = settings.value(p_identifier);
 | 
					  QVariant value = settings.value(p_identifier);
 | 
				
			||||||
  if (value.type() == QVariant::StringList) {
 | 
					  if (value.type() == QVariant::StringList) {
 | 
				
			||||||
    return value.toStringList().join(",");
 | 
					    return value.toStringList().join(",");
 | 
				
			||||||
@ -435,7 +436,7 @@ QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat)
 | 
				
			|||||||
  // New Chadly method
 | 
					  // New Chadly method
 | 
				
			||||||
  QString value = get_config_value(p_identifier, "chat_config.ini", current_theme, get_subtheme(), default_theme, p_chat);
 | 
					  QString value = get_config_value(p_identifier, "chat_config.ini", current_theme, get_subtheme(), default_theme, p_chat);
 | 
				
			||||||
  if (!value.isEmpty())
 | 
					  if (!value.isEmpty())
 | 
				
			||||||
    return value.toLatin1();
 | 
					    return value.toUtf8();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Backwards ass compatibility
 | 
					  // Backwards ass compatibility
 | 
				
			||||||
  QStringList backwards_paths{get_theme_path("misc/" + p_chat + "/config.ini"),
 | 
					  QStringList backwards_paths{get_theme_path("misc/" + p_chat + "/config.ini"),
 | 
				
			||||||
@ -446,7 +447,7 @@ QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat)
 | 
				
			|||||||
  for (const QString &p : backwards_paths) {
 | 
					  for (const QString &p : backwards_paths) {
 | 
				
			||||||
    QString value = read_design_ini(p_identifier, p);
 | 
					    QString value = read_design_ini(p_identifier, p);
 | 
				
			||||||
    if (!value.isEmpty()) {
 | 
					    if (!value.isEmpty()) {
 | 
				
			||||||
      return value.toLatin1();
 | 
					      return value.toUtf8();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -521,6 +522,7 @@ QString AOApplication::read_char_ini(QString p_char, QString p_search_line,
 | 
				
			|||||||
  QSettings settings(get_character_path(p_char, "char.ini"),
 | 
					  QSettings settings(get_character_path(p_char, "char.ini"),
 | 
				
			||||||
                     QSettings::IniFormat);
 | 
					                     QSettings::IniFormat);
 | 
				
			||||||
  settings.beginGroup(target_tag);
 | 
					  settings.beginGroup(target_tag);
 | 
				
			||||||
 | 
					  settings.setIniCodec("UTF-8");
 | 
				
			||||||
  QString value = settings.value(p_search_line).value<QString>();
 | 
					  QString value = settings.value(p_search_line).value<QString>();
 | 
				
			||||||
  settings.endGroup();
 | 
					  settings.endGroup();
 | 
				
			||||||
  return value;
 | 
					  return value;
 | 
				
			||||||
@ -541,6 +543,7 @@ QStringList AOApplication::read_ini_tags(QString p_path, QString target_tag)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  QStringList r_values;
 | 
					  QStringList r_values;
 | 
				
			||||||
  QSettings settings(p_path, QSettings::IniFormat);
 | 
					  QSettings settings(p_path, QSettings::IniFormat);
 | 
				
			||||||
 | 
					  settings.setIniCodec("UTF-8");
 | 
				
			||||||
  if (!target_tag.isEmpty())
 | 
					  if (!target_tag.isEmpty())
 | 
				
			||||||
    settings.beginGroup(target_tag);
 | 
					    settings.beginGroup(target_tag);
 | 
				
			||||||
  QStringList keys = settings.allKeys();
 | 
					  QStringList keys = settings.allKeys();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user