mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-25 02:43:02 -07:00
[Replay] Skip damage animations when skipping backward in replays (#7249)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
b01e107908
commit
745e94f332
11 changed files with 40 additions and 17 deletions
|
|
@ -13,12 +13,12 @@ CounterState *CounterState::fromProto(const ServerInfo_Counter &counter, QObject
|
||||||
convertColorToQColor(counter.counter_color()), counter.radius(), counter.count(), parent);
|
convertColorToQColor(counter.counter_color()), counter.radius(), counter.count(), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CounterState::setValue(int newValue)
|
void CounterState::setValue(int newValue, bool skipDamageAnimation)
|
||||||
{
|
{
|
||||||
if (newValue == value) {
|
if (newValue == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int old = value;
|
int old = value;
|
||||||
value = newValue;
|
value = newValue;
|
||||||
emit valueChanged(old, newValue);
|
emit valueChanged(old, newValue, skipDamageAnimation);
|
||||||
}
|
}
|
||||||
|
|
@ -35,10 +35,23 @@ public:
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setValue(int newValue);
|
/**
|
||||||
|
* @brief Set the counter value.
|
||||||
|
* @param newValue The new value.
|
||||||
|
* @param skipDamageAnimation When true, valueChanged is emitted with skipDamageAnimation=true, letting views
|
||||||
|
* suppress damage-related feedback (e.g. battlefield shimmer, life counter flash) for values set during replay
|
||||||
|
* rewinds.
|
||||||
|
*/
|
||||||
|
void setValue(int newValue, bool skipDamageAnimation = false);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void valueChanged(int oldValue, int newValue);
|
/**
|
||||||
|
* @brief Emitted whenever the value changes.
|
||||||
|
* @param oldValue The previous value.
|
||||||
|
* @param newValue The new value.
|
||||||
|
* @param skipDamageAnimation True when the change should not trigger damage/life-change feedback in views.
|
||||||
|
*/
|
||||||
|
void valueChanged(int oldValue, int newValue, bool skipDamageAnimation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int id;
|
int id;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
enum EventProcessingOption
|
enum EventProcessingOption
|
||||||
{
|
{
|
||||||
SKIP_REVEAL_WINDOW = 0x0001,
|
SKIP_REVEAL_WINDOW = 0x0001,
|
||||||
SKIP_TAP_ANIMATION = 0x0002
|
SKIP_TAP_ANIMATION = 0x0002,
|
||||||
|
SKIP_DAMAGE_ANIMATION = 0x0004
|
||||||
};
|
};
|
||||||
|
|
||||||
// Wrap it in a QFlags typedef
|
// Wrap it in a QFlags typedef
|
||||||
|
|
|
||||||
|
|
@ -262,14 +262,15 @@ void PlayerEventHandler::eventCreateCounter(const Event_CreateCounter &event)
|
||||||
player->addCounter(event.counter_info());
|
player->addCounter(event.counter_info());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerEventHandler::eventSetCounter(const Event_SetCounter &event)
|
void PlayerEventHandler::eventSetCounter(const Event_SetCounter &event, EventProcessingOptions options)
|
||||||
{
|
{
|
||||||
CounterState *ctr = player->getCounters().value(event.counter_id(), nullptr);
|
CounterState *ctr = player->getCounters().value(event.counter_id(), nullptr);
|
||||||
if (!ctr) {
|
if (!ctr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int oldValue = ctr->getValue();
|
int oldValue = ctr->getValue();
|
||||||
ctr->setValue(event.value());
|
const bool skipDamageAnimation = options.testFlag(SKIP_DAMAGE_ANIMATION);
|
||||||
|
ctr->setValue(event.value(), skipDamageAnimation);
|
||||||
emit logSetCounter(player, ctr->getName(), event.value(), oldValue);
|
emit logSetCounter(player, ctr->getName(), event.value(), oldValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -625,7 +626,7 @@ void PlayerEventHandler::processGameEvent(GameEvent::GameEventType type,
|
||||||
eventCreateCounter(event.GetExtension(Event_CreateCounter::ext));
|
eventCreateCounter(event.GetExtension(Event_CreateCounter::ext));
|
||||||
break;
|
break;
|
||||||
case GameEvent::SET_COUNTER:
|
case GameEvent::SET_COUNTER:
|
||||||
eventSetCounter(event.GetExtension(Event_SetCounter::ext));
|
eventSetCounter(event.GetExtension(Event_SetCounter::ext), options);
|
||||||
break;
|
break;
|
||||||
case GameEvent::DEL_COUNTER:
|
case GameEvent::DEL_COUNTER:
|
||||||
eventDelCounter(event.GetExtension(Event_DelCounter::ext));
|
eventDelCounter(event.GetExtension(Event_DelCounter::ext));
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ public:
|
||||||
void eventCreateCounter(const Event_CreateCounter &event);
|
void eventCreateCounter(const Event_CreateCounter &event);
|
||||||
|
|
||||||
/// Set a player-level counter value.
|
/// Set a player-level counter value.
|
||||||
void eventSetCounter(const Event_SetCounter &event);
|
void eventSetCounter(const Event_SetCounter &event, EventProcessingOptions options);
|
||||||
|
|
||||||
/// Delete a player-level counter.
|
/// Delete a player-level counter.
|
||||||
void eventDelCounter(const Event_DelCounter &event);
|
void eventDelCounter(const Event_DelCounter &event);
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@ AbstractCounter::AbstractCounter(CounterState *state,
|
||||||
{
|
{
|
||||||
setAcceptHoverEvents(true);
|
setAcceptHoverEvents(true);
|
||||||
|
|
||||||
connect(state, &CounterState::valueChanged, this, [this](int oldValue, int newValue) {
|
connect(state, &CounterState::valueChanged, this, [this](int oldValue, int newValue, bool skipDamageAnimation) {
|
||||||
value = newValue;
|
value = newValue;
|
||||||
onValueChanged(oldValue, newValue);
|
onValueChanged(oldValue, newValue, skipDamageAnimation);
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -230,7 +230,7 @@ void AbstractCounterDialog::changeValue(int diff)
|
||||||
setTextValue(QString::number(curValue));
|
setTextValue(QString::number(curValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractCounter::onValueChanged(int /*oldValue*/, int /*newValue*/)
|
void AbstractCounter::onValueChanged(int /*oldValue*/, int /*newValue*/, bool /*skipDamageAnimation*/)
|
||||||
{
|
{
|
||||||
// Default: no feedback. Subclasses such as PlayerCounter override this to
|
// Default: no feedback. Subclasses such as PlayerCounter override this to
|
||||||
// flash the counter on meaningful changes (life gain/loss).
|
// flash the counter on meaningful changes (life gain/loss).
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,9 @@ protected:
|
||||||
* @brief Hook for subclasses that need per-value-change feedback (e.g. life-total flash).
|
* @brief Hook for subclasses that need per-value-change feedback (e.g. life-total flash).
|
||||||
*
|
*
|
||||||
* Called whenever the counter's value changes, before the item repaints.
|
* Called whenever the counter's value changes, before the item repaints.
|
||||||
|
* @param skipDamageAnimation True when damage-related feedback should be suppressed (replay rewinds).
|
||||||
*/
|
*/
|
||||||
virtual void onValueChanged(int oldValue, int newValue);
|
virtual void onValueChanged(int oldValue, int newValue, bool skipDamageAnimation);
|
||||||
|
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||||
|
|
|
||||||
|
|
@ -252,8 +252,8 @@ void PlayerGraphicsItem::onCounterAdded(CounterState *state)
|
||||||
AbstractCounter *widget;
|
AbstractCounter *widget;
|
||||||
if (state->getName() == "life") {
|
if (state->getName() == "life") {
|
||||||
widget = playerTarget->addCounter(state);
|
widget = playerTarget->addCounter(state);
|
||||||
connect(state, &CounterState::valueChanged, this, [this](int oldValue, int newValue) {
|
connect(state, &CounterState::valueChanged, this, [this](int oldValue, int newValue, bool skipDamageAnimation) {
|
||||||
if (newValue < oldValue) {
|
if (newValue < oldValue && !skipDamageAnimation) {
|
||||||
tableZoneGraphicsItem->triggerDamageShimmer();
|
tableZoneGraphicsItem->triggerDamageShimmer();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ void PlayerCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerCounter::onValueChanged(int oldValue, int newValue)
|
void PlayerCounter::onValueChanged(int oldValue, int newValue, bool skipDamageAnimation)
|
||||||
{
|
{
|
||||||
flashDelta = newValue - oldValue;
|
flashDelta = newValue - oldValue;
|
||||||
if (flashDelta == 0) {
|
if (flashDelta == 0) {
|
||||||
|
|
@ -81,6 +81,11 @@ void PlayerCounter::onValueChanged(int oldValue, int newValue)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skipDamageAnimation) {
|
||||||
|
flashAlpha = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
flashAlpha = 1.0;
|
flashAlpha = 1.0;
|
||||||
flashClock.start();
|
flashClock.start();
|
||||||
if (scene()) {
|
if (scene()) {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class PlayerCounter : public AbstractCounter, public IAnimatedItem
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
protected:
|
protected:
|
||||||
void onValueChanged(int oldValue, int newValue) override;
|
void onValueChanged(int oldValue, int newValue, bool skipDamageAnimation) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr qreal flashDurationMs = 450.0;
|
static constexpr qreal flashDurationMs = 450.0;
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,10 @@ void ReplayManager::processNewEvents(PlaybackMode playbackMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// backwards skip => always skip tap animation
|
// backwards skip => always skip tap animation
|
||||||
|
// backwards skip => always skip damage animation (battlefield shimmer / life counter flash)
|
||||||
if (playbackMode == BACKWARD_SKIP) {
|
if (playbackMode == BACKWARD_SKIP) {
|
||||||
options |= SKIP_TAP_ANIMATION;
|
options |= SKIP_TAP_ANIMATION;
|
||||||
|
options |= SKIP_DAMAGE_ANIMATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit eventReplayed(replay->event_list(currentEvent), options);
|
emit eventReplayed(replay->event_list(currentEvent), options);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue