diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 3649131352e..1ef9a8f178f 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -843,6 +843,12 @@ public class GameAction { final Map runParams = Maps.newHashMap(); game.getTriggerHandler().runTrigger(TriggerType.Always, runParams, false); + // Update P/T and type in the view only once after all the cards have been processed, to avoid flickering + for (Card c : affectedCards) { + c.updatePowerToughnessForView(); + c.updateTypesForView(); + } + if (runEvents && !affectedCards.isEmpty()) { game.fireEvent(new GameEventCardStatsChanged(affectedCards)); } diff --git a/forge-game/src/main/java/forge/game/StaticEffect.java b/forge-game/src/main/java/forge/game/StaticEffect.java index e0c4237f282..1e434a72056 100644 --- a/forge-game/src/main/java/forge/game/StaticEffect.java +++ b/forge-game/src/main/java/forge/game/StaticEffect.java @@ -1003,8 +1003,9 @@ public class StaticEffect { if (addT.startsWith("AffectedX")) { toughnessBonus = getXMapValue(affectedCard); } - affectedCard.addSemiPermanentPowerBoost(powerBonus * -1); - affectedCard.addSemiPermanentToughnessBoost(toughnessBonus * -1); + // the view is updated in GameAction#checkStaticAbilities to avoid flickering + affectedCard.addSemiPermanentPowerBoost(powerBonus * -1, false); + affectedCard.addSemiPermanentToughnessBoost(toughnessBonus * -1, false); // remove keywords // TODO regular keywords currently don't try to use keyword multiplier @@ -1046,7 +1047,8 @@ public class StaticEffect { // remove Types if (params.containsKey("AddType") || params.containsKey("RemoveType")) { - affectedCard.removeChangedCardTypes(getTimestamp()); + // the view is updated in GameAction#checkStaticAbilities to avoid flickering + affectedCard.removeChangedCardTypes(getTimestamp(), false); } // remove colors diff --git a/forge-game/src/main/java/forge/game/StaticEffects.java b/forge-game/src/main/java/forge/game/StaticEffects.java index 96064e5f4a6..9bba9d9b0d9 100644 --- a/forge-game/src/main/java/forge/game/StaticEffects.java +++ b/forge-game/src/main/java/forge/game/StaticEffects.java @@ -63,8 +63,8 @@ public class StaticEffects { /** * Add a static effect to the list of static effects. * - * @param staticEffect - * a {@link StaticEffect}. + * @param staticAbility + * a {@link StaticAbility}. */ public final StaticEffect getStaticEffect(final StaticAbility staticAbility) { final StaticEffect currentEffect = staticEffects.get(staticAbility); diff --git a/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java index 621725854b5..36b7c0bce79 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java @@ -52,7 +52,7 @@ public class PumpEffect extends SpellAbilityEffect { applyTo.addTempPowerBoost(a); applyTo.addTempToughnessBoost(d); applyTo.addChangedCardKeywords(kws, Lists.newArrayList(), false, timestamp); - if (redrawPT) { applyTo.updatePowerToughnessView(); } + if (redrawPT) { applyTo.updatePowerToughnessForView(); } if (sa.hasParam("LeaveBattlefield")) { addLeaveBattlefieldReplacement(applyTo, sa, sa.getParam("LeaveBattlefield")); @@ -76,7 +76,7 @@ public class PumpEffect extends SpellAbilityEffect { if (kw.startsWith("HIDDEN")) { applyTo.removeHiddenExtrinsicKeyword(kw); if (redrawPT) { - applyTo.updatePowerToughnessView(); + applyTo.updatePowerToughnessForView(); } } } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 532b429fe5e..8f101149a4c 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -456,11 +456,22 @@ public class Card extends GameEntity implements Comparable { view.updateState(this); } + // The following methods are used to selectively update certain view components (text, + // P/T, card types) in order to avoid card flickering due to aggressive full update public void updateAbilityTextForView() { view.getCurrentState().updateKeywords(this, getCurrentState()); view.getCurrentState().updateAbilityText(this, getCurrentState()); } + public final void updatePowerToughnessForView() { + currentState.getView().updatePower(this); + currentState.getView().updateToughness(this); + } + + public final void updateTypesForView() { + currentState.getView().updateType(currentState); + } + public void setPreFaceDownState(CardStateName preCharacteristic) { preFaceDownState = preCharacteristic; } @@ -3129,16 +3140,20 @@ public class Card extends GameEntity implements Comparable { return semiPermanentToughnessBoost; } - public final void addSemiPermanentPowerBoost(final int n) { + public final void addSemiPermanentPowerBoost(final int n, final boolean updateViewImmediately) { if (n == 0) { return; } semiPermanentPowerBoost += n; - currentState.getView().updatePower(this); + if (updateViewImmediately) { + currentState.getView().updatePower(this); + } } - public final void addSemiPermanentToughnessBoost(final int n) { + public final void addSemiPermanentToughnessBoost(final int n, final boolean updateViewImmediately) { if (n == 0) { return; } semiPermanentToughnessBoost += n; - currentState.getView().updateToughness(this); + if (updateViewImmediately) { + currentState.getView().updateToughness(this); + } } public final void setSemiPermanentPowerBoost(final int n) { @@ -3153,11 +3168,6 @@ public class Card extends GameEntity implements Comparable { currentState.getView().updateToughness(this); } - public final void updatePowerToughnessView() { - currentState.getView().updatePower(this); - currentState.getView().updateToughness(this); - } - public final boolean isUntapped() { return !tapped; } diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index 5b9478957c4..ed8fa526d0e 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -496,6 +496,10 @@ public final class StaticAbilityContinuous { CardFactory.copyState(gainTextSource, CardStateName.Original, affectedCard, CardStateName.Original, false); + // Do not clone the set code and rarity from the target card + affectedCard.getState(CardStateName.Original).setSetCode(affectedCard.getState(CardStateName.OriginalText).getSetCode()); + affectedCard.getState(CardStateName.Original).setRarity(affectedCard.getState(CardStateName.OriginalText).getRarity()); + // Enable this in case Volrath's original image is to be used affectedCard.getState(CardStateName.Original).setImageKey(affectedCard.getState(CardStateName.OriginalText).getImageKey()); @@ -572,8 +576,8 @@ public final class StaticAbilityContinuous { toughnessBonus = CardFactoryUtil.xCount(affectedCard, AbilityUtils.getSVar(stAb, addT)); se.addXMapValue(affectedCard, toughnessBonus); } - affectedCard.addSemiPermanentPowerBoost(powerBonus); - affectedCard.addSemiPermanentToughnessBoost(toughnessBonus); + affectedCard.addSemiPermanentPowerBoost(powerBonus, false); + affectedCard.addSemiPermanentToughnessBoost(toughnessBonus, false); } // add keywords