Implement networking for frame-specific effects data sending/parsing if the server supports it

Reorganize charmovie.h a bit and make some functions private
Add a new helper function "read_char_ini_tag" which returns a qstringlist of all key=value strings associated with the tag
This commit is contained in:
Crystalwarrior 2019-09-15 20:02:24 +03:00
parent e94640b349
commit 661ec87646
5 changed files with 153 additions and 81 deletions

View File

@ -232,6 +232,9 @@ public:
//Returns the value of p_search_line within target_tag and terminator_tag
QString read_char_ini(QString p_char, QString p_search_line, QString target_tag);
//Returns a QStringList of all key=value definitions on a given tag.
QStringList read_char_ini_tag(QString p_char, QString target_tag);
//Returns the side of the p_char character from that characters ini file
QString get_char_side(QString p_char);

View File

@ -17,12 +17,6 @@ class AOCharMovie : public QLabel
public:
AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app);
//Set the movie's image to provided paths, preparing for playback.
void load_image(QString p_char, QString p_emote, QString emote_prefix);
//Start playback of the movie (if animated).
void play();
//Play a hat.gif - style preanimation
void play_pre(QString p_char, QString p_emote, int duration);
@ -32,15 +26,6 @@ public:
//Play an (a)normal.gif - style animation (not talking)
void play_idle(QString p_char, QString p_emote);
//Play a frame-specific effect, if there's any defined for that specific frame.
void play_frame_effect(int frame);
//Retreive a pixmap adjused for mirroring/aspect ratio shenanigans from a provided QImage
QPixmap get_pixmap(QImage image);
//Set the movie's frame to provided pixmap
void set_frame(QPixmap f_pixmap);
//Stop the movie, clearing the image
void stop();
@ -59,6 +44,8 @@ public:
//Return the frame delay adjusted for speed
int get_frame_delay(int delay);
QStringList network_strings;
private:
AOApplication *ao_app;
@ -75,6 +62,9 @@ private:
QString last_path;
QImageReader *m_reader = new QImageReader();
QString m_char;
QString m_emote;
QElapsedTimer actual_time;
const int time_mod = 60;
@ -90,6 +80,27 @@ private:
bool m_flipped = false;
bool play_once = true;
//Set the movie's image to provided paths, preparing for playback.
void load_image(QString p_char, QString p_emote, QString emote_prefix);
//Start playback of the movie (if animated).
void play();
//Play a frame-specific effect, if there's any defined for that specific frame.
void play_frame_effect(int frame);
//Retreive a pixmap adjused for mirroring/aspect ratio shenanigans from a provided QImage
QPixmap get_pixmap(QImage image);
//Set the movie's frame to provided pixmap
void set_frame(QPixmap f_pixmap);
//Initialize the frame-specific effects from the char.ini
void load_effects();
//Initialize the frame-specific effects from the provided network_strings, this is only initialized if network_strings has size more than 0.
void load_network_effects();
signals:
void done();
void shake();

View File

@ -64,39 +64,13 @@ void AOCharMovie::load_image(QString p_char, QString p_emote, QString emote_pref
movie_delays.append(f_delay);
}
movie_effects.resize(max_frames);
for (int e_frame = 0; e_frame < max_frames; ++e_frame)
{
#ifdef DEBUG_CHARMOVIE
qDebug() << p_char << p_emote << e_frame;
#endif
QString effect = ao_app->get_screenshake_frame(p_char, emote_prefix + p_emote, e_frame);
if (effect != "")
{
movie_effects[e_frame].append("shake");
#ifdef DEBUG_CHARMOVIE
qDebug() << e_frame << "shake";
#endif
}
m_char = p_char;
m_emote = emote_prefix + p_emote;
effect = ao_app->get_flash_frame(p_char, emote_prefix + p_emote, e_frame);
if (effect != "")
{
movie_effects[e_frame].append("flash");
#ifdef DEBUG_CHARMOVIE
qDebug() << e_frame << "flash";
#endif
}
effect = ao_app->get_sfx_frame(p_char, emote_prefix + p_emote, e_frame);
if (effect != "")
{
movie_effects[e_frame].append("sfx^"+effect);
#ifdef DEBUG_CHARMOVIE
qDebug() << e_frame << effect;
#endif
}
}
if (network_strings.size() > 0) //our FX overwritten by networked ones
this->load_network_effects();
else //Use default ini FX
this->load_effects();
#ifdef DEBUG_CHARMOVIE
qDebug() << max_frames << "Setting image to " << emote_path << "Time taken to process image:" << actual_time.elapsed();
@ -104,6 +78,77 @@ void AOCharMovie::load_image(QString p_char, QString p_emote, QString emote_pref
#endif
}
void AOCharMovie::load_effects()
{
movie_effects.clear();
movie_effects.resize(max_frames);
for (int e_frame = 0; e_frame < max_frames; ++e_frame)
{
QString effect = ao_app->get_screenshake_frame(m_char, m_emote, e_frame);
if (effect != "")
{
movie_effects[e_frame].append("shake");
}
effect = ao_app->get_flash_frame(m_char, m_emote, e_frame);
if (effect != "")
{
movie_effects[e_frame].append("flash");
}
effect = ao_app->get_sfx_frame(m_char, m_emote, e_frame);
if (effect != "")
{
movie_effects[e_frame].append("sfx^"+effect);
}
}
}
void AOCharMovie::load_network_effects()
{
movie_effects.clear();
movie_effects.resize(max_frames);
//Order is important!!!
QStringList effects_list = {"shake", "flash", "sfx^"};
//Determines which list is smaller - effects_list or network_strings - and uses it as basis for the loop.
//This way, incomplete network_strings would still be parsed, and excess/unaccounted for networked information is omitted.
int effects_size = qMin(effects_list.size(), network_strings.size());
for (int i = 0; i < effects_size; ++i)
{
QString netstring = network_strings.at(i);
QStringList emote_splits = netstring.split("^");
foreach (QString emote, emote_splits)
{
QStringList parsed = emote.split("|");
if (parsed.size() <= 0 || parsed.at(0) != m_emote)
continue;
foreach (QString frame_data, parsed)
{
QStringList frame_split = frame_data.split("=");
if (frame_split.size() <= 1) //We might still be hanging at the emote itself (entry 0).
continue;
int f_frame = frame_split.at(0).toInt();
if (f_frame >= max_frames)
{
qDebug() << "Warning: out of bounds" << effects_list[i] << "frame" << f_frame << "out of" << max_frames << "for" << m_char << m_emote;
continue;
}
QString f_data = frame_split.at(1);
if (f_data != "")
{
QString effect = effects_list[i];
if (effect == "sfx^") //Currently the only frame result that feeds us data, let's yank it in.
effect += f_data;
qDebug() << effect << f_data << "frame" << f_frame << "for" << m_char << m_emote;
movie_effects[f_frame].append(effect);
}
}
}
}
}
void AOCharMovie::play()
{
play_frame_effect(frame);

View File

@ -1267,41 +1267,31 @@ void Courtroom::on_chat_return_pressed()
packet_contents.append(QString::number(screenshake_state));
qDebug() << "Are we screen shaking this one? " << screenshake_state;
QString frame_screenshake = "";
QString frame_realization = "";
QString frame_sfx = "";
QString pre_emote = ao_app->get_pre_emote(current_char, current_emote);
QString emote = ao_app->get_emote(current_char, current_emote);
QStringList emotes_to_check = {pre_emote, "(b)" + emote, "(a)" + emote};
QStringList effects_to_check = {"_FrameScreenshake", "_FrameRealization", "_FrameSFX"};
QString preemote_sfx = ao_app->get_pre_emote(current_char, current_emote) + "^";
QString preemote_shake = ao_app->get_pre_emote(current_char, current_emote) + "^";
QString preemote_flash = ao_app->get_pre_emote(current_char, current_emote) + "^";
foreach (QString f_effect, effects_to_check)
{
QString packet;
foreach (QString f_emote, emotes_to_check)
{
packet += f_emote;
QString sfx_frames = ao_app->read_char_ini_tag(current_char, f_emote.append(f_effect)).join("|");
if (sfx_frames != "")
packet += "|" + sfx_frames;
packet += "^";
}
qDebug() << f_effect << "packet" << packet;
packet_contents.append(packet);
}
QString talkemote_sfx = "(b)" + ao_app->get_emote(current_char, current_emote) + "^";
QString talkemote_shake = "(b)" + ao_app->get_emote(current_char, current_emote) + "^";
QString talkemote_flash = "(b)" + ao_app->get_emote(current_char, current_emote) + "^";
//"roar|thing=thong^(b)roar^(a)roar^"
QString idleemote_sfx = "(a)" + ao_app->get_emote(current_char, current_emote) + "^";
QString idleemote_shake = "(a)" + ao_app->get_emote(current_char, current_emote) + "^";
QString idleemote_flash = "(a)" + ao_app->get_emote(current_char, current_emote) + "^";
frame_screenshake += preemote_shake;
frame_screenshake += talkemote_shake;
frame_screenshake += idleemote_shake;
frame_realization += preemote_flash;
frame_realization += talkemote_flash;
frame_realization += idleemote_flash;
frame_sfx += preemote_sfx;
frame_sfx += talkemote_sfx;
frame_sfx += idleemote_sfx;
qDebug() << "Final strings:";
qDebug() << frame_screenshake;
qDebug() << frame_realization;
qDebug() << frame_sfx;
packet_contents.append(frame_screenshake);
packet_contents.append(frame_realization);
packet_contents.append(frame_sfx);
// packet_contents.append(frame_screenshake);
// packet_contents.append(frame_realization);
// packet_contents.append(frame_sfx);
}
ao_app->send_server_packet(new AOPacket("MS", packet_contents));
}
@ -1447,6 +1437,15 @@ void Courtroom::handle_chatmessage_2()
//Clear all looping sfx to prevent obnoxiousness
sfx_player->loop_clear();
if (!m_chatmessage[FRAME_SFX].isEmpty())
{
//ORDER IS IMPORTANT!!
QStringList netstrings = {m_chatmessage[FRAME_SCREENSHAKE], m_chatmessage[FRAME_REALIZATION], m_chatmessage[FRAME_SFX]};
ui_vp_player_char->network_strings = netstrings;
}
else
ui_vp_player_char->network_strings.clear();
if (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked())
{
QString real_name = char_list.at(m_chatmessage[CHAR_ID].toInt()).name;
@ -1673,11 +1672,9 @@ void Courtroom::do_screenshake()
ui_vp_chatbox
};
int i = 0;
//I would prefer if this was its own "shake" function to be honest.
foreach (QWidget* ui_element, affected_list)
{
qDebug() << ++i;
QPropertyAnimation *screenshake_animation = new QPropertyAnimation(ui_element, "pos", this);
QPoint pos_default = QPoint(ui_element->x(), ui_element->y());

View File

@ -406,6 +406,22 @@ QString AOApplication::read_char_ini(QString p_char, QString p_search_line, QStr
return value;
}
//returns all the values of target_tag
QStringList AOApplication::read_char_ini_tag(QString p_char, QString target_tag)
{
QStringList r_values;
QSettings settings(get_character_path(p_char, "char.ini"), QSettings::IniFormat);
settings.beginGroup(target_tag);
QStringList keys = settings.allKeys();
foreach (QString key, keys)
{
QString value = settings.value(key).toString();
r_values << key + "=" + value;
}
settings.endGroup();
return r_values;
}
QString AOApplication::get_char_name(QString p_char)
{
QString f_result = read_char_ini(p_char, "name", "Options");