- Volrath's Shapeshifter: switched to a less aggressive update schedule (no update unless necessary), which fixes interaction with composite triggers that consist of several related parts (e.g. Undying, Persist).

- Volrath's Shapeshifter: QoL update: do not show the same text and discard ability twice if Volrath's Shapeshifter is attempting to copy the text of another Volrath's Shapeshifter that is on top of the graveyard.

git-svn-id: http://svn.slightlymagic.net/forge/trunk@35779 269b9781-a132-4a9b-9d4e-f004f1b56b58
This commit is contained in:
Agetian 2017-09-26 13:55:28 +00:00
parent 258c46868a
commit f12c49f712
2 changed files with 73 additions and 56 deletions

View File

@ -203,6 +203,8 @@ public class GameAction {
} }
if (c.getStates().contains(CardStateName.OriginalText)) { if (c.getStates().contains(CardStateName.OriginalText)) {
c.clearStates(CardStateName.OriginalText, false); c.clearStates(CardStateName.OriginalText, false);
c.removeSVar("GainingTextFrom");
c.removeSVar("GainingTextFromTimestamp");
} }
c.updateStateForView(); c.updateStateForView();
} else if (c.getStates().contains(CardStateName.OriginalText)) { } else if (c.getStates().contains(CardStateName.OriginalText)) {
@ -210,6 +212,8 @@ public class GameAction {
CardFactory.copyState(c, CardStateName.OriginalText, c, CardStateName.Original, false); CardFactory.copyState(c, CardStateName.OriginalText, c, CardStateName.Original, false);
c.setState(CardStateName.Original, false); c.setState(CardStateName.Original, false);
c.clearStates(CardStateName.OriginalText, false); c.clearStates(CardStateName.OriginalText, false);
c.removeSVar("GainingTextFrom");
c.removeSVar("GainingTextFromTimestamp");
c.updateStateForView(); c.updateStateForView();
} }

View File

@ -17,21 +17,10 @@
*/ */
package forge.game.staticability; package forge.game.staticability;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import forge.card.CardStateName;
import forge.game.card.*;
import forge.util.TextUtil;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.GameCommand; import forge.GameCommand;
import forge.card.CardStateName;
import forge.card.MagicColor; import forge.card.MagicColor;
import forge.game.Game; import forge.game.Game;
import forge.game.GlobalRuleChange; import forge.game.GlobalRuleChange;
@ -40,6 +29,7 @@ import forge.game.StaticEffects;
import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType; import forge.game.ability.ApiType;
import forge.game.card.*;
import forge.game.cost.Cost; import forge.game.cost.Cost;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementEffect;
@ -50,6 +40,10 @@ import forge.game.spellability.SpellAbility;
import forge.game.trigger.Trigger; import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerHandler; import forge.game.trigger.TriggerHandler;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.TextUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
/** /**
* The Class StaticAbility_Continuous. * The Class StaticAbility_Continuous.
@ -477,6 +471,15 @@ public final class StaticAbilityContinuous {
// Gain text from another card // Gain text from another card
if (layer == StaticAbilityLayer.TEXT) { if (layer == StaticAbilityLayer.TEXT) {
// Make no changes in case the target for the ability is still the same as before
boolean noChange = false;
if (gainTextSource != null && affectedCard.hasSVar("GainingTextFrom") && affectedCard.hasSVar("GainingTextFromTimestamp")
&& gainTextSource.getName() == affectedCard.getSVar("GainingTextFrom")
&& gainTextSource.getTimestamp() == Long.parseLong(affectedCard.getSVar("GainingTextFromTimestamp"))) {
noChange = true;
}
if (!noChange) {
// Restore the original text in case it was remembered before // Restore the original text in case it was remembered before
if (affectedCard.getStates().contains(CardStateName.OriginalText)) { if (affectedCard.getStates().contains(CardStateName.OriginalText)) {
affectedCard.clearTriggersNew(); affectedCard.clearTriggersNew();
@ -492,7 +495,11 @@ public final class StaticAbilityContinuous {
CardFactory.copyState(affectedCard, CardStateName.OriginalText, affectedCard, CardStateName.Original, false); CardFactory.copyState(affectedCard, CardStateName.OriginalText, affectedCard, CardStateName.Original, false);
} }
if (gainTextSource != null) { // TODO: find a better way to ascertain that the card will essentially try to copy its exact duplicate
// (e.g. Volrath's Shapeshifter copying the text of another pristine Volrath's Shapeshifter), since the
// check by name may fail in case one of the cards is modified in some way while the other is not
// (probably not very relevant for Volrath's Shapeshifter itself since it copies text on cards in GY).
if (gainTextSource != null && !gainTextSource.getCurrentState().getName().equals(affectedCard.getCurrentState().getName())) {
if (!affectedCard.getStates().contains(CardStateName.OriginalText)) { if (!affectedCard.getStates().contains(CardStateName.OriginalText)) {
// Remember the original text first in case it hasn't been done yet // Remember the original text first in case it hasn't been done yet
CardFactory.copyState(affectedCard, CardStateName.Original, affectedCard, CardStateName.OriginalText, false); CardFactory.copyState(affectedCard, CardStateName.Original, affectedCard, CardStateName.OriginalText, false);
@ -507,7 +514,7 @@ public final class StaticAbilityContinuous {
// Enable this in case Volrath's original image is to be used // Enable this in case Volrath's original image is to be used
affectedCard.getState(CardStateName.Original).setImageKey(affectedCard.getState(CardStateName.OriginalText).getImageKey()); affectedCard.getState(CardStateName.Original).setImageKey(affectedCard.getState(CardStateName.OriginalText).getImageKey());
// Activated abilities (statics and repleffects are apparently copied vis copyState?) // Activated abilities (statics and repleffects are apparently copied via copyState?)
for (SpellAbility sa : gainTextSource.getSpellAbilities()) { for (SpellAbility sa : gainTextSource.getSpellAbilities()) {
if (sa instanceof AbilityActivated) { if (sa instanceof AbilityActivated) {
SpellAbility newSA = ((AbilityActivated) sa).getCopy(); SpellAbility newSA = ((AbilityActivated) sa).getCopy();
@ -527,6 +534,12 @@ public final class StaticAbilityContinuous {
if (params.containsKey("GainedTextHasThisStaticAbility")) { if (params.containsKey("GainedTextHasThisStaticAbility")) {
affectedCard.getCurrentState().addStaticAbility(stAb); affectedCard.getCurrentState().addStaticAbility(stAb);
} }
// Remember the name and the timestamp of the card we're gaining text from, so we don't modify
// the card too aggressively when unnecessary
affectedCard.setSVar("GainingTextFrom", String.valueOf(gainTextSource.getName()));
affectedCard.setSVar("GainingTextFromTimestamp", String.valueOf(gainTextSource.getTimestamp()));
}
} }
} }