Consolidate AOScene, AOMovie, and AOCharMovie into one class, add support for (c) animations, implement emote continuity, add scaling overrides to all layer types, allow for stretch-to-fill images, allow for additional effect configuration (#302)
* Rewrite AOScene and remove the need for AOMovie and AOCharMovie by consolidation * Rename AOScene to AOLayer, apply suggestions to improve functionality * Implement suggested change to allocation * Switch from pointer to field, fix ui_vp_player_char not resetting play_once * Use the variable gif_name instead of the string "gif_name" Oops. * Total rewrite of AOLayer (again) * Add support for (c) animations, do some housekeeping * allow themes to override misc chatboxes * add support for pulling InterfaceLayer elements from theme/misc * mistakes were made * move all frame fx functionality to CharLayer subclass * virtual functions are cool mkay * remove evidence of my incompetence * allow themes to override font design inis under theme/misc * Proper support for theme/misc chatbox, fixes * Fix chatbox dimensions not updating and inline color causing missingnos * rename chat markdown to chat markup * add missing misc overrides * quick hotfix for chatblank and misc overrides * Fix oversight with backgrounds causing them to be culled * Same as last commit but for FG layer * amend comment to explain impossible shenanigans * Adjust ForegroundLayer to take charname rather than miscname, allow for checking in char folder * fix an incredibly embarrassing pathing bug * add scaling overrides for all layer types, parent orphaned viewport elements to the viewport * stupid fix because themes use "custom.png" as a button * switch to .append() * Revert "Merge branch 'aoscene_rewrite' of https://github.com/AttorneyOnline/AO2-Client into aoscene_rewrite" This reverts commit bdeb1bff7639d522031aab3c133a83b0e2a291df, reversing changes made to 125ee63b97a6f6c156e69525d88fddc625e7a978. * switch to .append() (again) * move function call to fix showname length calculation error * fix nonlooping character animations being broken Again * unparent elements from the viewport and do fancy masking arithmetic instead * use override keyword * move scaling override to char.ini, allow stretching, restructure effect property loading * fix some redundancy * unparent chat_arrow from chatbox to prevent accidental masking * at no point do we want a frozen gif to display * overhaul how wtce is handled * oops * also let sounds be pulled from theme miscs * i should probably compile before i push * actually make it work * don't check a default bg * readd 1x1 stretch thing * actually the 1x1 thing was a bad idea * Add missing parenthesis * Use load_image instead of play play is a nonexistent method now * Remote shout_message and usages because it does nothing * Remove multiple redefinitions * Add in missing brackets and indent to fix build I have know idea what this does but it brings fear * fix build error * fix chat arrow and remove duped code * remove more duped code and fix misc themes * only update chat_arrow when needed * consolidate log_chatmessage and display_log_chatmessage Co-authored-by: scatterflower <marisaposs@gameboyprinter.moe> Co-authored-by: Skye Deving <76892045+skyedeving@users.noreply.github.com> Co-authored-by: oldmud0 <oldmud0@users.noreply.github.com>
This commit is contained in:
parent
21b4aa5072
commit
894b2b2a0e
@ -130,6 +130,7 @@ public:
|
|||||||
QString get_default_theme_path(QString p_file);
|
QString get_default_theme_path(QString p_file);
|
||||||
QString get_custom_theme_path(QString p_theme, QString p_file);
|
QString get_custom_theme_path(QString p_theme, QString p_file);
|
||||||
QString get_character_path(QString p_char, QString p_file);
|
QString get_character_path(QString p_char, QString p_file);
|
||||||
|
QString get_misc_path(QString p_misc, QString p_file);
|
||||||
QString get_sounds_path(QString p_file);
|
QString get_sounds_path(QString p_file);
|
||||||
QString get_music_path(QString p_song);
|
QString get_music_path(QString p_song);
|
||||||
QString get_background_path(QString p_file);
|
QString get_background_path(QString p_file);
|
||||||
@ -301,14 +302,14 @@ public:
|
|||||||
// Returns the color with p_identifier from p_file
|
// Returns the color with p_identifier from p_file
|
||||||
QColor get_color(QString p_identifier, QString p_file);
|
QColor get_color(QString p_identifier, QString p_file);
|
||||||
|
|
||||||
// Returns the markdown symbol used for specified p_identifier such as colors
|
// Returns the markup symbol used for specified p_identifier such as colors
|
||||||
QString get_chat_markdown(QString p_identifier, QString p_file);
|
QString get_chat_markup(QString p_identifier, QString p_file);
|
||||||
|
|
||||||
// Returns the color from the misc folder.
|
// Returns the color from the misc folder.
|
||||||
QColor get_chat_color(QString p_identifier, QString p_chat);
|
QColor get_chat_color(QString p_identifier, QString p_chat);
|
||||||
|
|
||||||
// Returns the sfx with p_identifier from sounds.ini in the current theme path
|
// Returns the sfx with p_identifier from sounds.ini in the current theme path
|
||||||
QString get_sfx(QString p_identifier);
|
QString get_sfx(QString p_identifier, QString p_misc="default");
|
||||||
|
|
||||||
// Figure out if we can opus this or if we should fall back to wav
|
// Figure out if we can opus this or if we should fall back to wav
|
||||||
QString get_sfx_suffix(QString sound_to_check);
|
QString get_sfx_suffix(QString sound_to_check);
|
||||||
@ -380,9 +381,9 @@ public:
|
|||||||
// t
|
// t
|
||||||
QString get_effect(QString effect, QString p_char, QString p_folder);
|
QString get_effect(QString effect, QString p_char, QString p_folder);
|
||||||
|
|
||||||
// Return the effect sound associated with the fx_name in the
|
// Return p_property of fx_name. If p_property is "sound", return
|
||||||
// misc/effects/<char-defined>/sounds.ini, or theme/effects/sounds.ini.
|
// the value associated with fx_name, otherwise use fx_name + '_' + p_property.
|
||||||
QString get_effect_sound(QString fx_name, QString p_char);
|
QString get_effect_property(QString fx_name, QString p_char, QString p_property);
|
||||||
|
|
||||||
// Returns the custom realisation used by the character.
|
// Returns the custom realisation used by the character.
|
||||||
QString get_custom_realization(QString p_char);
|
QString get_custom_realization(QString p_char);
|
||||||
@ -432,6 +433,15 @@ public:
|
|||||||
// Returns p_char's blips (previously called their "gender")
|
// Returns p_char's blips (previously called their "gender")
|
||||||
QString get_blips(QString p_char);
|
QString get_blips(QString p_char);
|
||||||
|
|
||||||
|
// Get a property of a given emote, or get it from "options" if emote doesn't have it
|
||||||
|
QString get_emote_property(QString p_char, QString p_emote, QString p_property);
|
||||||
|
|
||||||
|
// Return a transformation mode from a string ("smooth" for smooth, anything else for fast)
|
||||||
|
Qt::TransformationMode get_scaling(QString p_scaling);
|
||||||
|
|
||||||
|
// Returns the scaling type for p_miscname
|
||||||
|
Qt::TransformationMode get_misc_scaling(QString p_miscname);
|
||||||
|
|
||||||
// ======
|
// ======
|
||||||
// These are all casing-related settings.
|
// These are all casing-related settings.
|
||||||
// ======
|
// ======
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
#ifndef AOCHARMOVIE_H
|
|
||||||
#define AOCHARMOVIE_H
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QElapsedTimer>
|
|
||||||
#include <QImageReader>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
class AOApplication;
|
|
||||||
|
|
||||||
class AOCharMovie : public QLabel {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app);
|
|
||||||
|
|
||||||
// Play a hat.gif - style preanimation
|
|
||||||
void play_pre(QString p_char, QString p_emote, int duration);
|
|
||||||
|
|
||||||
// Play a (b)normal.gif - style animation (talking)
|
|
||||||
void play_talking(QString p_char, QString p_emote);
|
|
||||||
|
|
||||||
// Play an (a)normal.gif - style animation (not talking)
|
|
||||||
void play_idle(QString p_char, QString p_emote);
|
|
||||||
|
|
||||||
// Stop the movie, clearing the image
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
// Set the m_flipped variable to true/false
|
|
||||||
void set_flipped(bool p_flipped) { m_flipped = p_flipped; }
|
|
||||||
|
|
||||||
// Set the movie's playback speed (between 10% and 1000%)
|
|
||||||
void set_speed(int modifier) { speed = qMax(10, qMin(modifier, 1000)); }
|
|
||||||
|
|
||||||
// Move the label itself around
|
|
||||||
void move(int ax, int ay);
|
|
||||||
|
|
||||||
// This is somewhat pointless now as there's no "QMovie" object to resize, aka
|
|
||||||
// no "combo" to speak of
|
|
||||||
void combo_resize(int w, int h);
|
|
||||||
|
|
||||||
// Return the frame delay adjusted for speed
|
|
||||||
int get_frame_delay(int delay);
|
|
||||||
|
|
||||||
QStringList network_strings;
|
|
||||||
|
|
||||||
QString m_char;
|
|
||||||
QString m_emote;
|
|
||||||
|
|
||||||
private:
|
|
||||||
AOApplication *ao_app;
|
|
||||||
|
|
||||||
QVector<QPixmap> movie_frames;
|
|
||||||
QVector<int> movie_delays;
|
|
||||||
|
|
||||||
// Effects such as sfx, screenshakes and realization flashes are stored in
|
|
||||||
// here. QString entry format: "sfx^[sfx_name]", "shake", "flash". The program
|
|
||||||
// uses the QVector index as reference.
|
|
||||||
QVector<QVector<QString>> movie_effects;
|
|
||||||
|
|
||||||
QTimer *preanim_timer;
|
|
||||||
QTimer *ticker;
|
|
||||||
QString last_path;
|
|
||||||
QImageReader *m_reader = new QImageReader();
|
|
||||||
|
|
||||||
QElapsedTimer actual_time;
|
|
||||||
|
|
||||||
// Usually used to turn seconds into milliseconds such as for [Time] tag in
|
|
||||||
// char.ini
|
|
||||||
const int time_mod = 60;
|
|
||||||
|
|
||||||
// These are the X and Y values before they are fixed based on the sprite's
|
|
||||||
// width.
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
// These are the width and height values before they are fixed based on the
|
|
||||||
// sprite's width.
|
|
||||||
int f_w = 0;
|
|
||||||
int f_h = 0;
|
|
||||||
|
|
||||||
int frame = 0;
|
|
||||||
int max_frames = 0;
|
|
||||||
|
|
||||||
int speed = 100;
|
|
||||||
|
|
||||||
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();
|
|
||||||
void flash();
|
|
||||||
void play_sfx(QString sfx);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void preanim_done();
|
|
||||||
void movie_ticker();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOCHARMOVIE_H
|
|
@ -2,7 +2,7 @@
|
|||||||
#define AOEVIDENCEDISPLAY_H
|
#define AOEVIDENCEDISPLAY_H
|
||||||
|
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
#include "aomovie.h"
|
#include "aolayer.h"
|
||||||
#include "aosfxplayer.h"
|
#include "aosfxplayer.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -21,7 +21,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
AOApplication *ao_app;
|
AOApplication *ao_app;
|
||||||
AOMovie *evidence_movie;
|
InterfaceLayer *evidence_movie;
|
||||||
QLabel *evidence_icon;
|
QLabel *evidence_icon;
|
||||||
AOSfxPlayer *sfx_player;
|
AOSfxPlayer *sfx_player;
|
||||||
|
|
||||||
|
214
include/aolayer.h
Normal file
214
include/aolayer.h
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
#ifndef AOLAYER_H
|
||||||
|
#define AOLAYER_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
#include <QImageReader>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QBitmap>
|
||||||
|
|
||||||
|
class AOApplication;
|
||||||
|
|
||||||
|
class AOLayer : public QLabel {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AOLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
||||||
|
|
||||||
|
QString filename; // file name without extension, i.e. "witnesstestimony"
|
||||||
|
int static_duration; // time in ms for static images to be displayed, if
|
||||||
|
// applicable. set to 0 for infinite
|
||||||
|
int max_duration; // maximum duration in ms, image will be culled if it is
|
||||||
|
// exceeded. set this to 0 for infinite duration
|
||||||
|
bool play_once = false; // Whether to loop this animation or not
|
||||||
|
bool cull_image = true; // if we're done playing this animation, should we
|
||||||
|
// hide it? also controls durational culling
|
||||||
|
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?
|
||||||
|
|
||||||
|
// Set the movie's image to provided paths, preparing for playback.
|
||||||
|
void start_playback(QString p_image);
|
||||||
|
|
||||||
|
void set_play_once(bool p_play_once);
|
||||||
|
void set_cull_image(bool p_cull_image);
|
||||||
|
void set_static_duration(int p_static_duration);
|
||||||
|
void set_max_duration(int p_max_duration);
|
||||||
|
|
||||||
|
// Stop the movie, clearing the image
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
// Set the m_flipped variable to true/false
|
||||||
|
void set_flipped(bool p_flipped) { m_flipped = p_flipped; }
|
||||||
|
|
||||||
|
// Set the movie's playback speed (between 10% and 1000%)
|
||||||
|
void set_speed(int modifier) { speed = qMax(10, qMin(modifier, 1000)); }
|
||||||
|
|
||||||
|
// Move the label itself around
|
||||||
|
void move(int ax, int ay);
|
||||||
|
|
||||||
|
// This is somewhat pointless now as there's no "QMovie" object to resize, aka
|
||||||
|
// no "combo" to speak of
|
||||||
|
void combo_resize(int w, int h);
|
||||||
|
|
||||||
|
// Return the frame delay adjusted for speed
|
||||||
|
int get_frame_delay(int delay);
|
||||||
|
|
||||||
|
// iterate through a list of paths and return the first entry that exists. if
|
||||||
|
// none exist, return NULL (safe because we check again for existence later)
|
||||||
|
QString find_image(QList<QString> p_list);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AOApplication *ao_app;
|
||||||
|
QVector<QPixmap> movie_frames;
|
||||||
|
QVector<int> movie_delays;
|
||||||
|
|
||||||
|
QTimer *preanim_timer;
|
||||||
|
QTimer *shfx_timer;
|
||||||
|
QTimer *ticker;
|
||||||
|
QString last_path;
|
||||||
|
QImageReader m_reader;
|
||||||
|
|
||||||
|
QElapsedTimer actual_time;
|
||||||
|
|
||||||
|
// Usually used to turn seconds into milliseconds such as for [Time] tag in
|
||||||
|
// char.ini
|
||||||
|
const int tick_ms = 60;
|
||||||
|
|
||||||
|
// These are the X and Y values before they are fixed based on the sprite's
|
||||||
|
// width.
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
// These are the width and height values before they are fixed based on the
|
||||||
|
// sprite's width.
|
||||||
|
int f_w = 0;
|
||||||
|
int f_h = 0;
|
||||||
|
|
||||||
|
int frame = 0;
|
||||||
|
int max_frames = 0;
|
||||||
|
int last_max_frames = 0;
|
||||||
|
|
||||||
|
int speed = 100;
|
||||||
|
|
||||||
|
bool m_flipped = false;
|
||||||
|
// Are we loading this from the same frame we left off on? TODO: actually make
|
||||||
|
// this work
|
||||||
|
bool continuous = false;
|
||||||
|
// Whether or not to forcibly bypass the simple check done by start_playback
|
||||||
|
// and use the existent value of continuous instead
|
||||||
|
bool force_continuous = false;
|
||||||
|
|
||||||
|
int duration = 0;
|
||||||
|
|
||||||
|
// Start playback of the movie (if animated).
|
||||||
|
void play();
|
||||||
|
|
||||||
|
// Freeze the movie at the current frame.
|
||||||
|
void freeze();
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void done();
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
virtual void preanim_done();
|
||||||
|
void shfx_timer_done();
|
||||||
|
virtual void movie_ticker();
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundLayer : public AOLayer {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
BackgroundLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
||||||
|
void load_image(QString p_filename);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ForegroundLayer : public AOLayer {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ForegroundLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
||||||
|
QString miscname; //'misc' folder to search. we fetch this based on p_charname below
|
||||||
|
void load_image(QString p_filename, QString p_charname);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CharLayer : public AOLayer {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CharLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
||||||
|
QString current_emote = ""; // name of the emote we're using
|
||||||
|
bool is_preanim; // equivalent to the old play_once, if true we don't want
|
||||||
|
// to loop this
|
||||||
|
QString prefix = ""; // prefix, left blank if it's a preanim
|
||||||
|
|
||||||
|
void load_image(QString p_filename, QString p_charname, int p_duration, bool p_is_preanim);
|
||||||
|
void play(); // overloaded so we can play effects
|
||||||
|
|
||||||
|
// networked frame fx string
|
||||||
|
QStringList network_strings;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString last_char; // name of the last character we used
|
||||||
|
QString last_emote; // name of the last animation we used
|
||||||
|
QString last_prefix; // prefix of the last animation we played
|
||||||
|
bool was_preanim = false; // whether is_preanim was true last time
|
||||||
|
|
||||||
|
// Effects such as sfx, screenshakes and realization flashes are stored in
|
||||||
|
// here. QString entry format: "sfx^[sfx_name]", "shake", "flash". The program
|
||||||
|
// uses the QVector index as reference.
|
||||||
|
QVector<QVector<QString>> movie_effects;
|
||||||
|
|
||||||
|
// used for effect loading
|
||||||
|
QString m_char = "";
|
||||||
|
QString m_emote = "";
|
||||||
|
|
||||||
|
// overloaded for effects reasons
|
||||||
|
void start_playback(QString p_image);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// Play a frame-specific effect, if there's any defined for that specific
|
||||||
|
// frame.
|
||||||
|
void play_frame_effect(int p_frame);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void preanim_done() override; // overridden so we don't accidentally cull characters
|
||||||
|
void movie_ticker() override; // overridden so we can play effects
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void shake();
|
||||||
|
void flash();
|
||||||
|
void play_sfx(QString sfx);
|
||||||
|
};
|
||||||
|
|
||||||
|
class InterjectionLayer : public AOLayer {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
InterjectionLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
||||||
|
void load_image(QString p_filename, QString p_charname, QString p_miscname);
|
||||||
|
};
|
||||||
|
|
||||||
|
class EffectLayer : public AOLayer {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
EffectLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
||||||
|
void load_image(QString p_filename, bool p_looping);
|
||||||
|
};
|
||||||
|
|
||||||
|
class InterfaceLayer : public AOLayer {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
InterfaceLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
||||||
|
void load_image(QString p_filename, QString p_miscname);
|
||||||
|
};
|
||||||
|
#endif // AOLAYER_H
|
@ -1,36 +0,0 @@
|
|||||||
#ifndef AOMOVIE_H
|
|
||||||
#define AOMOVIE_H
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QMovie>
|
|
||||||
|
|
||||||
class Courtroom;
|
|
||||||
class AOApplication;
|
|
||||||
|
|
||||||
class AOMovie : public QLabel {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
AOMovie(QWidget *p_parent, AOApplication *p_ao_app);
|
|
||||||
|
|
||||||
void set_play_once(bool p_play_once);
|
|
||||||
void play(QString p_image, QString p_char = "", QString p_custom_theme = "",
|
|
||||||
int default_duration = 0);
|
|
||||||
void combo_resize(int w, int h);
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QMovie *m_movie;
|
|
||||||
AOApplication *ao_app;
|
|
||||||
QTimer *timer;
|
|
||||||
bool play_once = true;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void done();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void frame_change(int n_frame);
|
|
||||||
void timer_done();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOMOVIE_H
|
|
@ -1,42 +0,0 @@
|
|||||||
#ifndef AOSCENE_H
|
|
||||||
#define AOSCENE_H
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QMovie>
|
|
||||||
|
|
||||||
class Courtroom;
|
|
||||||
class AOApplication;
|
|
||||||
|
|
||||||
class AOScene : public QLabel {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit AOScene(QWidget *parent, AOApplication *p_ao_app);
|
|
||||||
|
|
||||||
void set_image(QString p_image);
|
|
||||||
void set_legacy_desk(QString p_image);
|
|
||||||
|
|
||||||
// Move the label itself around
|
|
||||||
void move(int ax, int ay);
|
|
||||||
|
|
||||||
// This is somewhat pointless now as there's no "QMovie" object to resize, aka
|
|
||||||
// no "combo" to speak of
|
|
||||||
void combo_resize(int w, int h);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QWidget *m_parent;
|
|
||||||
QMovie *m_movie;
|
|
||||||
AOApplication *ao_app;
|
|
||||||
QString last_image;
|
|
||||||
|
|
||||||
// These are the X and Y values before they are fixed based on the sprite's
|
|
||||||
// width.
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
// These are the width and height values before they are fixed based on the
|
|
||||||
// sprite's width.
|
|
||||||
int f_w = 0;
|
|
||||||
int f_h = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOSCENE_H
|
|
@ -5,17 +5,15 @@
|
|||||||
#include "aoblipplayer.h"
|
#include "aoblipplayer.h"
|
||||||
#include "aobutton.h"
|
#include "aobutton.h"
|
||||||
#include "aocharbutton.h"
|
#include "aocharbutton.h"
|
||||||
#include "aocharmovie.h"
|
|
||||||
#include "aoemotebutton.h"
|
#include "aoemotebutton.h"
|
||||||
#include "aoevidencebutton.h"
|
#include "aoevidencebutton.h"
|
||||||
#include "aoevidencedisplay.h"
|
#include "aoevidencedisplay.h"
|
||||||
#include "aoimage.h"
|
#include "aoimage.h"
|
||||||
|
#include "aolayer.h"
|
||||||
#include "aolineedit.h"
|
#include "aolineedit.h"
|
||||||
#include "aomovie.h"
|
|
||||||
#include "aomusicplayer.h"
|
#include "aomusicplayer.h"
|
||||||
#include "aooptionsdialog.h"
|
#include "aooptionsdialog.h"
|
||||||
#include "aopacket.h"
|
#include "aopacket.h"
|
||||||
#include "aoscene.h"
|
|
||||||
#include "aosfxplayer.h"
|
#include "aosfxplayer.h"
|
||||||
#include "aotextarea.h"
|
#include "aotextarea.h"
|
||||||
#include "aotextedit.h"
|
#include "aotextedit.h"
|
||||||
@ -151,6 +149,9 @@ public:
|
|||||||
// reads theme inis and sets size and pos based on the identifier
|
// reads theme inis and sets size and pos based on the identifier
|
||||||
void set_size_and_pos(QWidget *p_widget, QString p_identifier);
|
void set_size_and_pos(QWidget *p_widget, QString p_identifier);
|
||||||
|
|
||||||
|
// reads theme and char inis and sets size and pos based on the identifier
|
||||||
|
void set_size_and_pos(QWidget *p_widget, QString p_identifier, QString p_char);
|
||||||
|
|
||||||
// reads theme inis and returns the size and pos as defined by it
|
// reads theme inis and returns the size and pos as defined by it
|
||||||
QPoint get_theme_pos(QString p_identifier);
|
QPoint get_theme_pos(QString p_identifier);
|
||||||
|
|
||||||
@ -224,11 +225,13 @@ public:
|
|||||||
// Parse the chat message packet and unpack it into the m_chatmessage[ITEM] format
|
// Parse the chat message packet and unpack it into the m_chatmessage[ITEM] format
|
||||||
void unpack_chatmessage(QStringList p_contents);
|
void unpack_chatmessage(QStringList p_contents);
|
||||||
|
|
||||||
// Log the message contents and information such as evidence presenting etc. into the log file
|
enum LogMode {
|
||||||
void log_chatmessage(QString f_message, int f_char_id, QString f_showname = "", int f_color = 0);
|
IO_ONLY,
|
||||||
|
DISPLAY_ONLY,
|
||||||
// Display the message contents and information such as evidence presenting etc. in the IC logs
|
DISPLAY_AND_IO
|
||||||
void display_log_chatmessage(QString f_message, int f_char_id, QString f_showname = "", int f_color = 0);
|
};
|
||||||
|
// 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);
|
||||||
|
|
||||||
// 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();
|
||||||
@ -264,7 +267,8 @@ public:
|
|||||||
QString filter_ic_text(QString p_text, bool colorize = false, int pos = -1,
|
QString filter_ic_text(QString p_text, bool colorize = false, int pos = -1,
|
||||||
int default_color = 0);
|
int default_color = 0);
|
||||||
|
|
||||||
void log_ic_text(QString p_name, QString p_showname, QString p_message, QString p_action="", int p_color=0);
|
void log_ic_text(QString p_name, QString p_showname, QString p_message,
|
||||||
|
QString p_action = "", int p_color = 0);
|
||||||
|
|
||||||
// adds text to the IC chatlog. p_name first as bold then p_text then a newlin
|
// adds text to the IC chatlog. p_name first as bold then p_text then a newlin
|
||||||
// this function keeps the chatlog scrolled to the top unless there's text
|
// this function keeps the chatlog scrolled to the top unless there's text
|
||||||
@ -380,7 +384,8 @@ private:
|
|||||||
// True, if log should display colors.
|
// True, if log should display colors.
|
||||||
bool log_colors = true;
|
bool log_colors = true;
|
||||||
|
|
||||||
// True, if the log should display the message like name<br>text instead of name: text
|
// True, if the log should display the message like name<br>text instead of
|
||||||
|
// name: text
|
||||||
bool log_newline = false;
|
bool log_newline = false;
|
||||||
|
|
||||||
// True, if the log should include RP actions like interjections, showing evidence, etc.
|
// True, if the log should include RP actions like interjections, showing evidence, etc.
|
||||||
@ -408,16 +413,21 @@ private:
|
|||||||
const int time_mod = 40;
|
const int time_mod = 40;
|
||||||
|
|
||||||
// the amount of time non-animated objection/hold it/takethat images stay
|
// the amount of time non-animated objection/hold it/takethat images stay
|
||||||
// onscreen for in ms
|
// onscreen for in ms, and the maximum amount of time any interjections are
|
||||||
const int shout_stay_time = 724;
|
// allowed to play
|
||||||
|
const int shout_static_time = 724;
|
||||||
|
const int shout_max_time = 1500;
|
||||||
|
|
||||||
// the amount of time non-animated guilty/not guilty images stay onscreen for
|
// the amount of time non-animated guilty/not guilty images stay onscreen for
|
||||||
// in ms
|
// in ms, and the maximum amount of time g/ng images are allowed to play
|
||||||
const int verdict_stay_time = 3000;
|
const int verdict_static_time = 3000;
|
||||||
|
const int verdict_max_time = 4000;
|
||||||
|
|
||||||
// the amount of time non-animated witness testimony/cross-examination images
|
// the amount of time non-animated witness testimony/cross-examination images
|
||||||
// stay onscreen for in ms
|
// stay onscreen for in ms, and the maximum time any wt/ce image is allowed to
|
||||||
const int wtce_stay_time = 1500;
|
// play
|
||||||
|
const int wtce_static_time = 1500;
|
||||||
|
const int wtce_max_time = 4000;
|
||||||
|
|
||||||
// characters we consider punctuation
|
// characters we consider punctuation
|
||||||
const QString punctuation_chars = ".,?!:;";
|
const QString punctuation_chars = ".,?!:;";
|
||||||
@ -441,7 +451,7 @@ private:
|
|||||||
bool is_muted = false;
|
bool is_muted = false;
|
||||||
|
|
||||||
// state of animation, 0 = objecting, 1 = preanim, 2 = talking, 3 = idle, 4 =
|
// state of animation, 0 = objecting, 1 = preanim, 2 = talking, 3 = idle, 4 =
|
||||||
// noniterrupting preanim
|
// noniterrupting preanim, 5 = (c) animation
|
||||||
int anim_state = 3;
|
int anim_state = 3;
|
||||||
|
|
||||||
// whether or not current color is a talking one
|
// whether or not current color is a talking one
|
||||||
@ -512,6 +522,7 @@ private:
|
|||||||
|
|
||||||
// is the message we're about to send supposed to present evidence?
|
// is the message we're about to send supposed to present evidence?
|
||||||
bool is_presenting_evidence = false;
|
bool is_presenting_evidence = false;
|
||||||
|
bool c_played = false; // whether we've played a (c)-style postanimation yet
|
||||||
|
|
||||||
// have we already presented evidence for this message?
|
// have we already presented evidence for this message?
|
||||||
bool evidence_presented = false;
|
bool evidence_presented = false;
|
||||||
@ -579,21 +590,20 @@ private:
|
|||||||
AOImage *ui_background;
|
AOImage *ui_background;
|
||||||
|
|
||||||
QWidget *ui_viewport;
|
QWidget *ui_viewport;
|
||||||
AOScene *ui_vp_background;
|
BackgroundLayer *ui_vp_background;
|
||||||
AOMovie *ui_vp_speedlines;
|
ForegroundLayer *ui_vp_speedlines;
|
||||||
AOCharMovie *ui_vp_player_char;
|
CharLayer *ui_vp_player_char;
|
||||||
AOCharMovie *ui_vp_sideplayer_char;
|
CharLayer *ui_vp_sideplayer_char;
|
||||||
AOScene *ui_vp_desk;
|
BackgroundLayer *ui_vp_desk;
|
||||||
AOScene *ui_vp_legacy_desk;
|
|
||||||
AOEvidenceDisplay *ui_vp_evidence_display;
|
AOEvidenceDisplay *ui_vp_evidence_display;
|
||||||
AOImage *ui_vp_chatbox;
|
AOImage *ui_vp_chatbox;
|
||||||
QLabel *ui_vp_showname;
|
QLabel *ui_vp_showname;
|
||||||
AOMovie *ui_vp_chat_arrow;
|
InterfaceLayer *ui_vp_chat_arrow;
|
||||||
QTextEdit *ui_vp_message;
|
QTextEdit *ui_vp_message;
|
||||||
AOMovie *ui_vp_effect;
|
EffectLayer *ui_vp_effect;
|
||||||
AOMovie *ui_vp_testimony;
|
InterfaceLayer *ui_vp_testimony;
|
||||||
AOMovie *ui_vp_wtce;
|
InterjectionLayer *ui_vp_wtce;
|
||||||
AOMovie *ui_vp_objection;
|
InterjectionLayer *ui_vp_objection;
|
||||||
|
|
||||||
QTextEdit *ui_ic_chatlog;
|
QTextEdit *ui_ic_chatlog;
|
||||||
|
|
||||||
@ -605,7 +615,7 @@ private:
|
|||||||
QTreeWidget *ui_music_list;
|
QTreeWidget *ui_music_list;
|
||||||
|
|
||||||
ScrollText *ui_music_name;
|
ScrollText *ui_music_name;
|
||||||
AOMovie *ui_music_display;
|
InterfaceLayer *ui_music_display;
|
||||||
|
|
||||||
AOButton *ui_pair_button;
|
AOButton *ui_pair_button;
|
||||||
QListWidget *ui_pair_list;
|
QListWidget *ui_pair_list;
|
||||||
@ -759,6 +769,7 @@ private:
|
|||||||
void regenerate_ic_chatlog();
|
void regenerate_ic_chatlog();
|
||||||
public slots:
|
public slots:
|
||||||
void objection_done();
|
void objection_done();
|
||||||
|
void effect_done();
|
||||||
void preanim_done();
|
void preanim_done();
|
||||||
void do_screenshake();
|
void do_screenshake();
|
||||||
void do_flash();
|
void do_flash();
|
||||||
|
@ -1,332 +0,0 @@
|
|||||||
#include "aocharmovie.h"
|
|
||||||
|
|
||||||
#include "aoapplication.h"
|
|
||||||
#include "file_functions.h"
|
|
||||||
#include "misc_functions.h"
|
|
||||||
|
|
||||||
AOCharMovie::AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app)
|
|
||||||
: QLabel(p_parent)
|
|
||||||
{
|
|
||||||
ao_app = p_ao_app;
|
|
||||||
preanim_timer = new QTimer(this);
|
|
||||||
preanim_timer->setSingleShot(true);
|
|
||||||
|
|
||||||
ticker = new QTimer(this);
|
|
||||||
ticker->setTimerType(Qt::PreciseTimer);
|
|
||||||
ticker->setSingleShot(false);
|
|
||||||
connect(ticker, SIGNAL(timeout()), this, SLOT(movie_ticker()));
|
|
||||||
|
|
||||||
// connect(m_movie, SIGNAL(frameChanged(int)), this,
|
|
||||||
// SLOT(frame_change(int)));
|
|
||||||
connect(preanim_timer, SIGNAL(timeout()), this, SLOT(preanim_done()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::load_image(QString p_char, QString p_emote,
|
|
||||||
QString emote_prefix)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_CHARMOVIE
|
|
||||||
actual_time.restart();
|
|
||||||
#endif
|
|
||||||
QString emote_path;
|
|
||||||
QList<QString> pathlist;
|
|
||||||
pathlist = {
|
|
||||||
ao_app->get_image_suffix(ao_app->get_character_path(
|
|
||||||
p_char, emote_prefix + p_emote)), // Default path
|
|
||||||
ao_app->get_image_suffix(ao_app->get_character_path(
|
|
||||||
p_char, emote_prefix + "/" +
|
|
||||||
p_emote)), // Path check if it's categorized into a folder
|
|
||||||
ao_app->get_image_suffix(ao_app->get_character_path(
|
|
||||||
p_char, p_emote)), // Just use the non-prefixed image, animated or not
|
|
||||||
ao_app->get_image_suffix(
|
|
||||||
ao_app->get_theme_path("placeholder")), // Theme placeholder path
|
|
||||||
ao_app->get_image_suffix(ao_app->get_default_theme_path(
|
|
||||||
"placeholder")), // Default theme placeholder path
|
|
||||||
};
|
|
||||||
|
|
||||||
for (QString path : pathlist) {
|
|
||||||
if (file_exists(path)) {
|
|
||||||
emote_path = path;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->clear();
|
|
||||||
ticker->stop();
|
|
||||||
preanim_timer->stop();
|
|
||||||
movie_frames.clear();
|
|
||||||
movie_delays.clear();
|
|
||||||
movie_effects.clear();
|
|
||||||
|
|
||||||
if (!file_exists(emote_path))
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_reader->setFileName(emote_path);
|
|
||||||
|
|
||||||
// set format to apng if png supports animation
|
|
||||||
if (emote_path.endsWith("png")) {
|
|
||||||
m_reader->setFormat("apng");
|
|
||||||
if (!m_reader->supportsAnimation()) {
|
|
||||||
m_reader->setFormat("png");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap f_pixmap = this->get_pixmap(m_reader->read());
|
|
||||||
int f_delay = m_reader->nextImageDelay();
|
|
||||||
|
|
||||||
frame = 0;
|
|
||||||
max_frames = m_reader->imageCount();
|
|
||||||
|
|
||||||
this->set_frame(f_pixmap);
|
|
||||||
this->show();
|
|
||||||
if (max_frames > 1) {
|
|
||||||
movie_frames.append(f_pixmap);
|
|
||||||
movie_delays.append(f_delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_char = p_char;
|
|
||||||
m_emote = emote_prefix + p_emote;
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
actual_time.restart();
|
|
||||||
#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);
|
|
||||||
if (max_frames <= 1) {
|
|
||||||
if (play_once)
|
|
||||||
ticker->start(60);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ticker->start(this->get_frame_delay(movie_delays[frame]));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::play_pre(QString p_char, QString p_emote, int duration)
|
|
||||||
{
|
|
||||||
load_image(p_char, p_emote, "");
|
|
||||||
// As much as I'd like to screw around with [Time] durations modifying the
|
|
||||||
// animation speed, I don't think I can reliably do that, not without looping
|
|
||||||
// through all frames in the image at least - which causes lag. So for now it
|
|
||||||
// simply ends the preanimation early instead.
|
|
||||||
play_once = true;
|
|
||||||
if (duration >
|
|
||||||
0) // It's -1 if there's no definition in [Time] for it. In which case, it
|
|
||||||
// will let the animation run out in full. Duration 0 does the same.
|
|
||||||
preanim_timer->start(duration *
|
|
||||||
time_mod); // This timer will not fire if the animation
|
|
||||||
// finishes earlier than that
|
|
||||||
play();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::play_talking(QString p_char, QString p_emote)
|
|
||||||
{
|
|
||||||
play_once = false;
|
|
||||||
load_image(p_char, p_emote, "(b)");
|
|
||||||
play();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::play_idle(QString p_char, QString p_emote)
|
|
||||||
{
|
|
||||||
play_once = false;
|
|
||||||
load_image(p_char, p_emote, "(a)");
|
|
||||||
play();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::play_frame_effect(int frame)
|
|
||||||
{
|
|
||||||
if (frame < max_frames) {
|
|
||||||
foreach (QString effect, movie_effects[frame]) {
|
|
||||||
if (effect == "shake") {
|
|
||||||
shake();
|
|
||||||
#ifdef DEBUG_CHARMOVIE
|
|
||||||
qDebug() << "Attempting to play shake on frame" << frame;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effect == "flash") {
|
|
||||||
flash();
|
|
||||||
#ifdef DEBUG_CHARMOVIE
|
|
||||||
qDebug() << "Attempting to play flash on frame" << frame;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effect.startsWith("sfx^")) {
|
|
||||||
QString sfx = effect.section("^", 1);
|
|
||||||
play_sfx(sfx);
|
|
||||||
#ifdef DEBUG_CHARMOVIE
|
|
||||||
qDebug() << "Attempting to play sfx" << sfx << "on frame" << frame;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::stop()
|
|
||||||
{
|
|
||||||
// for all intents and purposes, stopping is the same as hiding. at no point
|
|
||||||
// do we want a frozen gif to display
|
|
||||||
ticker->stop();
|
|
||||||
preanim_timer->stop();
|
|
||||||
this->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap AOCharMovie::get_pixmap(QImage image)
|
|
||||||
{
|
|
||||||
QPixmap f_pixmap;
|
|
||||||
if (m_flipped)
|
|
||||||
f_pixmap = QPixmap::fromImage(image.mirrored(true, false));
|
|
||||||
else
|
|
||||||
f_pixmap = QPixmap::fromImage(image);
|
|
||||||
// auto aspect_ratio = Qt::KeepAspectRatio;
|
|
||||||
auto transform_mode = Qt::FastTransformation;
|
|
||||||
if (f_pixmap.height() > f_h) // We are downscaling, use anti-aliasing.
|
|
||||||
transform_mode = Qt::SmoothTransformation;
|
|
||||||
|
|
||||||
f_pixmap = f_pixmap.scaledToHeight(f_h, transform_mode);
|
|
||||||
this->resize(f_pixmap.size());
|
|
||||||
|
|
||||||
return f_pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::set_frame(QPixmap f_pixmap)
|
|
||||||
{
|
|
||||||
this->setPixmap(f_pixmap);
|
|
||||||
QLabel::move(
|
|
||||||
x + (f_w - f_pixmap.width()) / 2,
|
|
||||||
y + (f_h - f_pixmap.height())); // Always center horizontally, always put
|
|
||||||
// at the bottom vertically
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::combo_resize(int w, int h)
|
|
||||||
{
|
|
||||||
QSize f_size(w, h);
|
|
||||||
f_w = w;
|
|
||||||
f_h = h;
|
|
||||||
this->resize(f_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int AOCharMovie::get_frame_delay(int delay)
|
|
||||||
{
|
|
||||||
return static_cast<int>(double(delay) * double(speed / 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::move(int ax, int ay)
|
|
||||||
{
|
|
||||||
x = ax;
|
|
||||||
y = ay;
|
|
||||||
QLabel::move(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::movie_ticker()
|
|
||||||
{
|
|
||||||
++frame;
|
|
||||||
if (frame >= max_frames) {
|
|
||||||
if (play_once) {
|
|
||||||
preanim_done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
frame = 0;
|
|
||||||
}
|
|
||||||
// qint64 difference = elapsed - movie_delays[frame];
|
|
||||||
if (frame >= movie_frames.size()) {
|
|
||||||
m_reader->jumpToImage(frame);
|
|
||||||
movie_frames.resize(frame + 1);
|
|
||||||
movie_frames[frame] = this->get_pixmap(m_reader->read());
|
|
||||||
movie_delays.resize(frame + 1);
|
|
||||||
movie_delays[frame] = m_reader->nextImageDelay();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_CHARMOVIE
|
|
||||||
qDebug() << frame << movie_delays[frame]
|
|
||||||
<< "actual time taken from last frame:" << actual_time.restart();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this->set_frame(movie_frames[frame]);
|
|
||||||
play_frame_effect(frame);
|
|
||||||
ticker->setInterval(this->get_frame_delay(movie_delays[frame]));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOCharMovie::preanim_done()
|
|
||||||
{
|
|
||||||
ticker->stop();
|
|
||||||
preanim_timer->stop();
|
|
||||||
done();
|
|
||||||
}
|
|
@ -11,7 +11,7 @@ AOEvidenceDisplay::AOEvidenceDisplay(QWidget *p_parent, AOApplication *p_ao_app)
|
|||||||
evidence_icon = new QLabel(this);
|
evidence_icon = new QLabel(this);
|
||||||
sfx_player = new AOSfxPlayer(this, ao_app);
|
sfx_player = new AOSfxPlayer(this, ao_app);
|
||||||
|
|
||||||
evidence_movie = new AOMovie(this, ao_app);
|
evidence_movie = new InterfaceLayer(this, ao_app);
|
||||||
|
|
||||||
connect(evidence_movie, SIGNAL(done()), this, SLOT(show_done()));
|
connect(evidence_movie, SIGNAL(done()), this, SLOT(show_done()));
|
||||||
}
|
}
|
||||||
@ -46,9 +46,11 @@ void AOEvidenceDisplay::show_evidence(QString p_evidence_image,
|
|||||||
evidence_icon->setPixmap(f_pixmap);
|
evidence_icon->setPixmap(f_pixmap);
|
||||||
evidence_icon->resize(f_pixmap.size());
|
evidence_icon->resize(f_pixmap.size());
|
||||||
evidence_icon->move(icon_dimensions.x, icon_dimensions.y);
|
evidence_icon->move(icon_dimensions.x, icon_dimensions.y);
|
||||||
|
evidence_movie->static_duration = 320;
|
||||||
evidence_movie->play(gif_name);
|
evidence_movie->max_duration = 1000;
|
||||||
sfx_player->play(ao_app->get_sfx("evidence_present"));
|
evidence_movie->set_play_once(true);
|
||||||
|
evidence_movie->load_image(gif_name, "");
|
||||||
|
sfx_player->play(ao_app->get_sfx("evidence_present", "default"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOEvidenceDisplay::reset()
|
void AOEvidenceDisplay::reset()
|
||||||
|
577
src/aolayer.cpp
Normal file
577
src/aolayer.cpp
Normal file
@ -0,0 +1,577 @@
|
|||||||
|
#include "aolayer.h"
|
||||||
|
|
||||||
|
#include "aoapplication.h"
|
||||||
|
#include "file_functions.h"
|
||||||
|
#include "misc_functions.h"
|
||||||
|
|
||||||
|
AOLayer::AOLayer(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent)
|
||||||
|
{
|
||||||
|
ao_app = p_ao_app;
|
||||||
|
|
||||||
|
// used for culling images when their max_duration is exceeded
|
||||||
|
shfx_timer = new QTimer(this);
|
||||||
|
shfx_timer->setTimerType(Qt::PreciseTimer);
|
||||||
|
shfx_timer->setSingleShot(true);
|
||||||
|
connect(shfx_timer, SIGNAL(timeout()), this, SLOT(shfx_timer_done()));
|
||||||
|
|
||||||
|
ticker = new QTimer(this);
|
||||||
|
ticker->setTimerType(Qt::PreciseTimer);
|
||||||
|
ticker->setSingleShot(false);
|
||||||
|
connect(ticker, SIGNAL(timeout()), this, SLOT(movie_ticker()));
|
||||||
|
|
||||||
|
preanim_timer = new QTimer(this);
|
||||||
|
preanim_timer->setSingleShot(true);
|
||||||
|
connect(preanim_timer, SIGNAL(timeout()), this, SLOT(preanim_done()));
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundLayer::BackgroundLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
||||||
|
: AOLayer(p_parent, p_ao_app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
ForegroundLayer::ForegroundLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
||||||
|
: AOLayer(p_parent, p_ao_app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
CharLayer::CharLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
||||||
|
: AOLayer(p_parent, p_ao_app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
EffectLayer::EffectLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
||||||
|
: AOLayer(p_parent, p_ao_app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
InterjectionLayer::InterjectionLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
||||||
|
: AOLayer(p_parent, p_ao_app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
InterfaceLayer::InterfaceLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
||||||
|
: AOLayer(p_parent, p_ao_app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AOLayer::find_image(QList<QString> p_list)
|
||||||
|
{
|
||||||
|
QString image_path;
|
||||||
|
for (QString path : p_list) {
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << "checking path " << path;
|
||||||
|
#endif
|
||||||
|
if (file_exists(path)) {
|
||||||
|
image_path = path;
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << "found path " << path;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap AOLayer::get_pixmap(QImage image)
|
||||||
|
{
|
||||||
|
QPixmap f_pixmap;
|
||||||
|
if (m_flipped)
|
||||||
|
f_pixmap = QPixmap::fromImage(image.mirrored(true, false));
|
||||||
|
else
|
||||||
|
f_pixmap = QPixmap::fromImage(image);
|
||||||
|
// auto aspect_ratio = Qt::KeepAspectRatio;
|
||||||
|
if (f_pixmap.height() > f_h) // We are downscaling, use anti-aliasing.
|
||||||
|
transform_mode = Qt::SmoothTransformation;
|
||||||
|
if (stretch)
|
||||||
|
f_pixmap = f_pixmap.scaled(f_w, f_h);
|
||||||
|
else
|
||||||
|
f_pixmap = f_pixmap.scaledToHeight(f_h, transform_mode);
|
||||||
|
this->resize(f_pixmap.size());
|
||||||
|
|
||||||
|
return f_pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::set_frame(QPixmap f_pixmap)
|
||||||
|
{
|
||||||
|
this->setPixmap(f_pixmap);
|
||||||
|
QLabel::move(
|
||||||
|
x + (f_w - f_pixmap.width()) / 2,
|
||||||
|
y + (f_h - f_pixmap.height())); // Always center horizontally, always put
|
||||||
|
// at the bottom vertically
|
||||||
|
this->setMask(
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
QSize f_size(w, h);
|
||||||
|
f_w = w;
|
||||||
|
f_h = h;
|
||||||
|
this->resize(f_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int AOLayer::get_frame_delay(int delay)
|
||||||
|
{
|
||||||
|
return static_cast<int>(double(delay) * double(speed / 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::move(int ax, int ay)
|
||||||
|
{
|
||||||
|
x = ax;
|
||||||
|
y = ay;
|
||||||
|
QLabel::move(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundLayer::load_image(QString p_filename)
|
||||||
|
{
|
||||||
|
play_once = false;
|
||||||
|
cull_image = false;
|
||||||
|
QString design_path = ao_app->get_background_path("design.ini");
|
||||||
|
transform_mode =
|
||||||
|
ao_app->get_scaling(ao_app->read_design_ini("scaling", design_path));
|
||||||
|
stretch = ao_app->read_design_ini("stretch", design_path).startsWith("true");
|
||||||
|
qDebug() << "[BackgroundLayer] BG loaded: " << p_filename;
|
||||||
|
start_playback(ao_app->get_image_suffix(ao_app->get_background_path(p_filename)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForegroundLayer::load_image(QString p_filename, QString p_charname)
|
||||||
|
{
|
||||||
|
play_once = false;
|
||||||
|
cull_image = false;
|
||||||
|
miscname = ao_app->get_char_shouts(p_charname);
|
||||||
|
qDebug() << "[ForegroundLayer] FG loaded: " << p_filename;
|
||||||
|
QList<QString> pathlist = {
|
||||||
|
ao_app->get_image_suffix(ao_app->get_character_path(
|
||||||
|
p_charname, p_filename)), // first check the character folder
|
||||||
|
ao_app->get_image_suffix(ao_app->get_theme_path(
|
||||||
|
"misc/" + miscname + "/" +
|
||||||
|
p_filename)), // then check our theme's misc directory
|
||||||
|
ao_app->get_image_suffix(ao_app->get_misc_path(
|
||||||
|
miscname, p_filename)), // then check our global misc folder
|
||||||
|
ao_app->get_image_suffix(
|
||||||
|
ao_app->get_theme_path(p_filename)), // then check the user's theme
|
||||||
|
ao_app->get_image_suffix(ao_app->get_default_theme_path(
|
||||||
|
p_filename))}; // and finally check the default theme
|
||||||
|
start_playback(find_image(pathlist));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharLayer::load_image(QString p_filename, QString p_charname,
|
||||||
|
int p_duration, bool p_is_preanim)
|
||||||
|
{
|
||||||
|
duration = p_duration;
|
||||||
|
cull_image = false;
|
||||||
|
force_continuous = false;
|
||||||
|
transform_mode = ao_app->get_scaling(
|
||||||
|
ao_app->get_emote_property(p_charname, p_filename, "scaling"));
|
||||||
|
stretch = ao_app->get_emote_property(p_charname, p_filename, "stretch")
|
||||||
|
.startsWith(true);
|
||||||
|
if ((p_charname == last_char) &&
|
||||||
|
((p_filename == last_emote) ||
|
||||||
|
(p_filename.mid(3, -1) == last_emote.mid(3, -1))) &&
|
||||||
|
(!is_preanim) && (!was_preanim)) {
|
||||||
|
continuous = true;
|
||||||
|
force_continuous = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continuous = false;
|
||||||
|
force_continuous = true;
|
||||||
|
}
|
||||||
|
prefix = "";
|
||||||
|
current_emote = p_filename;
|
||||||
|
was_preanim = is_preanim;
|
||||||
|
m_char = p_charname;
|
||||||
|
m_emote = current_emote;
|
||||||
|
last_char = p_charname;
|
||||||
|
last_emote = current_emote;
|
||||||
|
last_prefix = prefix;
|
||||||
|
is_preanim = p_is_preanim;
|
||||||
|
if ((p_filename.left(3) == "(a)") || (p_filename.left(3) == "(b)")) {
|
||||||
|
prefix = p_filename.left(3);
|
||||||
|
current_emote = p_filename.mid(3, -1);
|
||||||
|
}
|
||||||
|
else if ((duration > 0) || (p_filename.left(3) == "(c)")) {
|
||||||
|
if (p_filename.left(3) == "(c)") {
|
||||||
|
prefix = "(c)";
|
||||||
|
current_emote = p_filename.mid(3, -1);
|
||||||
|
}
|
||||||
|
is_preanim = true;
|
||||||
|
play_once = true;
|
||||||
|
preanim_timer->start(duration * tick_ms);
|
||||||
|
}
|
||||||
|
qDebug() << "[CharLayer] anim loaded: prefix " << prefix << " filename "
|
||||||
|
<< current_emote << " from character: " << p_charname
|
||||||
|
<< " continuous: " << continuous;
|
||||||
|
QList<QString> pathlist = {
|
||||||
|
ao_app->get_image_suffix(ao_app->get_character_path(
|
||||||
|
p_charname, prefix + current_emote)), // Default path
|
||||||
|
ao_app->get_image_suffix(ao_app->get_character_path(
|
||||||
|
p_charname,
|
||||||
|
prefix + "/" + current_emote)), // Path check if it's categorized
|
||||||
|
// into a folder
|
||||||
|
ao_app->get_image_suffix(ao_app->get_character_path(
|
||||||
|
p_charname,
|
||||||
|
current_emote)), // Just use the non-prefixed image, animated or not
|
||||||
|
ao_app->get_image_suffix(
|
||||||
|
ao_app->get_theme_path("placeholder")), // Theme placeholder path
|
||||||
|
ao_app->get_image_suffix(ao_app->get_default_theme_path(
|
||||||
|
"placeholder"))}; // Default theme placeholder path
|
||||||
|
this->start_playback(find_image(pathlist));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterjectionLayer::load_image(QString p_filename, QString p_charname,
|
||||||
|
QString p_miscname)
|
||||||
|
{
|
||||||
|
continuous = false;
|
||||||
|
force_continuous = true;
|
||||||
|
play_once = true;
|
||||||
|
transform_mode = ao_app->get_misc_scaling(p_miscname);
|
||||||
|
QList<QString> pathlist = {
|
||||||
|
ao_app->get_image_suffix(ao_app->get_character_path(
|
||||||
|
p_charname, p_filename)), // Character folder
|
||||||
|
ao_app->get_image_suffix(ao_app->get_theme_path(
|
||||||
|
"misc/" + p_miscname + "/" + p_filename)), // Theme misc path
|
||||||
|
ao_app->get_image_suffix(
|
||||||
|
ao_app->get_misc_path(p_miscname, p_filename)), // Misc path
|
||||||
|
ao_app->get_image_suffix(
|
||||||
|
ao_app->get_theme_path(p_filename)), // Theme path
|
||||||
|
ao_app->get_image_suffix(
|
||||||
|
ao_app->get_default_theme_path(p_filename)), // Default theme path
|
||||||
|
ao_app->get_image_suffix(
|
||||||
|
ao_app->get_theme_path("placeholder")), // Placeholder path
|
||||||
|
ao_app->get_image_suffix(ao_app->get_default_theme_path(
|
||||||
|
"placeholder")), // Default placeholder path
|
||||||
|
};
|
||||||
|
QString final_image = find_image(pathlist);
|
||||||
|
if (final_image == ao_app->get_theme_path("custom.png") ||
|
||||||
|
final_image == ao_app->get_default_theme_path("custom.png") ||
|
||||||
|
final_image == ao_app->get_theme_path("witnesstestimony.png") ||
|
||||||
|
final_image == ao_app->get_default_theme_path("witnesstestimony.png") ||
|
||||||
|
final_image == ao_app->get_theme_path("crossexamination.png") ||
|
||||||
|
final_image == ao_app->get_default_theme_path("crossexamination.png"))
|
||||||
|
// stupid exceptions because themes are stupid
|
||||||
|
final_image = find_image(
|
||||||
|
{ao_app->get_image_suffix(ao_app->get_theme_path("placeholder")),
|
||||||
|
ao_app->get_image_suffix(ao_app->get_default_theme_path("placeholder"))});
|
||||||
|
start_playback(final_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectLayer::load_image(QString p_filename, bool p_looping)
|
||||||
|
{
|
||||||
|
if (p_looping)
|
||||||
|
play_once = false;
|
||||||
|
else
|
||||||
|
play_once = true;
|
||||||
|
continuous = false;
|
||||||
|
force_continuous = true;
|
||||||
|
start_playback(p_filename); // handled in its own file before we see it
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterfaceLayer::load_image(QString p_filename, QString p_miscname)
|
||||||
|
{
|
||||||
|
transform_mode = ao_app->get_misc_scaling(p_miscname);
|
||||||
|
QList<QString> pathlist = {
|
||||||
|
ao_app->get_image_suffix(ao_app->get_theme_path(
|
||||||
|
"misc/" + p_miscname + "/" +
|
||||||
|
p_filename)), // first check our theme's misc directory
|
||||||
|
ao_app->get_image_suffix(ao_app->get_misc_path(
|
||||||
|
p_miscname, p_filename)), // then check our global misc folder
|
||||||
|
ao_app->get_image_suffix(ao_app->get_theme_path(
|
||||||
|
p_filename)), // then check the user's theme for a default image
|
||||||
|
ao_app->get_image_suffix(ao_app->get_default_theme_path(
|
||||||
|
p_filename))}; // and finally check the default theme
|
||||||
|
start_playback(find_image(pathlist));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharLayer::start_playback(QString p_image)
|
||||||
|
{
|
||||||
|
movie_effects.clear();
|
||||||
|
AOLayer::start_playback(p_image);
|
||||||
|
if (network_strings.size() > 0) // our FX overwritten by networked ones
|
||||||
|
load_network_effects();
|
||||||
|
else // Use default ini FX
|
||||||
|
load_effects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::start_playback(QString p_image)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
actual_time.restart();
|
||||||
|
#endif
|
||||||
|
this->clear();
|
||||||
|
freeze();
|
||||||
|
movie_frames.clear();
|
||||||
|
movie_delays.clear();
|
||||||
|
|
||||||
|
if (!file_exists(p_image))
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString scaling_override =
|
||||||
|
ao_app->read_design_ini("scaling", p_image + ".ini");
|
||||||
|
if (scaling_override != "")
|
||||||
|
transform_mode = ao_app->get_scaling(scaling_override);
|
||||||
|
QString stretch_override =
|
||||||
|
ao_app->read_design_ini("stretch", p_image + ".ini");
|
||||||
|
if (stretch_override != "")
|
||||||
|
stretch = stretch_override.startsWith("true");
|
||||||
|
|
||||||
|
qDebug() << "stretch:" << stretch << "filename:" << p_image;
|
||||||
|
m_reader.setFileName(p_image);
|
||||||
|
if (m_reader.loopCount() == 0)
|
||||||
|
play_once = true;
|
||||||
|
if ((last_path == p_image) && (!force_continuous))
|
||||||
|
continuous = true;
|
||||||
|
else if ((last_path != p_image) && !force_continuous)
|
||||||
|
continuous = false;
|
||||||
|
if (!continuous)
|
||||||
|
frame = 0;
|
||||||
|
force_continuous = false;
|
||||||
|
last_max_frames = max_frames;
|
||||||
|
max_frames = m_reader.imageCount();
|
||||||
|
if (((continuous) && (max_frames != last_max_frames)) || max_frames == 0) {
|
||||||
|
frame = 0;
|
||||||
|
continuous = false;
|
||||||
|
}
|
||||||
|
// CANTFIX: this causes a slight hitch
|
||||||
|
// The correct way of doing this would be to use QImageReader::jumpToImage()
|
||||||
|
// and populate missing data in the movie ticker when it's needed. This is
|
||||||
|
// unforunately completely impossible, because QImageReader::jumpToImage() is
|
||||||
|
// not implemented in any image format AO2 is equipped to use. Instead, the
|
||||||
|
// default behavior is used - that is, absolutely nothing.
|
||||||
|
if (continuous) {
|
||||||
|
for (int i = frame; i--;) {
|
||||||
|
if (i <= -1)
|
||||||
|
break;
|
||||||
|
QPixmap l_pixmap = this->get_pixmap(m_reader.read());
|
||||||
|
int l_delay = m_reader.nextImageDelay();
|
||||||
|
movie_frames.append(l_pixmap);
|
||||||
|
movie_delays.append(l_delay);
|
||||||
|
// qDebug() << "appending delay of " << l_delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// qDebug() << "CONT: " << continuous << " MAX: " << max_frames
|
||||||
|
// << " LAST MAX: " << last_max_frames << " FRAME: " << frame;
|
||||||
|
QPixmap f_pixmap = this->get_pixmap(m_reader.read());
|
||||||
|
int f_delay = m_reader.nextImageDelay();
|
||||||
|
|
||||||
|
this->set_frame(f_pixmap);
|
||||||
|
this->show();
|
||||||
|
if (max_frames > 1) {
|
||||||
|
movie_frames.append(f_pixmap);
|
||||||
|
movie_delays.append(f_delay);
|
||||||
|
}
|
||||||
|
else if (max_frames <= 1) {
|
||||||
|
duration = static_duration;
|
||||||
|
play_once = false;
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << "max_frames is <= 1, using static duration";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (duration > 0 && cull_image == true)
|
||||||
|
shfx_timer->start(duration);
|
||||||
|
play();
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << max_frames << "Setting image to " << image_path
|
||||||
|
<< "Time taken to process image:" << actual_time.elapsed();
|
||||||
|
|
||||||
|
actual_time.restart();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharLayer::play()
|
||||||
|
{
|
||||||
|
play_frame_effect(frame);
|
||||||
|
AOLayer::play();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::play()
|
||||||
|
{
|
||||||
|
if (max_frames <= 1) {
|
||||||
|
if (play_once)
|
||||||
|
ticker->start(tick_ms);
|
||||||
|
else
|
||||||
|
this->freeze();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ticker->start(this->get_frame_delay(movie_delays[frame]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::set_play_once(bool p_play_once) { play_once = p_play_once; }
|
||||||
|
void AOLayer::set_cull_image(bool p_cull_image) { cull_image = p_cull_image; }
|
||||||
|
void AOLayer::set_static_duration(int p_static_duration)
|
||||||
|
{
|
||||||
|
static_duration = p_static_duration;
|
||||||
|
}
|
||||||
|
void AOLayer::set_max_duration(int p_max_duration)
|
||||||
|
{
|
||||||
|
max_duration = p_max_duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharLayer::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 CharLayer::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("^");
|
||||||
|
for (const 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 || f_frame < 0) {
|
||||||
|
qDebug() << "Warning: out of bounds" << effects_list[i] << "frame"
|
||||||
|
<< f_frame << "out of" << max_frames << "for" << 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_emote;
|
||||||
|
movie_effects[f_frame].append(effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharLayer::play_frame_effect(int p_frame)
|
||||||
|
{
|
||||||
|
if (p_frame < max_frames) {
|
||||||
|
foreach (QString effect, movie_effects[p_frame]) {
|
||||||
|
if (effect == "shake") {
|
||||||
|
shake();
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << "Attempting to play shake on frame" << frame;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effect == "flash") {
|
||||||
|
flash();
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << "Attempting to play flash on frame" << frame;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effect.startsWith("sfx^")) {
|
||||||
|
QString sfx = effect.section("^", 1);
|
||||||
|
play_sfx(sfx);
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << "Attempting to play sfx" << sfx << "on frame" << frame;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::stop()
|
||||||
|
{
|
||||||
|
// for all intents and purposes, stopping is the same as hiding. at no point
|
||||||
|
// do we want a frozen gif to display
|
||||||
|
this->freeze();
|
||||||
|
this->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::freeze()
|
||||||
|
{
|
||||||
|
// aT nO pOiNt Do We WaNt A fRoZeN gIf To DiSpLaY
|
||||||
|
ticker->stop();
|
||||||
|
preanim_timer->stop();
|
||||||
|
shfx_timer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharLayer::movie_ticker()
|
||||||
|
{
|
||||||
|
AOLayer::movie_ticker();
|
||||||
|
play_frame_effect(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::movie_ticker()
|
||||||
|
{
|
||||||
|
++frame;
|
||||||
|
if ((frame >= max_frames) && (max_frames > 1)) {
|
||||||
|
if (play_once) {
|
||||||
|
if (cull_image)
|
||||||
|
this->stop();
|
||||||
|
else
|
||||||
|
this->freeze();
|
||||||
|
preanim_done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
frame = 0;
|
||||||
|
}
|
||||||
|
// qint64 difference = elapsed - movie_delays[frame];
|
||||||
|
if (frame >= movie_frames.size()) {
|
||||||
|
movie_frames.append(this->get_pixmap(m_reader.read()));
|
||||||
|
movie_delays.append(m_reader.nextImageDelay());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << frame << movie_delays[frame]
|
||||||
|
<< "actual time taken from last frame:" << actual_time.restart();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this->set_frame(movie_frames[frame]);
|
||||||
|
ticker->setInterval(this->get_frame_delay(movie_delays[frame]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharLayer::preanim_done()
|
||||||
|
{
|
||||||
|
if (is_preanim)
|
||||||
|
AOLayer::preanim_done();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::preanim_done()
|
||||||
|
{
|
||||||
|
ticker->stop();
|
||||||
|
preanim_timer->stop();
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOLayer::shfx_timer_done()
|
||||||
|
{
|
||||||
|
this->stop();
|
||||||
|
#ifdef DEBUG_MOVIE
|
||||||
|
qDebug() << "shfx timer signaled done";
|
||||||
|
#endif
|
||||||
|
// signal connected to courtroom object, let it figure out what to do
|
||||||
|
done();
|
||||||
|
}
|
100
src/aomovie.cpp
100
src/aomovie.cpp
@ -1,100 +0,0 @@
|
|||||||
#include "aomovie.h"
|
|
||||||
|
|
||||||
#include "courtroom.h"
|
|
||||||
#include "file_functions.h"
|
|
||||||
#include "misc_functions.h"
|
|
||||||
|
|
||||||
AOMovie::AOMovie(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent)
|
|
||||||
{
|
|
||||||
ao_app = p_ao_app;
|
|
||||||
|
|
||||||
m_movie = new QMovie();
|
|
||||||
m_movie->setCacheMode(QMovie::CacheAll);
|
|
||||||
|
|
||||||
this->setMovie(m_movie);
|
|
||||||
|
|
||||||
timer = new QTimer(this);
|
|
||||||
timer->setTimerType(Qt::PreciseTimer);
|
|
||||||
timer->setSingleShot(true);
|
|
||||||
|
|
||||||
connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int)));
|
|
||||||
connect(timer, SIGNAL(timeout()), this, SLOT(timer_done()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOMovie::set_play_once(bool p_play_once) { play_once = p_play_once; }
|
|
||||||
|
|
||||||
void AOMovie::play(QString p_image, QString p_char, QString p_custom_theme,
|
|
||||||
int duration)
|
|
||||||
{
|
|
||||||
m_movie->stop();
|
|
||||||
|
|
||||||
QString shout_path = p_image;
|
|
||||||
if (!file_exists(p_image)) {
|
|
||||||
QList<QString> pathlist;
|
|
||||||
|
|
||||||
pathlist = {
|
|
||||||
ao_app->get_image_suffix(
|
|
||||||
ao_app->get_character_path(p_char, p_image)), // Character folder
|
|
||||||
ao_app->get_image_suffix(ao_app->get_base_path() + "misc/" +
|
|
||||||
p_custom_theme + "/" + p_image), // Misc path
|
|
||||||
ao_app->get_image_suffix(ao_app->get_custom_theme_path(
|
|
||||||
p_custom_theme, p_image)), // Custom theme path
|
|
||||||
ao_app->get_image_suffix(ao_app->get_theme_path(p_image)), // Theme path
|
|
||||||
ao_app->get_image_suffix(
|
|
||||||
ao_app->get_default_theme_path(p_image)), // Default theme path
|
|
||||||
ao_app->get_image_suffix(
|
|
||||||
ao_app->get_theme_path("placeholder")), // Placeholder path
|
|
||||||
ao_app->get_image_suffix(ao_app->get_default_theme_path(
|
|
||||||
"placeholder")), // Default placeholder path
|
|
||||||
};
|
|
||||||
|
|
||||||
for (QString path : pathlist) {
|
|
||||||
if (file_exists(path)) {
|
|
||||||
shout_path = path;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_movie->setFileName(shout_path);
|
|
||||||
|
|
||||||
if (m_movie->loopCount() == 0)
|
|
||||||
play_once = true;
|
|
||||||
|
|
||||||
this->show();
|
|
||||||
m_movie->start();
|
|
||||||
if (m_movie->frameCount() == 0 && duration > 0)
|
|
||||||
timer->start(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOMovie::stop()
|
|
||||||
{
|
|
||||||
m_movie->stop();
|
|
||||||
this->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOMovie::frame_change(int n_frame)
|
|
||||||
{
|
|
||||||
// If it's a "static movie" (only one frame - png image), we can't change
|
|
||||||
// frames - ignore this function (use timer instead). If the frame didn't reach
|
|
||||||
// the last frame or the movie is continuous, don't stop the movie.
|
|
||||||
if (m_movie->frameCount() == 0 || n_frame < (m_movie->frameCount() - 1) ||
|
|
||||||
!play_once)
|
|
||||||
return;
|
|
||||||
// we need this or else the last frame wont show
|
|
||||||
timer->start(m_movie->nextFrameDelay());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOMovie::timer_done()
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
// signal connected to courtroom object, let it figure out what to do
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOMovie::combo_resize(int w, int h)
|
|
||||||
{
|
|
||||||
QSize f_size(w, h);
|
|
||||||
this->resize(f_size);
|
|
||||||
m_movie->setScaledSize(f_size);
|
|
||||||
}
|
|
132
src/aoscene.cpp
132
src/aoscene.cpp
@ -1,132 +0,0 @@
|
|||||||
#include "aoscene.h"
|
|
||||||
#include "courtroom.h"
|
|
||||||
#include "file_functions.h"
|
|
||||||
|
|
||||||
AOScene::AOScene(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent)
|
|
||||||
{
|
|
||||||
m_parent = parent;
|
|
||||||
ao_app = p_ao_app;
|
|
||||||
m_movie = new QMovie(this);
|
|
||||||
m_movie->setCacheMode(QMovie::CacheAll);
|
|
||||||
last_image = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOScene::set_image(QString p_image)
|
|
||||||
{
|
|
||||||
QString background_path =
|
|
||||||
ao_app->get_image_suffix(ao_app->get_background_path(p_image));
|
|
||||||
if (!file_exists(background_path)) // If image is missing, clear current image
|
|
||||||
{
|
|
||||||
this->clear();
|
|
||||||
this->setMovie(nullptr);
|
|
||||||
|
|
||||||
m_movie->stop();
|
|
||||||
last_image = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file_exists(background_path) || background_path != last_image)
|
|
||||||
{
|
|
||||||
this->clear();
|
|
||||||
this->setMovie(nullptr);
|
|
||||||
|
|
||||||
m_movie->stop();
|
|
||||||
m_movie->setFileName(background_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_movie->isValid() && m_movie->frameCount() > 1) {
|
|
||||||
m_movie->jumpToNextFrame();
|
|
||||||
float scale_factor = static_cast<float>(f_h) /
|
|
||||||
static_cast<float>(m_movie->frameRect().height());
|
|
||||||
// preserve aspect ratio
|
|
||||||
int n_w = static_cast<int>(m_movie->frameRect().width() * scale_factor);
|
|
||||||
int n_h = static_cast<int>(m_movie->frameRect().height() * scale_factor);
|
|
||||||
|
|
||||||
m_movie->setScaledSize(QSize(n_w, n_h));
|
|
||||||
this->resize(m_movie->scaledSize());
|
|
||||||
if (!file_exists(background_path) || background_path != last_image)
|
|
||||||
{
|
|
||||||
this->setMovie(m_movie);
|
|
||||||
m_movie->start();
|
|
||||||
}
|
|
||||||
QLabel::move(x + (f_w - n_w) / 2, y + (f_h - n_h) / 2); // Center
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QPixmap background(background_path);
|
|
||||||
auto transform_mode = Qt::FastTransformation;
|
|
||||||
if (background.height() > f_h) // We are downscaling, use anti-aliasing.
|
|
||||||
transform_mode = Qt::SmoothTransformation;
|
|
||||||
|
|
||||||
background = background.scaledToHeight(f_h, transform_mode);
|
|
||||||
this->resize(background.size());
|
|
||||||
this->setPixmap(background);
|
|
||||||
QLabel::move(
|
|
||||||
x + (f_w - background.width()) / 2,
|
|
||||||
y + (f_h - background.height()) /
|
|
||||||
2); // Always center horizontally, always center vertically
|
|
||||||
}
|
|
||||||
last_image = background_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOScene::set_legacy_desk(QString p_image)
|
|
||||||
{
|
|
||||||
|
|
||||||
QString desk_path =
|
|
||||||
ao_app->get_image_suffix(ao_app->get_background_path(p_image));
|
|
||||||
if (!file_exists(desk_path)) // If image is missing, clear current image
|
|
||||||
{
|
|
||||||
this->clear();
|
|
||||||
this->setMovie(nullptr);
|
|
||||||
|
|
||||||
m_movie->stop();
|
|
||||||
last_image = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_exists(desk_path) && desk_path == last_image)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QPixmap f_desk(desk_path);
|
|
||||||
|
|
||||||
// vanilla desks vary in both width and height. in order to make that work
|
|
||||||
// with viewport rescaling, some INTENSE math is needed.
|
|
||||||
int vp_width = m_parent->width();
|
|
||||||
int vp_height = m_parent->height();
|
|
||||||
|
|
||||||
double h_modifier = vp_height / 192;
|
|
||||||
|
|
||||||
int final_h = static_cast<int>(h_modifier * f_desk.height());
|
|
||||||
|
|
||||||
this->clear();
|
|
||||||
this->setMovie(nullptr);
|
|
||||||
|
|
||||||
m_movie->stop();
|
|
||||||
m_movie->setFileName(desk_path);
|
|
||||||
|
|
||||||
m_movie->setScaledSize(QSize(vp_width, final_h));
|
|
||||||
|
|
||||||
if (m_movie->isValid() && m_movie->frameCount() > 1) {
|
|
||||||
this->setMovie(m_movie);
|
|
||||||
m_movie->start();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this->resize(vp_width, final_h);
|
|
||||||
this->setPixmap(f_desk.scaled(vp_width, final_h));
|
|
||||||
}
|
|
||||||
last_image = desk_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOScene::combo_resize(int w, int h)
|
|
||||||
{
|
|
||||||
QSize f_size(w, h);
|
|
||||||
f_w = w;
|
|
||||||
f_h = h;
|
|
||||||
this->resize(f_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOScene::move(int ax, int ay)
|
|
||||||
{
|
|
||||||
x = ax;
|
|
||||||
y = ay;
|
|
||||||
QLabel::move(x, y);
|
|
||||||
}
|
|
@ -43,21 +43,22 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
|
|||||||
ui_background = new AOImage(this, ao_app);
|
ui_background = new AOImage(this, ao_app);
|
||||||
|
|
||||||
ui_viewport = new QWidget(this);
|
ui_viewport = new QWidget(this);
|
||||||
ui_vp_background = new AOScene(ui_viewport, ao_app);
|
ui_vp_background = new BackgroundLayer(ui_viewport, ao_app);
|
||||||
ui_vp_speedlines = new AOMovie(ui_viewport, ao_app);
|
ui_vp_speedlines = new ForegroundLayer(ui_viewport, ao_app);
|
||||||
ui_vp_speedlines->set_play_once(false);
|
ui_vp_player_char = new CharLayer(ui_viewport, ao_app);
|
||||||
ui_vp_player_char = new AOCharMovie(ui_viewport, ao_app);
|
ui_vp_sideplayer_char = new CharLayer(ui_viewport, ao_app);
|
||||||
ui_vp_sideplayer_char = new AOCharMovie(ui_viewport, ao_app);
|
|
||||||
ui_vp_sideplayer_char->hide();
|
ui_vp_sideplayer_char->hide();
|
||||||
ui_vp_desk = new AOScene(ui_viewport, ao_app);
|
ui_vp_desk = new BackgroundLayer(ui_viewport, ao_app);
|
||||||
ui_vp_legacy_desk = new AOScene(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_evidence_display = new AOEvidenceDisplay(ui_viewport, ao_app);
|
||||||
|
|
||||||
ui_vp_chatbox = new AOImage(this, ao_app);
|
ui_vp_chatbox = new AOImage(this, ao_app);
|
||||||
ui_vp_showname = new QLabel(ui_vp_chatbox);
|
ui_vp_showname = new QLabel(ui_vp_chatbox);
|
||||||
ui_vp_showname->setAlignment(Qt::AlignLeft);
|
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_chat_arrow->set_play_once(false);
|
||||||
|
|
||||||
ui_vp_message = new QTextEdit(this);
|
ui_vp_message = new QTextEdit(this);
|
||||||
@ -66,14 +67,13 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
|
|||||||
ui_vp_message->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
ui_vp_message->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
ui_vp_message->setReadOnly(true);
|
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->set_play_once(false);
|
||||||
ui_vp_testimony->setAttribute(Qt::WA_TransparentForMouseEvents);
|
ui_vp_testimony->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
ui_vp_effect = new AOMovie(this, ao_app);
|
ui_vp_wtce = new InterjectionLayer(this, ao_app);
|
||||||
ui_vp_effect->setAttribute(Qt::WA_TransparentForMouseEvents);
|
ui_vp_wtce->set_play_once(true);
|
||||||
ui_vp_wtce = new AOMovie(this, ao_app);
|
|
||||||
ui_vp_wtce->setAttribute(Qt::WA_TransparentForMouseEvents);
|
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_vp_objection->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
ui_ic_chatlog = new QTextEdit(this);
|
ui_ic_chatlog = new QTextEdit(this);
|
||||||
@ -113,7 +113,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
|
|||||||
ui_music_list->setUniformRowHeights(true);
|
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->set_play_once(false);
|
||||||
ui_music_display->setAttribute(Qt::WA_TransparentForMouseEvents);
|
ui_music_display->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
@ -271,6 +271,8 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
|
|||||||
connect(keepalive_timer, SIGNAL(timeout()), this, SLOT(ping_server()));
|
connect(keepalive_timer, SIGNAL(timeout()), this, SLOT(ping_server()));
|
||||||
|
|
||||||
connect(ui_vp_objection, SIGNAL(done()), this, SLOT(objection_done()));
|
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(done()), this, SLOT(preanim_done()));
|
||||||
connect(ui_vp_player_char, SIGNAL(shake()), this, SLOT(do_screenshake()));
|
connect(ui_vp_player_char, SIGNAL(shake()), this, SLOT(do_screenshake()));
|
||||||
connect(ui_vp_player_char, SIGNAL(flash()), this, SLOT(do_flash()));
|
connect(ui_vp_player_char, SIGNAL(flash()), this, SLOT(do_flash()));
|
||||||
@ -532,13 +534,8 @@ void Courtroom::set_widgets()
|
|||||||
ui_vp_desk->move(0, 0);
|
ui_vp_desk->move(0, 0);
|
||||||
ui_vp_desk->combo_resize(ui_viewport->width(), ui_viewport->height());
|
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;
|
double y_modifier = 147.0 / 192.0;
|
||||||
int final_y = static_cast<int>(y_modifier * ui_viewport->height());
|
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->move(0, 0);
|
||||||
ui_vp_evidence_display->combo_resize(ui_viewport->width(),
|
ui_vp_evidence_display->combo_resize(ui_viewport->width(),
|
||||||
@ -553,11 +550,14 @@ void Courtroom::set_widgets()
|
|||||||
ui_vp_chat_arrow->hide();
|
ui_vp_chat_arrow->hide();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ui_vp_chat_arrow->move(design_ini_result.x, design_ini_result.y);
|
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,
|
ui_vp_chat_arrow->combo_resize(design_ini_result.width, design_ini_result.height);
|
||||||
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->move(ui_viewport->x(), ui_viewport->y());
|
||||||
ui_vp_testimony->combo_resize(ui_viewport->width(), ui_viewport->height());
|
ui_vp_testimony->combo_resize(ui_viewport->width(), ui_viewport->height());
|
||||||
|
|
||||||
@ -659,18 +659,16 @@ void Courtroom::set_widgets()
|
|||||||
ui_music_display->combo_resize(design_ini_result.width,
|
ui_music_display->combo_resize(design_ini_result.width,
|
||||||
design_ini_result.height);
|
design_ini_result.height);
|
||||||
}
|
}
|
||||||
|
ui_music_display->load_image("music_display", "");
|
||||||
ui_music_display->play("music_display");
|
|
||||||
ui_music_display->set_play_once(false);
|
|
||||||
|
|
||||||
if (is_ao2_bg) {
|
if (is_ao2_bg) {
|
||||||
set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message");
|
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");
|
set_size_and_pos(ui_ic_chat_name, "ao2_ic_chat_name");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set_size_and_pos(ui_ic_chat_message, "ic_chat_message");
|
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");
|
set_size_and_pos(ui_ic_chat_name, "ic_chat_name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1120,6 +1118,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)
|
void Courtroom::set_taken(int n_char, bool p_taken)
|
||||||
{
|
{
|
||||||
if (n_char >= char_list.size()) {
|
if (n_char >= char_list.size()) {
|
||||||
@ -1219,11 +1235,11 @@ void Courtroom::set_background(QString p_background, bool display)
|
|||||||
is_ao2_bg = true;
|
is_ao2_bg = true;
|
||||||
|
|
||||||
if (is_ao2_bg) {
|
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");
|
set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message");
|
||||||
}
|
}
|
||||||
else {
|
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");
|
set_size_and_pos(ui_ic_chat_message, "ic_chat_message");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1403,6 +1419,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
|
if (m_cid != -1) // there is no name at char_list -1, and we crash if we try
|
||||||
// to find one
|
// to find one
|
||||||
@ -1838,7 +1860,8 @@ void Courtroom::on_chat_return_pressed()
|
|||||||
packet_contents.append(ui_additive->isChecked() ? "1" : "0");
|
packet_contents.append(ui_additive->isChecked() ? "1" : "0");
|
||||||
}
|
}
|
||||||
if (ao_app->effects_enabled) {
|
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 =
|
QString p_effect =
|
||||||
ao_app->read_char_ini(current_char, "effects", "Options");
|
ao_app->read_char_ini(current_char, "effects", "Options");
|
||||||
packet_contents.append(effect + "|" + p_effect + "|" + fx_sound);
|
packet_contents.append(effect + "|" + p_effect + "|" + fx_sound);
|
||||||
@ -1919,12 +1942,9 @@ void Courtroom::chatmessage_enqueue(QStringList p_contents)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Record the log I/O, log files should be accurate.
|
// Record the log I/O, log files should be accurate.
|
||||||
log_chatmessage(p_contents[MESSAGE], f_char_id, p_contents[SHOWNAME], p_contents[TEXT_COLOR].toInt());
|
// If desynced logs are on, display the log IC immediately.
|
||||||
if (ao_app->is_desyncrhonized_logs_enabled()) {
|
LogMode log_mode = ao_app->is_desyncrhonized_logs_enabled() ? DISPLAY_AND_IO : IO_ONLY;
|
||||||
// Display the logs immediately.
|
log_chatmessage(p_contents[MESSAGE], f_char_id, p_contents[SHOWNAME], p_contents[TEXT_COLOR].toInt(), log_mode);
|
||||||
display_log_chatmessage(p_contents[MESSAGE], f_char_id, p_contents[SHOWNAME], p_contents[TEXT_COLOR].toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send this boi into the queue
|
// Send this boi into the queue
|
||||||
chatmessage_queue.enqueue(p_contents);
|
chatmessage_queue.enqueue(p_contents);
|
||||||
|
|
||||||
@ -1939,11 +1959,12 @@ void Courtroom::chatmessage_enqueue(QStringList p_contents)
|
|||||||
void Courtroom::chatmessage_dequeue()
|
void Courtroom::chatmessage_dequeue()
|
||||||
{
|
{
|
||||||
// Chat stopped being processed, indicate that the user can post their message now.
|
// Chat stopped being processed, indicate that the user can post their message now.
|
||||||
QString f_char = m_chatmessage[CHAR_NAME];
|
QString f_custom_theme;
|
||||||
QString f_custom_theme = ao_app->get_char_shouts(f_char);
|
if (ao_app->is_customchat_enabled()) {
|
||||||
ui_vp_chat_arrow->play(
|
QString f_char = m_chatmessage[CHAR_NAME];
|
||||||
"chat_arrow", f_char,
|
f_custom_theme = ao_app->get_chat(f_char);
|
||||||
f_custom_theme);
|
}
|
||||||
|
ui_vp_chat_arrow->load_image("chat_arrow", f_custom_theme);
|
||||||
|
|
||||||
// Nothing to parse in the queue
|
// Nothing to parse in the queue
|
||||||
if (chatmessage_queue.isEmpty())
|
if (chatmessage_queue.isEmpty())
|
||||||
@ -1975,7 +1996,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.
|
||||||
display_log_chatmessage(m_chatmessage[MESSAGE], m_chatmessage[CHAR_ID].toInt(), m_chatmessage[SHOWNAME], m_chatmessage[TEXT_COLOR].toInt());
|
log_chatmessage(m_chatmessage[MESSAGE], m_chatmessage[CHAR_ID].toInt(), m_chatmessage[SHOWNAME], m_chatmessage[TEXT_COLOR].toInt(), DISPLAY_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the callwords for this message
|
// Process the callwords for this message
|
||||||
@ -1994,7 +2015,7 @@ 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)
|
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
|
// Display name will use the showname
|
||||||
QString f_displayname = f_showname;
|
QString f_displayname = f_showname;
|
||||||
@ -2058,95 +2079,17 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
log_ic_text(f_char, f_displayname, shout_message, tr("shouts"));
|
switch (f_log_mode) {
|
||||||
}
|
case IO_ONLY:
|
||||||
|
log_ic_text(f_char, f_displayname, shout_message, tr("shouts"));
|
||||||
// Obtain evidence ID we're trying to work with
|
break;
|
||||||
int f_evi_id = m_chatmessage[EVIDENCE_ID].toInt();
|
case DISPLAY_AND_IO:
|
||||||
// If the evidence ID is in the valid range
|
log_ic_text(f_char, f_displayname, shout_message, tr("shouts"));
|
||||||
if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) {
|
[[fallthrough]];
|
||||||
// Obtain the evidence name
|
case DISPLAY_ONLY:
|
||||||
QString f_evi_name = local_evidence_list.at(f_evi_id - 1).name;
|
append_ic_text(shout_message, f_displayname, tr("shouts"));
|
||||||
// Add the message to the logs file
|
break;
|
||||||
log_ic_text(f_showname, f_displayname, f_evi_name,
|
|
||||||
tr("has presented evidence"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If our current message is a blankpost, the chat log isn't empty, the chat log's last message is a blank post, and the blankpost's showname is the same as ours
|
|
||||||
if (f_message.isEmpty() && !ic_chatlog_history.isEmpty() && ic_chatlog_history.last().get_message().isEmpty() && ic_chatlog_history.last().get_showname() == f_displayname)
|
|
||||||
return; // Skip adding message
|
|
||||||
|
|
||||||
// Add the message to the logs file
|
|
||||||
log_ic_text(f_showname, f_displayname, f_message, "",
|
|
||||||
f_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Courtroom::display_log_chatmessage(QString f_message, int f_char_id, QString f_showname, int f_color)
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
append_ic_text(shout_message, f_displayname, tr("shouts"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain evidence ID we're trying to work with
|
// Obtain evidence ID we're trying to work with
|
||||||
@ -2155,19 +2098,35 @@ void Courtroom::display_log_chatmessage(QString f_message, int f_char_id, QStrin
|
|||||||
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
|
||||||
QString f_evi_name = local_evidence_list.at(f_evi_id - 1).name;
|
QString f_evi_name = local_evidence_list.at(f_evi_id - 1).name;
|
||||||
// Append the message to the IC chatlogs in client
|
switch (f_log_mode) {
|
||||||
append_ic_text(f_evi_name, f_displayname, tr("has presented evidence"));
|
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 our current message is a blankpost, the chat log isn't empty, the chat log's last message is a blank post, and the blankpost's showname is the same as ours
|
// 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() && last_ic_message == f_displayname + ":")
|
if (!f_message.isEmpty() ||
|
||||||
return; // Skip adding message
|
ic_chatlog_history.isEmpty() || ic_chatlog_history.last().get_message() != "") {
|
||||||
|
switch (f_log_mode) {
|
||||||
last_ic_message = f_displayname + ":" + f_message;
|
case IO_ONLY:
|
||||||
// Append the message to the IC chatlogs in client
|
log_ic_text(f_showname, f_displayname, f_message, "",f_color);
|
||||||
append_ic_text(f_message, f_displayname, "",
|
break;
|
||||||
f_color);
|
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()
|
bool Courtroom::handle_objection()
|
||||||
@ -2184,64 +2143,75 @@ bool Courtroom::handle_objection()
|
|||||||
objection_mod = m_chatmessage[OBJECTION_MOD].toInt();
|
objection_mod = m_chatmessage[OBJECTION_MOD].toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString f_char = m_chatmessage[CHAR_NAME];
|
if (is_ao2_bg) {
|
||||||
QString f_custom_theme = ao_app->get_char_shouts(f_char);
|
set_size_and_pos(ui_vp_chatbox, "ao2_chatbox", m_chatmessage[CHAR_NAME]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set_size_and_pos(ui_vp_chatbox, "chatbox", m_chatmessage[CHAR_NAME]);
|
||||||
|
}
|
||||||
|
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 an objection is used
|
||||||
if (objection_mod <= 4 && objection_mod >= 1) {
|
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) {
|
switch (objection_mod) {
|
||||||
case 1:
|
case 1:
|
||||||
ui_vp_objection->play("holdit_bubble", f_char, f_custom_theme, 724);
|
filename = "holdit_bubble";
|
||||||
objection_player->play("holdit", f_char, f_custom_theme);
|
objection_player->play("holdit", m_chatmessage[CHAR_NAME],
|
||||||
shout_message = ao_app->read_char_ini(f_char, "holdit_message", "Shouts");
|
ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
|
||||||
if (shout_message == "")
|
|
||||||
shout_message = tr("HOLD IT!");
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ui_vp_objection->play("objection_bubble", f_char, f_custom_theme, 724);
|
filename = "objection_bubble";
|
||||||
objection_player->play("objection", f_char, f_custom_theme);
|
objection_player->play("objection", m_chatmessage[CHAR_NAME],
|
||||||
shout_message = ao_app->read_char_ini(f_char, "objection_message", "Shouts");
|
ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
|
||||||
if (shout_message == "")
|
|
||||||
shout_message = tr("OBJECTION!");
|
|
||||||
if (ao_app->objection_stop_music())
|
if (ao_app->objection_stop_music())
|
||||||
music_player->stop();
|
music_player->stop();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
ui_vp_objection->play("takethat_bubble", f_char, f_custom_theme, 724);
|
filename = "takethat_bubble";
|
||||||
objection_player->play("takethat", f_char, f_custom_theme);
|
objection_player->play("takethat", m_chatmessage[CHAR_NAME],
|
||||||
shout_message = ao_app->read_char_ini(f_char, "takethat_message", "Shouts");
|
ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
|
||||||
if (shout_message == "")
|
|
||||||
shout_message = tr("TAKE THAT!");
|
|
||||||
break;
|
break;
|
||||||
// case 4 is AO2 only
|
// case 4 is AO2 only
|
||||||
case 4:
|
case 4:
|
||||||
if (custom_objection != "") {
|
if (custom_objection != "") {
|
||||||
ui_vp_objection->play("custom_objections/" + custom_objection, f_char,
|
filename = "custom_objections/" + custom_objection;
|
||||||
f_custom_theme, shout_stay_time);
|
objection_player->play(
|
||||||
objection_player->play("custom_objections/" +
|
"custom_objections/" + custom_objection.split('.')[0],
|
||||||
custom_objection.split('.')[0],
|
m_chatmessage[CHAR_NAME],
|
||||||
f_char, f_custom_theme);
|
ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
|
||||||
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 {
|
else {
|
||||||
ui_vp_objection->play("custom", f_char, f_custom_theme,
|
filename = "custom";
|
||||||
shout_stay_time);
|
objection_player->play(
|
||||||
objection_player->play("custom", f_char, f_custom_theme);
|
"custom", m_chatmessage[CHAR_NAME],
|
||||||
shout_message = ao_app->read_char_ini(f_char, "custom_message", "Shouts");
|
ao_app->get_char_shouts(m_chatmessage[CHAR_NAME]));
|
||||||
if (shout_message == "")
|
|
||||||
shout_message = tr("CUSTOM OBJECTION!");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
m_chatmessage[EMOTE_MOD] = 1;
|
||||||
}
|
}
|
||||||
|
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.
|
sfx_player->clear(); // Objection played! Cut all sfx.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
display_character();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Courtroom::effect_done()
|
||||||
|
{
|
||||||
|
ui_vp_effect->stop();
|
||||||
|
ui_vp_wtce->stop();
|
||||||
|
}
|
||||||
|
|
||||||
void Courtroom::display_character()
|
void Courtroom::display_character()
|
||||||
{
|
{
|
||||||
// Stop all previously playing animations, effects etc.
|
// Stop all previously playing animations, effects etc.
|
||||||
@ -2333,26 +2303,6 @@ void Courtroom::display_pair_character(QString other_charid, QString other_offse
|
|||||||
ui_vp_sideplayer_char->move(ui_viewport->width() * offset_x / 100,
|
ui_vp_sideplayer_char->move(ui_viewport->width() * offset_x / 100,
|
||||||
ui_viewport->height() * offset_y / 100);
|
ui_viewport->height() * offset_y / 100);
|
||||||
|
|
||||||
// Split the charid according to the ^ to determine if we have "ordering" info
|
|
||||||
QStringList args = 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: // Our character is in front
|
|
||||||
ui_vp_sideplayer_char->stackUnder(ui_vp_player_char);
|
|
||||||
break;
|
|
||||||
case 1: // Our character is behind
|
|
||||||
ui_vp_player_char->stackUnder(ui_vp_sideplayer_char);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flip the pair character
|
// Flip the pair character
|
||||||
if (ao_app->flipping_enabled && m_chatmessage[OTHER_FLIP].toInt() == 1)
|
if (ao_app->flipping_enabled && m_chatmessage[OTHER_FLIP].toInt() == 1)
|
||||||
ui_vp_sideplayer_char->set_flipped(true);
|
ui_vp_sideplayer_char->set_flipped(true);
|
||||||
@ -2360,10 +2310,11 @@ void Courtroom::display_pair_character(QString other_charid, QString other_offse
|
|||||||
ui_vp_sideplayer_char->set_flipped(false);
|
ui_vp_sideplayer_char->set_flipped(false);
|
||||||
|
|
||||||
// Play the other pair character's idle animation
|
// Play the other pair character's idle animation
|
||||||
ui_vp_sideplayer_char->play_idle(m_chatmessage[OTHER_NAME],
|
QString filename = "(a)" + m_chatmessage[OTHER_EMOTE];
|
||||||
m_chatmessage[OTHER_EMOTE]);
|
ui_vp_sideplayer_char->load_image(filename, m_chatmessage[OTHER_NAME],
|
||||||
|
0, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Courtroom::handle_emote_mod(int emote_mod, bool p_immediate)
|
void Courtroom::handle_emote_mod(int emote_mod, bool p_immediate)
|
||||||
@ -2494,7 +2445,11 @@ void Courtroom::do_flash()
|
|||||||
|
|
||||||
QString f_char = m_chatmessage[CHAR_NAME];
|
QString f_char = m_chatmessage[CHAR_NAME];
|
||||||
QString f_custom_theme = ao_app->get_char_shouts(f_char);
|
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,
|
void Courtroom::do_effect(QString fx_name, QString fx_sound, QString p_char,
|
||||||
@ -2511,12 +2466,17 @@ 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
|
// Only check if effects are disabled after playing the sound if it exists
|
||||||
if (!ao_app->is_effects_enabled())
|
if (!ao_app->is_effects_enabled())
|
||||||
return;
|
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(
|
ui_vp_effect->set_play_once(
|
||||||
false); // The effects themselves dictate whether or not they're looping.
|
false); // The effects themselves dictate whether or not they're looping.
|
||||||
// Static effects will linger.
|
// Static effects will linger.
|
||||||
ui_vp_effect->play(effect); // It will set_play_once to true if the filepath
|
ui_vp_effect->set_static_duration(0);
|
||||||
// provided is not designed to loop more than once
|
ui_vp_effect->set_max_duration(0);
|
||||||
|
ui_vp_effect->load_image(effect, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Courtroom::play_char_sfx(QString sfx_name)
|
void Courtroom::play_char_sfx(QString sfx_name)
|
||||||
@ -2530,7 +2490,7 @@ 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);
|
||||||
@ -2562,23 +2522,28 @@ void Courtroom::initialize_chatbox()
|
|||||||
QString chatbox = ao_app->get_chat(customchar);
|
QString chatbox = ao_app->get_chat(customchar);
|
||||||
|
|
||||||
if (chatbox != "" && ao_app->is_customchat_enabled()) {
|
if (chatbox != "" && ao_app->is_customchat_enabled()) {
|
||||||
chatbox_path = ao_app->get_base_path() + "misc/" + chatbox + "/chat";
|
chatbox_path = ao_app->get_theme_path("misc/" + chatbox + "/chat");
|
||||||
if (!ui_vp_chatbox->set_chatbox(chatbox_path))
|
if (!ui_vp_chatbox->set_chatbox(chatbox_path)) {
|
||||||
ui_vp_chatbox->set_chatbox(chatbox_path + "box");
|
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
|
// This should probably be called only if any change from the last chat
|
||||||
// arrow was actually detected.
|
// arrow was actually detected.
|
||||||
pos_size_type design_ini_result = ao_app->get_element_dimensions(
|
if (current_misc != last_misc) {
|
||||||
"chat_arrow", "courtroom_design.ini", customchar);
|
pos_size_type design_ini_result = ao_app->get_element_dimensions(
|
||||||
if (design_ini_result.width < 0 || design_ini_result.height < 0) {
|
"chat_arrow", "courtroom_design.ini", customchar);
|
||||||
qDebug() << "W: could not find \"chat_arrow\" in courtroom_design.ini";
|
if (design_ini_result.width < 0 || design_ini_result.height < 0) {
|
||||||
ui_vp_chat_arrow->hide();
|
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);
|
else {
|
||||||
ui_vp_chat_arrow->combo_resize(design_ini_result.width,
|
ui_vp_chat_arrow->move(design_ini_result.x + ui_vp_chatbox->x(), design_ini_result.y + ui_vp_chatbox->y());
|
||||||
design_ini_result.height);
|
ui_vp_chat_arrow->combo_resize(design_ini_result.width,
|
||||||
|
design_ini_result.height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos_size_type default_width = ao_app->get_element_dimensions(
|
pos_size_type default_width = ao_app->get_element_dimensions(
|
||||||
@ -2686,39 +2651,41 @@ void Courtroom::handle_ic_speaking()
|
|||||||
if (emote_mod == 5 || emote_mod == 6) {
|
if (emote_mod == 5 || emote_mod == 6) {
|
||||||
// Hide the desks
|
// Hide the desks
|
||||||
ui_vp_desk->hide();
|
ui_vp_desk->hide();
|
||||||
ui_vp_legacy_desk->hide();
|
|
||||||
|
|
||||||
// Obtain character information for our character
|
// Obtain character information for our character
|
||||||
QString f_char = m_chatmessage[CHAR_NAME];
|
QString filename;
|
||||||
QString f_custom_theme = ao_app->get_char_shouts(f_char);
|
|
||||||
// I still hate this hardcoding. If we're on pos pro, hlp and wit, use prosecution_speedlines. Otherwise, defense_speedlines.
|
// 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")
|
if (side == "pro" || side == "hlp" || side == "wit")
|
||||||
ui_vp_speedlines->play("prosecution_speedlines", f_char, f_custom_theme);
|
filename = "prosecution_speedlines";
|
||||||
else
|
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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this is a talking color (white text, etc.)
|
// Check if this is a talking color (white text, etc.)
|
||||||
color_is_talking =
|
color_is_talking =
|
||||||
color_markdown_talking_list.at(m_chatmessage[TEXT_COLOR].toInt());
|
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, and our state isn't already talking
|
||||||
if (color_is_talking && text_state == 1 &&
|
if (color_is_talking && text_state == 1 &&
|
||||||
anim_state < 2)
|
anim_state < 2)
|
||||||
{
|
{
|
||||||
// Stop the previous animation and play the talking animation
|
// Stop the previous animation and play the talking animation
|
||||||
ui_vp_player_char->stop();
|
ui_vp_player_char->stop();
|
||||||
ui_vp_player_char->play_talking(m_chatmessage[CHAR_NAME],
|
ui_vp_player_char->set_play_once(false);
|
||||||
m_chatmessage[EMOTE]);
|
filename = "(b)" + m_chatmessage[EMOTE];
|
||||||
|
ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, false);
|
||||||
// Set the anim state accordingly
|
// Set the anim state accordingly
|
||||||
anim_state = 2;
|
anim_state = 2;
|
||||||
}
|
}
|
||||||
else if (anim_state < 3)
|
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
|
// Stop the previous animation and play the idle animation
|
||||||
ui_vp_player_char->stop();
|
ui_vp_player_char->stop();
|
||||||
ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME],
|
ui_vp_player_char->set_play_once(false);
|
||||||
m_chatmessage[EMOTE]);
|
filename = "(a)" + m_chatmessage[EMOTE];
|
||||||
|
ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, false);
|
||||||
// Set the anim state accordingly
|
// Set the anim state accordingly
|
||||||
anim_state = 3;
|
anim_state = 3;
|
||||||
}
|
}
|
||||||
@ -3117,7 +3084,6 @@ void Courtroom::play_preanim(bool immediate)
|
|||||||
{
|
{
|
||||||
QString f_char = m_chatmessage[CHAR_NAME];
|
QString f_char = m_chatmessage[CHAR_NAME];
|
||||||
QString f_preanim = m_chatmessage[PRE_EMOTE];
|
QString f_preanim = m_chatmessage[PRE_EMOTE];
|
||||||
|
|
||||||
// all time values in char.inis are multiplied by a constant(time_mod) to get
|
// all time values in char.inis are multiplied by a constant(time_mod) to get
|
||||||
// the actual time
|
// the actual time
|
||||||
int ao2_duration = ao_app->get_ao2_preanim_duration(f_char, f_preanim);
|
int ao2_duration = ao_app->get_ao2_preanim_duration(f_char, f_preanim);
|
||||||
@ -3143,8 +3109,9 @@ void Courtroom::play_preanim(bool immediate)
|
|||||||
qDebug() << "W: could not find " + anim_to_find;
|
qDebug() << "W: could not find " + anim_to_find;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ui_vp_player_char->set_static_duration(preanim_duration);
|
||||||
ui_vp_player_char->play_pre(f_char, f_preanim, 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)
|
if (immediate)
|
||||||
anim_state = 4;
|
anim_state = 4;
|
||||||
@ -3161,6 +3128,7 @@ void Courtroom::play_preanim(bool immediate)
|
|||||||
void Courtroom::preanim_done()
|
void Courtroom::preanim_done()
|
||||||
{
|
{
|
||||||
anim_state = 1;
|
anim_state = 1;
|
||||||
|
qDebug() << "preanim over, anim_state set to 1";
|
||||||
handle_ic_speaking();
|
handle_ic_speaking();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3232,6 +3200,8 @@ void Courtroom::start_chat_ticking()
|
|||||||
|
|
||||||
// means text is currently ticking
|
// means text is currently ticking
|
||||||
text_state = 1;
|
text_state = 1;
|
||||||
|
|
||||||
|
c_played = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Courtroom::chat_tick()
|
void Courtroom::chat_tick()
|
||||||
@ -3243,13 +3213,30 @@ void Courtroom::chat_tick()
|
|||||||
|
|
||||||
// Due to our new text speed system, we always need to stop the timer now.
|
// Due to our new text speed system, we always need to stop the timer now.
|
||||||
chat_tick_timer->stop();
|
chat_tick_timer->stop();
|
||||||
|
ui_vp_player_char->set_static_duration(0);
|
||||||
|
QString filename;
|
||||||
|
|
||||||
if (tick_pos >= f_message.size()) {
|
if (tick_pos >= f_message.size()) {
|
||||||
text_state = 2;
|
text_state = 2;
|
||||||
if (anim_state < 3) {
|
if (anim_state < 3) {
|
||||||
anim_state = 3;
|
QStringList c_paths = {
|
||||||
ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME],
|
ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)" + m_chatmessage[EMOTE])),
|
||||||
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_char;
|
||||||
QString f_custom_theme;
|
QString f_custom_theme;
|
||||||
@ -3257,7 +3244,11 @@ void Courtroom::chat_tick()
|
|||||||
f_char = m_chatmessage[CHAR_NAME];
|
f_char = m_chatmessage[CHAR_NAME];
|
||||||
f_custom_theme = ao_app->get_chat(f_char);
|
f_custom_theme = ao_app->get_chat(f_char);
|
||||||
}
|
}
|
||||||
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) {
|
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));
|
f_message_filtered = f_message_filtered.replace("$c" + QString::number(c), char_color_rgb_list.at(c).name(QColor::HexRgb));
|
||||||
}
|
}
|
||||||
@ -3453,16 +3444,20 @@ void Courtroom::chat_tick()
|
|||||||
// to avoid interrupting a non-interrupted preanim)
|
// to avoid interrupting a non-interrupted preanim)
|
||||||
{
|
{
|
||||||
ui_vp_player_char->stop();
|
ui_vp_player_char->stop();
|
||||||
ui_vp_player_char->play_talking(m_chatmessage[CHAR_NAME],
|
ui_vp_player_char->set_play_once(false);
|
||||||
m_chatmessage[EMOTE]);
|
filename = "(b)" + m_chatmessage[EMOTE];
|
||||||
|
ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
|
||||||
|
false);
|
||||||
anim_state = 2;
|
anim_state = 2;
|
||||||
}
|
}
|
||||||
else if (!color_is_talking && anim_state < 3 &&
|
else if (!color_is_talking && anim_state < 3 &&
|
||||||
anim_state != 3) // Set it to idle as we're not on that already
|
anim_state != 3) // Set it to idle as we're not on that already
|
||||||
{
|
{
|
||||||
ui_vp_player_char->stop();
|
ui_vp_player_char->stop();
|
||||||
ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME],
|
ui_vp_player_char->set_play_once(false);
|
||||||
m_chatmessage[EMOTE]);
|
filename = "(a)" + m_chatmessage[EMOTE];
|
||||||
|
ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0,
|
||||||
|
false);
|
||||||
anim_state = 3;
|
anim_state = 3;
|
||||||
}
|
}
|
||||||
// Continue ticking
|
// Continue ticking
|
||||||
@ -3547,19 +3542,15 @@ void Courtroom::set_scene(QString f_desk_mod, QString f_side)
|
|||||||
f_background = f_side;
|
f_background = f_side;
|
||||||
f_desk_image = f_side + "_overlay";
|
f_desk_image = f_side + "_overlay";
|
||||||
}
|
}
|
||||||
|
ui_vp_background->load_image(f_background);
|
||||||
ui_vp_background->set_image(f_background);
|
ui_vp_desk->load_image(f_desk_image);
|
||||||
ui_vp_desk->set_image(f_desk_image);
|
|
||||||
ui_vp_legacy_desk->set_legacy_desk(f_desk_image);
|
|
||||||
|
|
||||||
if (f_desk_mod == "0" ||
|
if (f_desk_mod == "0" ||
|
||||||
(f_desk_mod != "1" &&
|
(f_desk_mod != "1" &&
|
||||||
(f_side == "jud" || f_side == "hld" || f_side == "hlp"))) {
|
(f_side == "jud" || f_side == "hld" || f_side == "hlp"))) {
|
||||||
ui_vp_desk->hide();
|
ui_vp_desk->hide();
|
||||||
ui_vp_legacy_desk->hide();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ui_vp_legacy_desk->hide();
|
|
||||||
ui_vp_desk->show();
|
ui_vp_desk->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3707,31 +3698,40 @@ void Courtroom::handle_song(QStringList *p_contents)
|
|||||||
void Courtroom::handle_wtce(QString p_wtce, int variant)
|
void Courtroom::handle_wtce(QString p_wtce, int variant)
|
||||||
{
|
{
|
||||||
QString sfx_file = "courtroom_sounds.ini";
|
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
|
// witness testimony
|
||||||
if (p_wtce == "testimony1") {
|
if (p_wtce == "testimony1") {
|
||||||
sfx_player->play(ao_app->get_sfx("witness_testimony"));
|
sfx_name = "witness_testimony";
|
||||||
ui_vp_wtce->play("witnesstestimony", "", "", 1500);
|
filename = "witnesstestimony";
|
||||||
ui_vp_testimony->play("testimony");
|
ui_vp_testimony->load_image("testimony", "");
|
||||||
}
|
}
|
||||||
// cross examination
|
// cross examination
|
||||||
else if (p_wtce == "testimony2") {
|
else if (p_wtce == "testimony2") {
|
||||||
sfx_player->play(ao_app->get_sfx("cross_examination"));
|
sfx_name = "cross_examination";
|
||||||
ui_vp_wtce->play("crossexamination", "", "", 1500);
|
filename = "crossexamination";
|
||||||
ui_vp_testimony->stop();
|
ui_vp_testimony->stop();
|
||||||
}
|
}
|
||||||
else if (p_wtce == "judgeruling") {
|
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) {
|
if (variant == 0) {
|
||||||
sfx_player->play(ao_app->get_sfx("not_guilty"));
|
sfx_name = "not_guilty";
|
||||||
ui_vp_wtce->play("notguilty", "", "", 3000);
|
filename = "notguilty";
|
||||||
ui_vp_testimony->stop();
|
ui_vp_testimony->stop();
|
||||||
}
|
}
|
||||||
else if (variant == 1) {
|
else if (variant == 1) {
|
||||||
sfx_player->play(ao_app->get_sfx("guilty"));
|
sfx_name = "guilty";
|
||||||
ui_vp_wtce->play("guilty", "", "", 3000);
|
filename = "guilty";
|
||||||
ui_vp_testimony->stop();
|
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)
|
void Courtroom::set_hp_bar(int p_bar, int p_state)
|
||||||
@ -4954,18 +4954,18 @@ void Courtroom::set_text_color_dropdown()
|
|||||||
QColor color =
|
QColor color =
|
||||||
ao_app->get_chat_color("c" + QString::number(c), current_char);
|
ao_app->get_chat_color("c" + QString::number(c), current_char);
|
||||||
color_rgb_list.append(color);
|
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));
|
"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));
|
"c" + QString::number(c) + "_end", current_char));
|
||||||
color_markdown_remove_list.append(
|
color_markdown_remove_list.append(
|
||||||
ao_app->get_chat_markdown("c" + QString::number(c) + "_remove",
|
ao_app->get_chat_markup("c" + QString::number(c) + "_remove",
|
||||||
current_char) == "1");
|
current_char) == "1");
|
||||||
color_markdown_talking_list.append(
|
color_markdown_talking_list.append(
|
||||||
ao_app->get_chat_markdown("c" + QString::number(c) + "_talking",
|
ao_app->get_chat_markup("c" + QString::number(c) + "_talking",
|
||||||
current_char) != "0");
|
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);
|
"c" + QString::number(c) + "_name", current_char);
|
||||||
if (color_name.isEmpty()) // Not defined
|
if (color_name.isEmpty()) // Not defined
|
||||||
{
|
{
|
||||||
|
@ -65,6 +65,16 @@ QString AOApplication::get_character_path(QString p_char, QString p_file)
|
|||||||
return get_case_sensitive_path(path);
|
return get_case_sensitive_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString AOApplication::get_misc_path(QString p_misc, QString p_file)
|
||||||
|
{
|
||||||
|
QString path = get_base_path() + "misc/" + p_misc + "/" + p_file;
|
||||||
|
#ifndef CASE_SENSITIVE_FILESYSTEM
|
||||||
|
return path;
|
||||||
|
#else
|
||||||
|
return get_case_sensitive_path(path);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QString AOApplication::get_sounds_path(QString p_file)
|
QString AOApplication::get_sounds_path(QString p_file)
|
||||||
{
|
{
|
||||||
QString path = get_base_path() + "sounds/general/" + p_file;
|
QString path = get_base_path() + "sounds/general/" + p_file;
|
||||||
|
@ -67,8 +67,7 @@ bool AOApplication::get_log_goes_downwards()
|
|||||||
|
|
||||||
bool AOApplication::get_log_newline()
|
bool AOApplication::get_log_newline()
|
||||||
{
|
{
|
||||||
QString result =
|
QString result = configini->value("log_newline", "false").value<QString>();
|
||||||
configini->value("log_newline", "false").value<QString>();
|
|
||||||
return result.startsWith("true");
|
return result.startsWith("true");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,8 +79,7 @@ int AOApplication::get_log_margin()
|
|||||||
|
|
||||||
bool AOApplication::get_log_timestamp()
|
bool AOApplication::get_log_timestamp()
|
||||||
{
|
{
|
||||||
QString result =
|
QString result = configini->value("log_timestamp", "false").value<QString>();
|
||||||
configini->value("log_timestamp", "false").value<QString>();
|
|
||||||
return result.startsWith("true");
|
return result.startsWith("true");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +280,13 @@ QString AOApplication::read_design_ini(QString p_identifier,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::TransformationMode AOApplication::get_scaling(QString p_scaling)
|
||||||
|
{
|
||||||
|
if (p_scaling == "smooth")
|
||||||
|
return Qt::SmoothTransformation;
|
||||||
|
return Qt::FastTransformation;
|
||||||
|
}
|
||||||
|
|
||||||
QPoint AOApplication::get_button_spacing(QString p_identifier, QString p_file)
|
QPoint AOApplication::get_button_spacing(QString p_identifier, QString p_file)
|
||||||
{
|
{
|
||||||
QString design_ini_path = get_theme_path(p_file);
|
QString design_ini_path = get_theme_path(p_file);
|
||||||
@ -315,28 +320,12 @@ pos_size_type AOApplication::get_element_dimensions(QString p_identifier,
|
|||||||
QString p_file,
|
QString p_file,
|
||||||
QString p_char)
|
QString p_char)
|
||||||
{
|
{
|
||||||
QString char_ini_path =
|
|
||||||
get_base_path() + "misc/" + get_chat(p_char) + "/" + p_file;
|
|
||||||
QString design_ini_path = get_theme_path(p_file);
|
|
||||||
QString default_path = get_default_theme_path(p_file);
|
|
||||||
QString f_result = read_design_ini(p_identifier, char_ini_path);
|
|
||||||
|
|
||||||
pos_size_type return_value;
|
pos_size_type return_value;
|
||||||
|
|
||||||
return_value.x = 0;
|
return_value.x = 0;
|
||||||
return_value.y = 0;
|
return_value.y = 0;
|
||||||
return_value.width = -1;
|
return_value.width = -1;
|
||||||
return_value.height = -1;
|
return_value.height = -1;
|
||||||
|
QString f_result = get_design_element(p_identifier, p_file, p_char);
|
||||||
if (f_result == "") {
|
|
||||||
f_result = read_design_ini(p_identifier, design_ini_path);
|
|
||||||
if (f_result == "") {
|
|
||||||
f_result = read_design_ini(p_identifier, default_path);
|
|
||||||
|
|
||||||
if (f_result == "")
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList sub_line_elements = f_result.split(",");
|
QStringList sub_line_elements = f_result.split(",");
|
||||||
|
|
||||||
@ -353,17 +342,16 @@ pos_size_type AOApplication::get_element_dimensions(QString p_identifier,
|
|||||||
QString AOApplication::get_design_element(QString p_identifier, QString p_file,
|
QString AOApplication::get_design_element(QString p_identifier, QString p_file,
|
||||||
QString p_char)
|
QString p_char)
|
||||||
{
|
{
|
||||||
QString char_ini_path =
|
QStringList paths{get_theme_path("misc/" + get_chat(p_char) + "/" +
|
||||||
get_base_path() + "misc/" + get_chat(p_char) + "/" + p_file;
|
p_file), // user theme overrides base/misc
|
||||||
QString design_ini_path = get_theme_path(p_file);
|
get_base_path() + "misc/" + get_chat(p_char) + "/" + p_file,
|
||||||
QString default_path = get_default_theme_path(p_file);
|
get_theme_path(p_file), get_default_theme_path(p_file)};
|
||||||
QString f_result = read_design_ini(p_identifier, char_ini_path);
|
for (const QString &path : paths) {
|
||||||
if (f_result == "") {
|
QString value = read_design_ini(p_identifier, path);
|
||||||
f_result = read_design_ini(p_identifier, design_ini_path);
|
if (!value.isEmpty())
|
||||||
if (f_result == "")
|
return value;
|
||||||
f_result = read_design_ini(p_identifier, default_path);
|
|
||||||
}
|
}
|
||||||
return f_result;
|
return "";
|
||||||
}
|
}
|
||||||
QString AOApplication::get_font_name(QString p_identifier, QString p_file)
|
QString AOApplication::get_font_name(QString p_identifier, QString p_file)
|
||||||
{
|
{
|
||||||
@ -483,34 +471,30 @@ QString AOApplication::get_tagged_stylesheet(QString target_tag, QString p_file)
|
|||||||
return f_text;
|
return f_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AOApplication::get_chat_markdown(QString p_identifier, QString p_chat)
|
QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat)
|
||||||
{
|
{
|
||||||
QString design_ini_path =
|
QStringList paths{get_theme_path("misc/" + get_chat(p_chat) + "/config.ini"),
|
||||||
get_base_path() + "misc/" + get_chat(p_chat) + "/config.ini";
|
get_base_path() + "misc/" + get_chat(p_chat) +
|
||||||
QString default_path = get_base_path() + "misc/default/config.ini";
|
"/config.ini",
|
||||||
QString f_result = read_design_ini(p_identifier, design_ini_path);
|
get_base_path() + "misc/default/config.ini",
|
||||||
|
get_theme_path("misc/default/config.ini")};
|
||||||
|
|
||||||
if (f_result == "")
|
for (const QString &path : paths) {
|
||||||
f_result = read_design_ini(p_identifier, default_path);
|
QString value = read_design_ini(p_identifier, path);
|
||||||
|
if (!value.isEmpty()) {
|
||||||
|
return value.toLatin1();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return f_result.toLatin1();
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor AOApplication::get_chat_color(QString p_identifier, QString p_chat)
|
QColor AOApplication::get_chat_color(QString p_identifier, QString p_chat)
|
||||||
{
|
{
|
||||||
QColor return_color(255, 255, 255);
|
QColor return_color(255, 255, 255);
|
||||||
|
QString f_result = get_chat_markup(p_identifier, p_chat);
|
||||||
QString design_ini_path =
|
if (f_result == "")
|
||||||
get_base_path() + "misc/" + get_chat(p_chat) + "/config.ini";
|
return return_color;
|
||||||
QString default_path = get_base_path() + "misc/default/config.ini";
|
|
||||||
QString f_result = read_design_ini(p_identifier, design_ini_path);
|
|
||||||
|
|
||||||
if (f_result == "") {
|
|
||||||
f_result = read_design_ini(p_identifier, default_path);
|
|
||||||
|
|
||||||
if (f_result == "")
|
|
||||||
return return_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList color_list = f_result.split(",");
|
QStringList color_list = f_result.split(",");
|
||||||
|
|
||||||
@ -524,23 +508,21 @@ QColor AOApplication::get_chat_color(QString p_identifier, QString p_chat)
|
|||||||
return return_color;
|
return return_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AOApplication::get_sfx(QString p_identifier)
|
QString AOApplication::get_sfx(QString p_identifier, QString p_misc)
|
||||||
{
|
{
|
||||||
QString design_ini_path = get_theme_path("courtroom_sounds.ini");
|
QStringList paths{get_theme_path("misc/" + p_misc + "/courtroom_sounds.ini"),
|
||||||
QString default_path = get_default_theme_path("courtroom_sounds.ini");
|
get_misc_path(p_misc, "courtroom_sounds.ini"),
|
||||||
QString f_result = read_design_ini(p_identifier, design_ini_path);
|
get_theme_path("courtroom_sounds.ini"),
|
||||||
|
get_default_theme_path("courtroom_sounds.ini")};
|
||||||
|
|
||||||
QString return_sfx = "";
|
QString return_sfx = "";
|
||||||
|
|
||||||
if (f_result == "") {
|
for (const QString &path : paths) {
|
||||||
f_result = read_design_ini(p_identifier, default_path);
|
QString value = read_design_ini(p_identifier, path);
|
||||||
|
if (!value.isEmpty()) {
|
||||||
if (f_result == "")
|
return value.toLatin1();
|
||||||
return return_sfx;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return_sfx = f_result;
|
|
||||||
|
|
||||||
return return_sfx;
|
return return_sfx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,6 +649,31 @@ QString AOApplication::get_blips(QString p_char)
|
|||||||
return f_result;
|
return f_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString AOApplication::get_emote_property(QString p_char, QString p_emote,
|
||||||
|
QString p_property)
|
||||||
|
{
|
||||||
|
QString f_result =
|
||||||
|
read_char_ini(p_char, p_emote, p_property); // per-emote override
|
||||||
|
if (f_result == "")
|
||||||
|
f_result = read_char_ini(p_char, p_property,
|
||||||
|
"Options"); // global for this character
|
||||||
|
return f_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::TransformationMode AOApplication::get_misc_scaling(QString p_miscname)
|
||||||
|
{
|
||||||
|
if (p_miscname != "") {
|
||||||
|
QString misc_transform_mode = read_design_ini(
|
||||||
|
"scaling", get_theme_path("misc/" + p_miscname + "/config.ini"));
|
||||||
|
if (misc_transform_mode == "")
|
||||||
|
misc_transform_mode =
|
||||||
|
read_design_ini("scaling", get_misc_path(p_miscname, "config.ini"));
|
||||||
|
if (misc_transform_mode == "smooth")
|
||||||
|
return Qt::SmoothTransformation;
|
||||||
|
}
|
||||||
|
return Qt::FastTransformation;
|
||||||
|
}
|
||||||
|
|
||||||
QString AOApplication::get_category(QString p_char)
|
QString AOApplication::get_category(QString p_char)
|
||||||
{
|
{
|
||||||
QString f_result = read_char_ini(p_char, "category", "Options");
|
QString f_result = read_char_ini(p_char, "category", "Options");
|
||||||
@ -904,7 +911,7 @@ QStringList AOApplication::get_theme_effects()
|
|||||||
|
|
||||||
QStringList lines = read_file(p_path).split("\n");
|
QStringList lines = read_file(p_path).split("\n");
|
||||||
foreach (QString effect, lines) {
|
foreach (QString effect, lines) {
|
||||||
effect = effect.split("=")[0].trimmed();
|
effect = effect.split("=")[0].trimmed().split("_")[0];
|
||||||
if (!effect.isEmpty() && !effects.contains(effect))
|
if (!effect.isEmpty() && !effects.contains(effect))
|
||||||
effects.append(effect);
|
effects.append(effect);
|
||||||
}
|
}
|
||||||
@ -922,7 +929,7 @@ QStringList AOApplication::get_effects(QString p_char)
|
|||||||
|
|
||||||
QStringList lines = read_file(p_path).split("\n");
|
QStringList lines = read_file(p_path).split("\n");
|
||||||
foreach (QString effect, lines) {
|
foreach (QString effect, lines) {
|
||||||
effect = effect.split("=")[0].trimmed();
|
effect = effect.split("=")[0].trimmed().split("_")[0];
|
||||||
if (!effect.isEmpty() && !effects.contains(effect))
|
if (!effect.isEmpty() && !effects.contains(effect))
|
||||||
effects.append(effect);
|
effects.append(effect);
|
||||||
}
|
}
|
||||||
@ -957,25 +964,33 @@ QString AOApplication::get_effect(QString effect, QString p_char,
|
|||||||
return p_path;
|
return p_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AOApplication::get_effect_sound(QString fx_name, QString p_char)
|
QString AOApplication::get_effect_property(QString fx_name, QString p_char,
|
||||||
|
QString p_property)
|
||||||
{
|
{
|
||||||
|
QString f_property;
|
||||||
|
if (p_property == "sound")
|
||||||
|
f_property = fx_name;
|
||||||
|
else
|
||||||
|
f_property = fx_name + "_" + p_property;
|
||||||
QString p_effect = read_char_ini(p_char, "effects", "Options");
|
QString p_effect = read_char_ini(p_char, "effects", "Options");
|
||||||
QString p_path = get_base_path() + "misc/" + p_effect + "/effects.ini";
|
QString p_path = get_base_path() + "misc/" + p_effect + "/effects.ini";
|
||||||
QString design_ini_path = get_theme_path("effects/effects.ini");
|
QString design_ini_path = get_theme_path("effects/effects.ini");
|
||||||
QString default_path = get_default_theme_path("effects/effects.ini");
|
QString default_path = get_default_theme_path("effects/effects.ini");
|
||||||
|
|
||||||
QString f_result = read_design_ini(fx_name, p_path);
|
QString f_result = read_design_ini(f_property, p_path);
|
||||||
if (f_result == "") {
|
if (f_result == "") {
|
||||||
f_result = read_design_ini(fx_name, design_ini_path);
|
f_result = read_design_ini(f_property, design_ini_path);
|
||||||
if (f_result == "") {
|
if (f_result == "") {
|
||||||
f_result = read_design_ini(fx_name, default_path);
|
f_result = read_design_ini(f_property, default_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fx_name == "realization") {
|
if (fx_name == "realization" && p_property == "sound") {
|
||||||
f_result = get_custom_realization(p_char);
|
f_result = get_custom_realization(p_char);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "got" << f_property << "of" << fx_name << "==" << f_result;
|
||||||
|
|
||||||
return f_result;
|
return f_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user