mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
[Replay] Skip damage animations when skipping backward in replays
This commit is contained in:
parent
ada774f5cc
commit
cf0eb70f25
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);
|
||||
}
|
||||
|
||||
void CounterState::setValue(int newValue)
|
||||
void CounterState::setValue(int newValue, bool skipDamageAnimation)
|
||||
{
|
||||
if (newValue == value) {
|
||||
return;
|
||||
}
|
||||
int old = value;
|
||||
value = newValue;
|
||||
emit valueChanged(old, newValue);
|
||||
emit valueChanged(old, newValue, skipDamageAnimation);
|
||||
}
|
||||
|
|
@ -35,10 +35,23 @@ public:
|
|||
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:
|
||||
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:
|
||||
int id;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
enum EventProcessingOption
|
||||
{
|
||||
SKIP_REVEAL_WINDOW = 0x0001,
|
||||
SKIP_TAP_ANIMATION = 0x0002
|
||||
SKIP_TAP_ANIMATION = 0x0002,
|
||||
SKIP_DAMAGE_ANIMATION = 0x0004
|
||||
};
|
||||
|
||||
// Wrap it in a QFlags typedef
|
||||
|
|
|
|||
|
|
@ -262,14 +262,15 @@ void PlayerEventHandler::eventCreateCounter(const Event_CreateCounter &event)
|
|||
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);
|
||||
if (!ctr) {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -625,7 +626,7 @@ void PlayerEventHandler::processGameEvent(GameEvent::GameEventType type,
|
|||
eventCreateCounter(event.GetExtension(Event_CreateCounter::ext));
|
||||
break;
|
||||
case GameEvent::SET_COUNTER:
|
||||
eventSetCounter(event.GetExtension(Event_SetCounter::ext));
|
||||
eventSetCounter(event.GetExtension(Event_SetCounter::ext), options);
|
||||
break;
|
||||
case GameEvent::DEL_COUNTER:
|
||||
eventDelCounter(event.GetExtension(Event_DelCounter::ext));
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ public:
|
|||
void eventCreateCounter(const Event_CreateCounter &event);
|
||||
|
||||
/// 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.
|
||||
void eventDelCounter(const Event_DelCounter &event);
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ AbstractCounter::AbstractCounter(CounterState *state,
|
|||
{
|
||||
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;
|
||||
onValueChanged(oldValue, newValue);
|
||||
onValueChanged(oldValue, newValue, skipDamageAnimation);
|
||||
update();
|
||||
});
|
||||
|
||||
|
|
@ -230,7 +230,7 @@ void AbstractCounterDialog::changeValue(int diff)
|
|||
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
|
||||
// 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).
|
||||
*
|
||||
* 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 hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
|
|
|
|||
|
|
@ -251,8 +251,8 @@ void PlayerGraphicsItem::onCounterAdded(CounterState *state)
|
|||
AbstractCounter *widget;
|
||||
if (state->getName() == "life") {
|
||||
widget = playerTarget->addCounter(state);
|
||||
connect(state, &CounterState::valueChanged, this, [this](int oldValue, int newValue) {
|
||||
if (newValue < oldValue) {
|
||||
connect(state, &CounterState::valueChanged, this, [this](int oldValue, int newValue, bool skipDamageAnimation) {
|
||||
if (newValue < oldValue && !skipDamageAnimation) {
|
||||
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;
|
||||
if (flashDelta == 0) {
|
||||
|
|
@ -81,6 +81,11 @@ void PlayerCounter::onValueChanged(int oldValue, int newValue)
|
|||
return;
|
||||
}
|
||||
|
||||
if (skipDamageAnimation) {
|
||||
flashAlpha = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
flashAlpha = 1.0;
|
||||
flashClock.start();
|
||||
if (scene()) {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class PlayerCounter : public AbstractCounter, public IAnimatedItem
|
|||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
void onValueChanged(int oldValue, int newValue) override;
|
||||
void onValueChanged(int oldValue, int newValue, bool skipDamageAnimation) override;
|
||||
|
||||
private:
|
||||
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 damage animation (battlefield shimmer / life counter flash)
|
||||
if (playbackMode == BACKWARD_SKIP) {
|
||||
options |= SKIP_TAP_ANIMATION;
|
||||
options |= SKIP_DAMAGE_ANIMATION;
|
||||
}
|
||||
|
||||
emit eventReplayed(replay->event_list(currentEvent), options);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue