From 0519abab0343835eeb2a33d65ad85f2f68200156 Mon Sep 17 00:00:00 2001 From: Rosemary Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Sat, 23 Jul 2022 10:19:06 -0500 Subject: [PATCH] Fix multiple issues with screenshake code (#812) * Major cleanup of screenshake code * Add pre-5.10 support for screenshake math * more compat, uglier too * add surprise tool * we don't need inline functions --- include/courtroom.h | 3 +++ src/courtroom.cpp | 27 ++++++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/courtroom.h b/include/courtroom.h index eee84a6..0c53c95 100644 --- a/include/courtroom.h +++ b/include/courtroom.h @@ -52,6 +52,9 @@ #include #include #include +#if QT_VERSION > QT_VERSION_CHECK(5, 10, 0) +#include //added in Qt 5.10 +#endif #include #include #include diff --git a/src/courtroom.cpp b/src/courtroom.cpp index ef4051d..799e9fe 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -2626,33 +2626,38 @@ void Courtroom::do_screenshake() // This way, the animation is reset in such a way that last played screenshake // would return to its "final frame" properly. This properly resets all UI // elements without having to bother keeping track of "origin" positions. - // Works great wit the chat text being detached from the chat box! + // Works great with the chat text being detached from the chat box! screenshake_animation_group->setCurrentTime( screenshake_animation_group->duration()); screenshake_animation_group->clear(); - QList affected_list = {ui_vp_background, ui_vp_player_char, + const QList &affected_list = {ui_vp_background, ui_vp_player_char, ui_vp_sideplayer_char, ui_vp_chatbox}; // I would prefer if this was its own "shake" function to be honest. - foreach (QWidget *ui_element, affected_list) { + for (QWidget *ui_element : affected_list) { QPropertyAnimation *screenshake_animation = new QPropertyAnimation(ui_element, "pos", this); QPoint pos_default = QPoint(ui_element->x(), ui_element->y()); int duration = 300; // How long does the screenshake last int frequency = 20; // How often in ms is there a "jolt" frame - int maxframes = duration / frequency; - int max_x = 7; // Max deviation from origin on x axis - int max_y = 7; // Max deviation from origin on y axis + // Maximum deviation from the origin position. This is 7 pixels for a 256x192 viewport, + // so we scale that value in accordance with the current viewport height so the shake + // is roughly the same intensity regardless of viewport size. Done as a float operation for maximum accuracy. + int max_deviation = 7 * (float(ui_viewport->height()) / 192); + int maxframes = 15; // duration / frequency; screenshake_animation->setDuration(duration); for (int frame = 0; frame < maxframes; frame++) { double fraction = double(frame * frequency) / duration; - int rng = qrand(); // QRandomGenerator::global()->generate(); - int rand_x = max_x - (int(rng) % (max_x * 2)); - int rand_y = max_y - (int(rng + 100) % (max_y * 2)); - screenshake_animation->setKeyValueAt( - fraction, QPoint(pos_default.x() + rand_x, pos_default.y() + rand_y)); +#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) + int rand_x = max_deviation * (2 * (qrand() / (float)RAND_MAX) - 1) + 1; + int rand_y = max_deviation * (2 * (qrand() / (float)RAND_MAX) - 1) + 1; +#else + int rand_x = QRandomGenerator::system()->bounded(-max_deviation, max_deviation); + int rand_y = QRandomGenerator::system()->bounded(-max_deviation, max_deviation); +#endif + screenshake_animation->setKeyValueAt(fraction, QPoint(pos_default.x() + rand_x, pos_default.y() + rand_y)); } screenshake_animation->setEndValue(pos_default); screenshake_animation->setEasingCurve(QEasingCurve::Linear);