aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/courtroom.h4
-rw-r--r--src/courtroom.cpp161
-rw-r--r--src/text_file_functions.cpp57
3 files changed, 142 insertions, 80 deletions
diff --git a/include/courtroom.h b/include/courtroom.h
index deabb460..73ef6fbb 100644
--- a/include/courtroom.h
+++ b/include/courtroom.h
@@ -188,8 +188,7 @@ public:
void set_scene(QString f_desk_mod, QString f_side);
// sets ui_vp_player_char according to SELF_OFFSET, only a function bc it's used with desk_mod 4 and 5
- // sets ui_effects_layer according to the SELF_OFFSET, unless it is overwritten by effects.ini
- void set_self_offset(QString p_list, QString p_effect);
+ void set_self_offset(const QString& p_list);
// takes in serverD-formatted IP list as prints a converted version to server
// OOC admittedly poorly named
@@ -821,7 +820,6 @@ private:
void regenerate_ic_chatlog();
public slots:
void objection_done();
- void effect_done();
void preanim_done();
void do_screenshake();
void do_flash();
diff --git a/src/courtroom.cpp b/src/courtroom.cpp
index 7bde8377..30d226e1 100644
--- a/src/courtroom.cpp
+++ b/src/courtroom.cpp
@@ -411,8 +411,6 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
connect(keepalive_timer, &QTimer::timeout, this, &Courtroom::ping_server);
connect(ui_vp_objection, &SplashLayer::done, this, &Courtroom::objection_done);
- connect(ui_vp_effect, &EffectLayer::done, this, &Courtroom::effect_done);
- connect(ui_vp_wtce, &SplashLayer::done, this, &Courtroom::effect_done);
connect(ui_vp_player_char, &CharLayer::done, this, &Courtroom::preanim_done);
connect(ui_vp_player_char, &CharLayer::shake, this, &Courtroom::do_screenshake);
connect(ui_vp_player_char, &CharLayer::flash, this, &Courtroom::do_flash);
@@ -2056,8 +2054,14 @@ void Courtroom::on_chat_return_pressed()
ao_app->get_effect_property(effect, current_char, "sound");
QString p_effect =
ao_app->read_char_ini(current_char, "effects", "Options");
+
+ // Don't overlap the two sfx
+ if (!ui_pre->isChecked() && (!custom_sfx.isEmpty() || ui_sfx_dropdown->currentIndex() == 1)) {
+ fx_sound = "0";
+ }
+
packet_contents.append(effect + "|" + p_effect + "|" + fx_sound);
- if (!ao_app->is_stickyeffects_enabled()) {
+ if (!ao_app->is_stickyeffects_enabled() && !ao_app->get_effect_property(effect, current_char, "sticky").startsWith("true")) {
ui_effects_dropdown->blockSignals(true);
ui_effects_dropdown->setCurrentIndex(0);
ui_effects_dropdown->blockSignals(false);
@@ -2396,12 +2400,6 @@ bool Courtroom::handle_objection()
return false;
}
-void Courtroom::effect_done()
-{
- ui_vp_effect->stop();
- ui_vp_wtce->stop();
-}
-
void Courtroom::display_character()
{
// Stop all previously playing animations, effects etc.
@@ -2436,13 +2434,10 @@ void Courtroom::display_character()
else
ui_vp_player_char->network_strings.clear();
- // Determine if we should flip the character or not (what servers don't support flipping at this point?)
- if (ao_app->flipping_enabled && m_chatmessage[FLIP].toInt() == 1)
- ui_vp_player_char->set_flipped(true);
- else
- ui_vp_player_char->set_flipped(false);
+ // Determine if we should flip the character or not
+ ui_vp_player_char->set_flipped(m_chatmessage[FLIP].toInt() == 1);
// Move the character on the viewport according to the offsets
- set_self_offset(m_chatmessage[SELF_OFFSET], m_chatmessage[EFFECTS]);
+ set_self_offset(m_chatmessage[SELF_OFFSET]);
}
void Courtroom::display_pair_character(QString other_charid, QString other_offset)
@@ -2652,45 +2647,100 @@ void Courtroom::do_flash()
QString f_char = m_chatmessage[CHAR_NAME];
QString f_custom_theme = ao_app->get_chat(f_char);
- ui_vp_effect->stretch = true;
- ui_vp_effect->set_static_duration(60);
- ui_vp_effect->set_max_duration(60);
- ui_vp_player_char->stackUnder(ui_vp_objection); // go above the chatbox
- ui_vp_effect->load_image(
- ao_app->get_effect("realization", f_char, f_custom_theme), false);
+ do_effect("realization", "", f_char, f_custom_theme);
}
-void Courtroom::do_effect(QString fx_name, QString fx_sound, QString p_char,
+void Courtroom::do_effect(QString fx_path, QString fx_sound, QString p_char,
QString p_folder)
{
- if (fx_name == "")
+ if (fx_path == "") {
return;
- QString effect = ao_app->get_effect(fx_name, p_char, p_folder);
- if (effect == "")
+ }
+ QString effect = ao_app->get_effect(fx_path, p_char, p_folder);
+ if (effect == "") {
return;
+ }
- if (fx_sound != "")
+ if (fx_sound != "") {
sfx_player->play(fx_sound);
+ }
// 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;
+ }
ui_vp_effect->transform_mode = ao_app->get_scaling(
- ao_app->get_effect_property(fx_name, p_char, "scaling"));
+ ao_app->get_effect_property(fx_path, p_char, "scaling"));
ui_vp_effect->stretch =
- ao_app->get_effect_property(fx_name, p_char, "stretch")
+ ao_app->get_effect_property(fx_path, p_char, "stretch")
.startsWith("true");
- bool under_chatbox = ao_app->get_effect_property(fx_name, p_char, "under_chatbox").startsWith("true");
- if (under_chatbox)
- ui_vp_effect->stackUnder(ui_vp_chatbox);
- else
- ui_vp_effect->stackUnder(ui_vp_objection);
+ ui_vp_effect->set_flipped(ao_app->get_effect_property(fx_path, p_char, "respect_flip").startsWith("true") && m_chatmessage[FLIP].toInt() == 1);
ui_vp_effect->set_play_once(
false); // The effects themselves dictate whether or not they're looping.
// Static effects will linger.
- ui_vp_effect->set_static_duration(0);
- ui_vp_effect->set_max_duration(0);
- ui_vp_effect->load_image(effect, true);
+
+ bool looping =
+ ao_app->get_effect_property(fx_path, p_char, "loop")
+ .startsWith("true");
+
+ int max_duration =
+ ao_app->get_effect_property(fx_path, p_char, "max_duration")
+ .toInt();
+
+ bool cull =
+ ao_app->get_effect_property(fx_path, p_char, "cull")
+ .startsWith("true");
+
+ // Possible values: "chat", "character", "behind"
+ QString layer = ao_app->get_effect_property(fx_path, p_char, "layer").toLower();
+ if (layer == "behind"){
+ ui_vp_effect->setParent(ui_viewport);
+ ui_vp_effect->stackUnder(ui_vp_player_char);
+ }
+ else if (layer == "character") {
+ ui_vp_effect->setParent(ui_viewport);
+ ui_vp_effect->stackUnder(ui_vp_desk);
+ }
+ else if (layer == "over") {
+ ui_vp_effect->setParent(ui_viewport);
+ ui_vp_effect->raise();
+ }
+ else { // if (layer == "chat") {
+ ui_vp_effect->setParent(this);
+ ui_vp_effect->stackUnder(ui_vp_objection);
+ }
+
+ int effect_x = 0;
+ int effect_y = 0;
+ // The effect is not parented to viewport, meaning we're overlaying ui elements
+ if (ui_vp_effect->parentWidget() != ui_viewport) {
+ //We need to add the viewport as an offset as effects are not bound to it.
+ effect_x = ui_viewport->x();
+ effect_y = ui_viewport->y();
+ }
+ // This effect respects the character offset settings
+ if (ao_app->get_effect_property(fx_path, p_char, "respect_offset") == "true") {
+ QStringList self_offsets = m_chatmessage[SELF_OFFSET].split("&");
+ int self_offset = self_offsets[0].toInt();
+ int self_offset_v;
+ if (self_offsets.length() <= 1) {
+ self_offset_v = 0;
+ }
+ else {
+ self_offset_v = self_offsets[1].toInt();
+ }
+
+ // Move the effects layer to match the position of our character
+ const int percent = 100;
+ effect_x += ui_viewport->width() * self_offset / percent;
+ effect_y += ui_viewport->height() * self_offset_v / percent;
+ }
+ ui_vp_effect->move(effect_x, effect_y);
+
+ ui_vp_effect->set_static_duration(max_duration);
+ ui_vp_effect->set_max_duration(max_duration);
+ ui_vp_effect->load_image(effect, looping);
+ ui_vp_effect->set_cull_image(cull);
}
void Courtroom::play_char_sfx(QString sfx_name)
@@ -3385,7 +3435,7 @@ void Courtroom::start_chat_ticking()
// handle expanded desk mods
switch(m_chatmessage[DESK_MOD].toInt()) {
case 4:
- set_self_offset(m_chatmessage[SELF_OFFSET], QString("||"));
+ set_self_offset(m_chatmessage[SELF_OFFSET]);
[[fallthrough]];
case 2:
set_scene("1", m_chatmessage[SIDE]);
@@ -3785,28 +3835,19 @@ void Courtroom::set_scene(const QString f_desk_mod, const QString f_side)
}
}
-void Courtroom::set_self_offset(QString p_list, QString p_effect) {
+void Courtroom::set_self_offset(const QString& p_list) {
QStringList self_offsets = p_list.split("&");
- QStringList play_effect = p_effect.split("|");
int self_offset = self_offsets[0].toInt();
int self_offset_v;
- if (self_offsets.length() <= 1)
+ if (self_offsets.length() <= 1) {
self_offset_v = 0;
- else
+ }
+ else {
self_offset_v = self_offsets[1].toInt();
- ui_vp_player_char->move_and_center(ui_viewport->width() * self_offset / 100, ui_viewport->height() * self_offset_v / 100);
-
- //If an effect is ignoring the users offset, we force it to the default position of the viewport.
- if (ao_app->get_effect_property(play_effect[0], current_char, "ignore_offset") == "true") {
- ui_vp_effect->move(ui_viewport->x(), ui_viewport->y());
- return;
+ ui_vp_player_char->move_and_center(ui_viewport->width() * self_offset / 100, ui_viewport->height() * self_offset_v / 100);
+ const int percent = 100;
+ ui_vp_player_char->move(ui_viewport->width() * self_offset / percent, ui_viewport->height() * self_offset_v / percent);
}
-
- //Offset is not disabled, we move the effects layer to match the position of our character
- //We need to add the viewport as an offset as effects are not bound to it.
- int effect_x = (ui_viewport->width() * self_offset / 100) + ui_viewport->x();
- int effect_y = (ui_viewport->height() * self_offset_v / 100) + ui_viewport->y();
- ui_vp_effect->move(effect_x, effect_y);
}
void Courtroom::set_ip_list(QString p_list)
@@ -4607,9 +4648,17 @@ void Courtroom::set_effects_dropdown()
ui_effects_dropdown->hide();
return;
}
- QStringList effectslist = ao_app->get_effects(current_char);
+ QStringList effectslist;
+ QStringList char_effects = ao_app->get_effects(current_char);
+ for (int i = 0; i < char_effects.size(); ++i) {
+ QString effect = char_effects[i];
+ if (effect.contains(":")) {
+ effect = effect.section(':', 1);
+ }
+ effectslist.append(effect);
+ }
- if (effectslist.size() <= 0) {
+ if (effectslist.empty()) {
ui_effects_dropdown->hide();
return;
}
diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp
index 28478e9f..be162b22 100644
--- a/src/text_file_functions.cpp
+++ b/src/text_file_functions.cpp
@@ -877,19 +877,18 @@ QStringList AOApplication::get_effects(QString p_char)
QString p_misc = read_char_ini(p_char, "effects", "Options");
QString p_path = get_asset("effects/effects.ini", current_theme, get_subtheme(), default_theme, "");
QString p_misc_path = get_asset("effects.ini", current_theme, get_subtheme(), default_theme, p_misc);
- QStringList effects;
-
- QStringList lines = read_file(p_path).split("\n");
- // Misc path different from default path, stack the new miscs on top of the defaults
- if (p_misc_path != p_path) {
- lines << read_file(p_misc_path).split("\n");
- }
- foreach (QString effect, lines) {
- effect = effect.split("=")[0].trimmed().split("_")[0];
- if (!effect.isEmpty() && !effects.contains(effect))
- effects.append(effect);
+ QSettings effects_config(p_path, QSettings::IniFormat);
+ effects_config.setIniCodec("UTF-8");
+ QStringList effects = effects_config.childGroups();
+ std::sort(effects.begin(), effects.end(), [] (const QString &a, const QString &b) {return a.split(":")[0].toInt() < b.split(":")[0].toInt();});
+ if (p_path != p_misc_path) {
+ // If misc path is different from default path, stack the new miscs on top of the defaults
+ QSettings effects_config_misc(p_misc_path, QSettings::IniFormat);
+ effects_config_misc.setIniCodec("UTF-8");
+ QStringList misc_effects = effects_config_misc.childGroups();
+ std::sort(misc_effects.begin(), misc_effects.end(), [] (const QString &a, const QString &b) {return a.split(":")[0].toInt() < b.split(":")[0].toInt();});
+ effects += misc_effects;
}
-
return effects;
}
@@ -913,15 +912,31 @@ QString AOApplication::get_effect(QString effect, 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 f_result = get_config_value(f_property, "effects.ini", current_theme, get_subtheme(), default_theme, read_char_ini(p_char, "effects", "Options"));
- if (f_result == "")
- f_result = get_config_value(f_property, "effects/effects.ini", current_theme, get_subtheme(), default_theme, "");
+ const auto paths = get_asset_paths("effects/effects.ini", current_theme, get_subtheme(), default_theme, "");
+ const auto misc_paths = get_asset_paths("effects.ini", current_theme, get_subtheme(), default_theme, read_char_ini(p_char, "effects", "Options"));
+ QString path;
+ QString f_result;
+ for (const VPath &p : paths + misc_paths) {
+ path = get_real_path(p);
+ if (!path.isEmpty()) {
+ QSettings settings(path, QSettings::IniFormat);
+ settings.setIniCodec("UTF-8");
+ QStringList char_effects = settings.childGroups();
+ for (int i = 0; i < char_effects.size(); ++i) {
+ QString effect = char_effects[i];
+ if (effect.contains(":")) {
+ effect = effect.section(':', 1);
+ }
+ if (effect.toLower() == fx_name.toLower()) {
+ f_result = settings.value(char_effects[i] + "/" + p_property).toString();
+ if (!f_result.isEmpty()) {
+ // Only break the loop if we get a non-empty result, continue the search otherwise
+ break;
+ }
+ }
+ }
+ }
+ }
if (fx_name == "realization" && p_property == "sound") {
f_result = get_custom_realization(p_char);
}