From 04f24faf320db6b4f5510e37771d125e001bf2a1 Mon Sep 17 00:00:00 2001 From: Agetian Date: Mon, 28 Aug 2017 14:06:28 +0000 Subject: [PATCH] - Experimental: attempting to fix card flickering (power/toughness, jumping between rows) by selectively updating the view for P/T and types after all static effects for all cards have been processed instead of aggressively updating the entire state view during each static effect operation (might also make the game run a bit faster on mobile). - Volrath's Shapeshifter: do not copy the target's set code and rarity. --- .../src/main/java/forge/game/GameAction.java | 6 ++++ .../main/java/forge/game/StaticEffect.java | 8 ++++-- .../main/java/forge/game/StaticEffects.java | 4 +-- .../game/ability/effects/PumpEffect.java | 4 +-- .../src/main/java/forge/game/card/Card.java | 28 +++++++++++++------ .../StaticAbilityContinuous.java | 8 ++++-- 6 files changed, 40 insertions(+), 18 deletions(-) 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