mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Add code allowing text-changing effects (+some cleanup).
This commit is contained in:
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -307,6 +307,7 @@ forge-game/src/main/java/forge/game/ability/effects/BecomesBlockedEffect.java -t
|
||||
forge-game/src/main/java/forge/game/ability/effects/BidLifeEffect.java -text
|
||||
forge-game/src/main/java/forge/game/ability/effects/BondEffect.java -text
|
||||
forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java -text
|
||||
forge-game/src/main/java/forge/game/ability/effects/ChangeTextEffect.java -text
|
||||
forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java -text
|
||||
forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java -text
|
||||
forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java -text
|
||||
@@ -422,6 +423,8 @@ forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java -text
|
||||
forge-game/src/main/java/forge/game/ability/effects/ZoneExchangeEffect.java -text
|
||||
forge-game/src/main/java/forge/game/ability/package-info.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/card/Card.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/card/CardChangedWord.java -text
|
||||
forge-game/src/main/java/forge/game/card/CardChangedWords.java -text
|
||||
forge-game/src/main/java/forge/game/card/CardCharacteristics.java -text
|
||||
forge-game/src/main/java/forge/game/card/CardColor.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/card/CardDamageHistory.java -text
|
||||
|
||||
@@ -481,7 +481,7 @@ public class AiController {
|
||||
|
||||
// don't play the land if it has cycling and enough lands are
|
||||
// available
|
||||
final ArrayList<SpellAbility> spellAbilities = c.getSpellAbilities();
|
||||
final List<SpellAbility> spellAbilities = c.getSpellAbilities();
|
||||
|
||||
final List<Card> hand = player.getCardsIn(ZoneType.Hand);
|
||||
List<Card> lands = player.getCardsIn(ZoneType.Battlefield);
|
||||
|
||||
@@ -178,4 +178,9 @@ public class TextUtil {
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String capitalize(final String s) {
|
||||
return s.substring(0, 1).toUpperCase()
|
||||
+ s.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import forge.util.Expressions;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Base class for Triggers,ReplacementEffects and StaticAbilities.
|
||||
*
|
||||
@@ -22,7 +24,8 @@ public abstract class CardTraitBase extends GameObject {
|
||||
protected Card hostCard;
|
||||
|
||||
/** The map params. */
|
||||
protected final Map<String, String> mapParams = new HashMap<String, String>();
|
||||
protected final Map<String, String> originalMapParams = Maps.newHashMap(),
|
||||
mapParams = Maps.newHashMap();
|
||||
|
||||
/** The is intrinsic. */
|
||||
protected boolean intrinsic;
|
||||
@@ -66,11 +69,6 @@ public abstract class CardTraitBase extends GameObject {
|
||||
return this.mapParams;
|
||||
}
|
||||
|
||||
public final void setMapParams(Map<String,String> params) {
|
||||
this.mapParams.clear();
|
||||
this.mapParams.putAll(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is intrinsic.
|
||||
*
|
||||
@@ -350,4 +348,15 @@ public abstract class CardTraitBase extends GameObject {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void changeText() {
|
||||
for (final String key : this.mapParams.keySet()) {
|
||||
// don't change literal SVar names!
|
||||
if (!this.getHostCard().hasSVar(key)) {
|
||||
final String value = this.originalMapParams.get(key),
|
||||
newValue = AbilityUtils.applyTextChangeEffects(value, this.getHostCard());
|
||||
this.mapParams.put(key, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public class AbilityApiBased extends AbilityActivated {
|
||||
|
||||
public AbilityApiBased(ApiType api0, Card sourceCard, Cost abCost, TargetRestrictions tgt, Map<String, String> params0) {
|
||||
super(sourceCard, abCost, tgt);
|
||||
originalMapParams.putAll(params0);
|
||||
mapParams.putAll(params0);
|
||||
api = api0;
|
||||
effect = api.getSpellEffect();
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.apache.commons.lang3.text.WordUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -79,7 +80,7 @@ public class AbilityUtils {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Card> getDefinedCards(final Card hostCard, final String def, final SpellAbility sa) {
|
||||
final List<Card> cards = new ArrayList<Card>();
|
||||
final String defined = (def == null) ? "Self" : def; // default to Self
|
||||
final String defined = (def == null) ? "Self" : applyTextChangeEffects(def, hostCard); // default to Self
|
||||
final Game game = hostCard.getGame();
|
||||
|
||||
Card c = null;
|
||||
@@ -351,34 +352,37 @@ public class AbilityUtils {
|
||||
// return result soon for plain numbers
|
||||
if (StringUtils.isNumeric(amount)) { return Integer.parseInt(amount) * multiplier; }
|
||||
|
||||
// modify amount string for text changes
|
||||
final String amount2 = AbilityUtils.applyTextChangeEffects(amount, card);
|
||||
|
||||
// Try to fetch variable, try ability first, then card.
|
||||
String svarval = null;
|
||||
if (amount.indexOf('$') > 0) { // when there is a dollar sign, it's not a reference, it's a raw value!
|
||||
svarval = amount;
|
||||
if (amount2.indexOf('$') > 0) { // when there is a dollar sign, it's not a reference, it's a raw value!
|
||||
svarval = amount2;
|
||||
}
|
||||
else if (ability != null) {
|
||||
svarval = ability.getSVar(amount);
|
||||
svarval = ability.getSVar(amount2);
|
||||
}
|
||||
if (StringUtils.isBlank(svarval)) {
|
||||
if (ability != null) {
|
||||
System.err.printf("SVar '%s' not found in ability, fallback to Card (%s). Ability is (%s)%n", amount, card.getName(), ability);
|
||||
System.err.printf("SVar '%s' not found in ability, fallback to Card (%s). Ability is (%s)%n", amount2, card.getName(), ability);
|
||||
}
|
||||
svarval = card.getSVar(amount);
|
||||
svarval = card.getSVar(amount2);
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(svarval)) {
|
||||
// Some variables may be not chosen yet at this moment
|
||||
// So return 0 and don't issue an error.
|
||||
if (amount.equals("ChosenX")) {
|
||||
if (amount2.equals("ChosenX")) {
|
||||
// isn't made yet
|
||||
return 0;
|
||||
}
|
||||
// cost hasn't been paid yet
|
||||
if (amount.startsWith("Cost")) {
|
||||
if (amount2.startsWith("Cost")) {
|
||||
return 0;
|
||||
}
|
||||
// Nothing to do here if value is missing or blank
|
||||
System.err.printf("SVar '%s' not defined in Card (%s)%n", amount, card.getName());
|
||||
System.err.printf("SVar '%s' not defined in Card (%s)%n", amount2, card.getName());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -395,6 +399,9 @@ public class AbilityUtils {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// modify amount string for text changes
|
||||
calcX[1] = AbilityUtils.applyTextChangeEffects(calcX[1], card);
|
||||
|
||||
if (calcX[0].startsWith("Count")) {
|
||||
return AbilityUtils.xCount(card, calcX[1], ability) * multiplier;
|
||||
}
|
||||
@@ -806,7 +813,7 @@ public class AbilityUtils {
|
||||
*/
|
||||
public static List<Player> getDefinedPlayers(final Card card, final String def, final SpellAbility sa) {
|
||||
final List<Player> players = new ArrayList<Player>();
|
||||
final String defined = (def == null) ? "You" : def;
|
||||
final String defined = (def == null) ? "You" : applyTextChangeEffects(def, card);
|
||||
final Game game = card == null ? null : card.getGame();
|
||||
|
||||
if (defined.equals("Targeted") || defined.equals("TargetedPlayer")) {
|
||||
@@ -1125,7 +1132,7 @@ public class AbilityUtils {
|
||||
public static ArrayList<SpellAbility> getDefinedSpellAbilities(final Card card, final String def,
|
||||
final SpellAbility sa) {
|
||||
final ArrayList<SpellAbility> sas = new ArrayList<SpellAbility>();
|
||||
final String defined = (def == null) ? "Self" : def; // default to Self
|
||||
final String defined = (def == null) ? "Self" : applyTextChangeEffects(def, card); // default to Self
|
||||
final Game game = sa.getActivatingPlayer().getGame();
|
||||
|
||||
SpellAbility s = null;
|
||||
@@ -1398,9 +1405,9 @@ public class AbilityUtils {
|
||||
* @return a int.
|
||||
*/
|
||||
public static int xCount(final Card c, final String s, final SpellAbility sa) {
|
||||
|
||||
final String[] l = s.split("/");
|
||||
final String expr = CardFactoryUtil.extractOperators(s);
|
||||
final String s2 = AbilityUtils.applyTextChangeEffects(s, c);
|
||||
final String[] l = s2.split("/");
|
||||
final String expr = CardFactoryUtil.extractOperators(s2);
|
||||
|
||||
final String[] sq;
|
||||
sq = l[0].split("\\.");
|
||||
@@ -1459,7 +1466,7 @@ public class AbilityUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
return CardFactoryUtil.xCount(c, s);
|
||||
return CardFactoryUtil.xCount(c, s2);
|
||||
}
|
||||
|
||||
public static final void applyManaColorConversion(final Player p, final Map<String, String> params) {
|
||||
@@ -1506,4 +1513,15 @@ public class AbilityUtils {
|
||||
}
|
||||
return sas;
|
||||
}
|
||||
|
||||
public static final String applyTextChangeEffects(final String def, final Card hostCard) {
|
||||
String replaced = def;
|
||||
for (final Entry<String, String> e : hostCard.getChangedTextColorWords().entrySet()) {
|
||||
replaced = replaced.replace(e.getKey(), e.getValue());
|
||||
}
|
||||
for (final Entry<String, String> e : hostCard.getChangedTextTypeWords().entrySet()) {
|
||||
replaced = replaced.replace(e.getKey(), e.getValue());
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ public enum ApiType {
|
||||
BidLife (BidLifeEffect.class),
|
||||
Bond (BondEffect.class),
|
||||
ChangeTargets (ChangeTargetsEffect.class),
|
||||
ChangeText (ChangeTextEffect.class),
|
||||
ChangeZone (ChangeZoneEffect.class),
|
||||
ChangeZoneAll (ChangeZoneAllEffect.class),
|
||||
|
||||
Charm (CharmEffect.class),
|
||||
ChooseCard (ChooseCardEffect.class),
|
||||
ChooseColor (ChooseColorEffect.class),
|
||||
|
||||
@@ -19,7 +19,8 @@ public class SpellApiBased extends Spell {
|
||||
public SpellApiBased(ApiType api0, Card sourceCard, Cost abCost, TargetRestrictions tgt, Map<String, String> params0) {
|
||||
super(sourceCard, abCost);
|
||||
this.setTargetRestrictions(tgt);
|
||||
|
||||
|
||||
originalMapParams.putAll(params0);
|
||||
mapParams.putAll(params0);
|
||||
api = api0;
|
||||
effect = api.getSpellEffect();
|
||||
|
||||
@@ -15,6 +15,7 @@ public class StaticAbilityApiBased extends AbilityStatic {
|
||||
|
||||
public StaticAbilityApiBased(ApiType api0, Card sourceCard, Cost abCost, TargetRestrictions tgt, Map<String, String> params0) {
|
||||
super(sourceCard, abCost, tgt);
|
||||
originalMapParams.putAll(params0);
|
||||
mapParams.putAll(params0);
|
||||
api = api0;
|
||||
effect = api.getSpellEffect();
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GameCommand;
|
||||
import forge.card.CardType;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.Game;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.event.GameEventCardStatsChanged;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
public class ChangeTextEffect extends SpellAbilityEffect {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.abilityfactory.SpellEffect#resolve(forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
@Override
|
||||
public void resolve(final SpellAbility sa) {
|
||||
final Card source = sa.getHostCard();
|
||||
final Game game = source.getGame();
|
||||
final boolean permanent = sa.hasParam("Permanent");
|
||||
|
||||
final String changedColorWordOriginal, changedColorWordNew;
|
||||
if (sa.hasParam("ChangeColorWord")) {
|
||||
byte originalColor = 0;
|
||||
final String[] changedColorWordsArray = sa.getParam("ChangeColorWord").split(" ");
|
||||
if (changedColorWordsArray[0].equals("Choose")) {
|
||||
originalColor = sa.getActivatingPlayer().getController().chooseColor(
|
||||
"Choose a color word to replace", sa, ColorSet.fromMask(MagicColor.ALL_COLORS));
|
||||
changedColorWordOriginal = TextUtil.capitalize(MagicColor.toLongString(originalColor));
|
||||
} else {
|
||||
changedColorWordOriginal = changedColorWordsArray[0];
|
||||
originalColor = MagicColor.fromName(changedColorWordOriginal);
|
||||
}
|
||||
|
||||
if (changedColorWordsArray[1].equals("Choose")) {
|
||||
final ColorSet possibleNewColors;
|
||||
if (originalColor == 0) { // no original color (ie. any or absent)
|
||||
possibleNewColors = ColorSet.fromMask(MagicColor.ALL_COLORS);
|
||||
} else { // may choose any except original color
|
||||
possibleNewColors = ColorSet.fromMask(originalColor).inverse();
|
||||
}
|
||||
final byte newColor = sa.getActivatingPlayer().getController().chooseColor(
|
||||
"Choose a new color word", sa, possibleNewColors);
|
||||
changedColorWordNew = TextUtil.capitalize(MagicColor.toLongString(newColor));
|
||||
} else {
|
||||
changedColorWordNew = changedColorWordsArray[1];
|
||||
}
|
||||
} else {
|
||||
changedColorWordOriginal = null;
|
||||
changedColorWordNew = null;
|
||||
}
|
||||
|
||||
final String changedTypeWordOriginal, changedTypeWordNew;
|
||||
if (sa.hasParam("ChangeTypeWord")) {
|
||||
String kindOfType = "";
|
||||
final List<String> validTypes = Lists.newArrayList();
|
||||
final String[] changedTypeWordsArray = sa.getParam("ChangeTypeWord").split(" ");
|
||||
if (changedTypeWordsArray[0].equals("ChooseBasicLandType") || changedTypeWordsArray[0].equals("ChooseCreatureType")) {
|
||||
if (changedTypeWordsArray[0].equals("ChooseBasicLandType")) {
|
||||
validTypes.addAll(CardType.getBasicTypes());
|
||||
kindOfType = "basic land";
|
||||
} else if (changedTypeWordsArray[0].equals("ChooseCreatureType")) {
|
||||
validTypes.addAll(CardType.getCreatureTypes());
|
||||
kindOfType = "creature";
|
||||
}
|
||||
changedTypeWordOriginal = sa.getActivatingPlayer().getController().chooseSomeType(kindOfType, sa, validTypes, Lists.<String>newArrayList());
|
||||
} else {
|
||||
changedTypeWordOriginal = changedTypeWordsArray[0];
|
||||
}
|
||||
|
||||
validTypes.clear();
|
||||
final List<String> forbiddenTypes = sa.hasParam("ForbiddenNewTypes") ? Lists.newArrayList(sa.getParam("ForbiddenNewTypes").split(",")) : Lists.<String>newArrayList();
|
||||
forbiddenTypes.add(changedTypeWordOriginal);
|
||||
if (changedTypeWordsArray[0].startsWith("Choose")) {
|
||||
if (changedTypeWordsArray[0].equals("ChooseBasicLandType")) {
|
||||
validTypes.addAll(CardType.getBasicTypes());
|
||||
kindOfType = "basic land";
|
||||
} else if (changedTypeWordsArray[0].equals("ChooseCreatureType")) {
|
||||
validTypes.addAll(CardType.getCreatureTypes());
|
||||
kindOfType = "creature";
|
||||
}
|
||||
changedTypeWordNew = sa.getActivatingPlayer().getController().chooseSomeType(kindOfType, sa, validTypes, forbiddenTypes);
|
||||
} else {
|
||||
changedTypeWordNew = changedTypeWordsArray[1];
|
||||
}
|
||||
} else {
|
||||
changedTypeWordOriginal = null;
|
||||
changedTypeWordNew = null;
|
||||
}
|
||||
|
||||
final List<Card> tgts = getTargetCards(sa);
|
||||
for (final Card c : tgts) {
|
||||
final Long colorTimestamp;
|
||||
if (changedColorWordNew != null) {
|
||||
colorTimestamp = c.addChangedTextColorWord(changedColorWordOriginal, changedColorWordNew);
|
||||
} else {
|
||||
colorTimestamp = null;
|
||||
}
|
||||
|
||||
final Long typeTimestamp;
|
||||
if (changedTypeWordNew != null) {
|
||||
typeTimestamp = c.addChangedTextTypeWord(changedTypeWordOriginal, changedTypeWordNew);
|
||||
} else {
|
||||
typeTimestamp = null;
|
||||
}
|
||||
|
||||
if (!permanent) {
|
||||
final GameCommand revert = new GameCommand() {
|
||||
private static final long serialVersionUID = -7802388880114360593L;
|
||||
@Override
|
||||
public void run() {
|
||||
if (changedColorWordNew != null) {
|
||||
c.removeChangedTextColorWord(colorTimestamp);
|
||||
}
|
||||
if (changedTypeWordNew != null) {
|
||||
c.removeChangedTextTypeWord(typeTimestamp);
|
||||
}
|
||||
}
|
||||
};
|
||||
game.getEndOfTurn().addUntil(revert);
|
||||
}
|
||||
|
||||
game.fireEvent(new GameEventCardStatsChanged(c));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
@Override
|
||||
protected String getStackDescription(SpellAbility sa) {
|
||||
final String changedColorWordOriginal, changedColorWordNew;
|
||||
if (sa.hasParam("ChangeColorWord")) {
|
||||
final String[] changedColorWordsArray = sa.getParam("ChangeColorWord").split(" ");
|
||||
changedColorWordOriginal = changedColorWordsArray[0];
|
||||
changedColorWordNew = changedColorWordsArray[1];
|
||||
} else {
|
||||
changedColorWordOriginal = null;
|
||||
changedColorWordNew = null;
|
||||
}
|
||||
|
||||
final String changedTypeWordOriginal, changedTypeWordNew;
|
||||
if (sa.hasParam("ChangeTypeWord")) {
|
||||
final String[] changedTypeWordsArray = sa.getParam("ChangeTypeWord").split(" ");
|
||||
changedTypeWordOriginal = changedTypeWordsArray[0];
|
||||
changedTypeWordNew = changedTypeWordsArray[1];
|
||||
} else {
|
||||
changedTypeWordOriginal = null;
|
||||
changedTypeWordNew = null;
|
||||
}
|
||||
|
||||
final boolean permanent = sa.hasParam("Permanent");
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Change the text of ");
|
||||
|
||||
final List<Card> tgts = getTargetCards(sa);
|
||||
for (final Card c : tgts) {
|
||||
sb.append(c).append(" ");
|
||||
}
|
||||
|
||||
if (changedColorWordOriginal != null) {
|
||||
sb.append(" by replacing all instances of ");
|
||||
if (changedColorWordOriginal.equals("Choose")) {
|
||||
sb.append("one color word");
|
||||
} else if (changedColorWordOriginal.equals("Any")) {
|
||||
sb.append("each color word");
|
||||
} else {
|
||||
sb.append(changedColorWordOriginal);
|
||||
}
|
||||
sb.append(" with ");
|
||||
if (changedColorWordNew.equals("Choose")) {
|
||||
if (changedColorWordOriginal.equals("Choose")) {
|
||||
sb.append("another");
|
||||
} else {
|
||||
sb.append("a color word of your choice");
|
||||
}
|
||||
} else {
|
||||
sb.append(changedColorWordNew);
|
||||
}
|
||||
}
|
||||
|
||||
if (changedTypeWordOriginal != null) {
|
||||
sb.append(" by replacing all instances of ");
|
||||
if (changedTypeWordOriginal.equals("ChooseBasicLandType")) {
|
||||
sb.append("one basic land type");
|
||||
} else if (changedTypeWordOriginal.equals("ChooseCreatureType")) {
|
||||
sb.append("one creature type");
|
||||
} else {
|
||||
sb.append(changedTypeWordOriginal);
|
||||
}
|
||||
sb.append(" with ");
|
||||
if (changedTypeWordNew.equals("ChooseBasicLandType")) {
|
||||
if (changedTypeWordOriginal.equals("ChooseBasicLandType")) {
|
||||
sb.append("another");
|
||||
} else {
|
||||
sb.append("a basic land type of your choice");
|
||||
}
|
||||
} else if (changedTypeWordNew.equals("ChooseCreatureType")) {
|
||||
if (changedTypeWordOriginal.equals("ChooseCreatureType")) {
|
||||
sb.append("another");
|
||||
} else {
|
||||
sb.append("a creature type of your choice");
|
||||
}
|
||||
} else {
|
||||
sb.append(changedTypeWordNew);
|
||||
}
|
||||
}
|
||||
|
||||
if (!permanent) {
|
||||
sb.append(" until end of turn");
|
||||
}
|
||||
sb.append('.');
|
||||
|
||||
if (sa.hasParam("ForbiddenNewTypes")) {
|
||||
sb.append(" The new creature type can't be ");
|
||||
sb.append(sa.getParam("ForbiddenNewTypes"));
|
||||
sb.append('.');
|
||||
}
|
||||
|
||||
if (permanent) {
|
||||
sb.append(" (This effect lasts indefinitely.)");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -518,7 +518,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
movedCard = game.getAction().moveTo(destination, tgtC);
|
||||
// If a card is Exiled from the stack, remove its spells from the stack
|
||||
if (sa.hasParam("Fizzle")) {
|
||||
ArrayList<SpellAbility> spells = tgtC.getSpellAbilities();
|
||||
final List<SpellAbility> spells = tgtC.getSpellAbilities();
|
||||
for (SpellAbility spell : spells) {
|
||||
if (tgtC.isInZone(ZoneType.Exile) || tgtC.isInZone(ZoneType.Hand)) {
|
||||
final SpellAbilityStackInstance si = game.getStack().getInstanceFromSpellAbility(spell);
|
||||
|
||||
@@ -20,7 +20,9 @@ package forge.game.card;
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import forge.GameCommand;
|
||||
import forge.StaticData;
|
||||
@@ -118,6 +120,12 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
private Map<Long, CardType> changedCardTypes = new ConcurrentSkipListMap<Long, CardType>();
|
||||
private Map<Long, CardKeywords> changedCardKeywords = new ConcurrentSkipListMap<Long, CardKeywords>();
|
||||
|
||||
// changes that say "replace each instance of one [color,type] by another - timestamp is the key of maps
|
||||
private final CardChangedWords changedTextColors = new CardChangedWords();
|
||||
private final CardChangedWords changedTextTypes = new CardChangedWords();
|
||||
/** List of the keywords that have been added by text changes. */
|
||||
private final List<String> keywordsGrantedByTextChanges = Lists.newArrayList();
|
||||
|
||||
private final ArrayList<Object> rememberedObjects = new ArrayList<Object>();
|
||||
private final MapOfLists<GameEntity, Object> rememberMap = new HashMapOfLists<GameEntity, Object>(CollectionSuppliers.<Object>arrayLists());
|
||||
private final ArrayList<Card> imprintedCards = new ArrayList<Card>();
|
||||
@@ -2389,6 +2397,18 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
}
|
||||
|
||||
for (final Entry<String, String> e : Sets.union(this.changedTextColors.toMap().entrySet(),
|
||||
this.changedTextTypes.toMap().entrySet())) {
|
||||
// only the upper case ones, to avoid duplicity
|
||||
if (Character.isUpperCase(e.getKey().charAt(0))) {
|
||||
sb.append("Text changed: all instances of ");
|
||||
sb.append(e.getKey());
|
||||
sb.append(" are replaced by ");
|
||||
sb.append(e.getValue());
|
||||
sb.append(".\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE:
|
||||
if (sb.toString().contains(" (NOTE: ")) {
|
||||
sb.insert(sb.indexOf("(NOTE: "), "\r\n");
|
||||
@@ -2594,7 +2614,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
return Collections.unmodifiableList(this.getCharacteristics().getManaAbility());
|
||||
}
|
||||
|
||||
|
||||
public final boolean canProduceSameManaTypeWith(final Card c) {
|
||||
final List<SpellAbility> manaAb = this.getManaAbility();
|
||||
if (manaAb.isEmpty()) {
|
||||
@@ -2691,7 +2710,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
* a {@link forge.game.spellability.SpellAbility} object.
|
||||
*/
|
||||
public final void addSpellAbility(final SpellAbility a) {
|
||||
|
||||
a.setHostCard(this);
|
||||
if (a.isManaAbility()) {
|
||||
this.getCharacteristics().getManaAbility().add(a);
|
||||
@@ -2700,7 +2718,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* removeSpellAbility.
|
||||
@@ -2726,7 +2743,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
*
|
||||
* @return a {@link java.util.ArrayList} object.
|
||||
*/
|
||||
public final ArrayList<SpellAbility> getSpellAbilities() {
|
||||
public final List<SpellAbility> getSpellAbilities() {
|
||||
final ArrayList<SpellAbility> res = new ArrayList<SpellAbility>(this.getManaAbility());
|
||||
res.addAll(this.getCharacteristics().getSpellAbility());
|
||||
return res;
|
||||
@@ -4483,9 +4500,10 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
*
|
||||
* @param timestamp
|
||||
* the timestamp
|
||||
* @return the removed {@link CardKeywords}.
|
||||
*/
|
||||
public final void removeChangedCardKeywords(final long timestamp) {
|
||||
changedCardKeywords.remove(Long.valueOf(timestamp));
|
||||
public final CardKeywords removeChangedCardKeywords(final long timestamp) {
|
||||
return changedCardKeywords.remove(Long.valueOf(timestamp));
|
||||
}
|
||||
|
||||
// Hidden keywords will be left out
|
||||
@@ -4518,6 +4536,97 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all instances of one color word in this card's text by another.
|
||||
* @param originalWord the original color word.
|
||||
* @param newWord the new color word.
|
||||
* @return the timestamp.
|
||||
* @throws RuntimeException if either of the strings is not a valid Magic
|
||||
* color.
|
||||
*/
|
||||
public final Long addChangedTextColorWord(final String originalWord, final String newWord) {
|
||||
if (MagicColor.fromName(newWord) == 0) {
|
||||
throw new RuntimeException("Not a color: " + newWord);
|
||||
}
|
||||
final Long timestamp = this.changedTextColors.add(this.getGame().getNextTimestamp(), originalWord, newWord);
|
||||
this.updateKeywordsChangedText(originalWord, newWord, timestamp);
|
||||
this.updateChangedText();
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public final void removeChangedTextColorWord(final Long timestamp) {
|
||||
this.changedTextColors.remove(timestamp);
|
||||
this.updateKeywordsOnRemoveChangedText(
|
||||
this.removeChangedCardKeywords(timestamp.longValue()));
|
||||
this.updateChangedText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all instances of one type in this card's text by another.
|
||||
* @param originalWord the original type word.
|
||||
* @param newWord the new type word.
|
||||
*/
|
||||
public final Long addChangedTextTypeWord(final String originalWord, final String newWord) {
|
||||
final Long timestamp = this.changedTextTypes.add(this.getGame().getNextTimestamp(), originalWord, newWord);
|
||||
if (this.getType().contains(originalWord)) {
|
||||
this.addChangedCardTypes(Lists.newArrayList(newWord), Lists.newArrayList(originalWord), false, false, false, false, timestamp);
|
||||
}
|
||||
this.updateKeywordsChangedText(originalWord, newWord, timestamp);
|
||||
this.updateChangedText();
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public final void removeChangedTextTypeWord(final Long timestamp) {
|
||||
this.changedTextTypes.remove(timestamp);
|
||||
this.removeChangedCardTypes(timestamp);
|
||||
this.updateKeywordsOnRemoveChangedText(
|
||||
this.removeChangedCardKeywords(timestamp.longValue()));
|
||||
this.updateChangedText();
|
||||
}
|
||||
|
||||
private final void updateKeywordsChangedText(final String originalWord, final String newWord, final Long timestamp) {
|
||||
final List<String> addKeywords = Lists.newArrayList(),
|
||||
removeKeywords = Lists.newArrayList(this.keywordsGrantedByTextChanges);
|
||||
|
||||
for (final String kw : this.getIntrinsicKeyword()) {
|
||||
final String newKw = AbilityUtils.applyTextChangeEffects(kw, this);
|
||||
if (!newKw.equals(kw)) {
|
||||
addKeywords.add(newKw);
|
||||
removeKeywords.add(kw);
|
||||
this.keywordsGrantedByTextChanges.add(newKw);
|
||||
}
|
||||
}
|
||||
this.addChangedCardKeywords(addKeywords, removeKeywords, false, timestamp.longValue());
|
||||
}
|
||||
|
||||
private final void updateKeywordsOnRemoveChangedText(final CardKeywords k) {
|
||||
this.keywordsGrantedByTextChanges.removeAll(k.getKeywords());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the changed text of the intrinsic spell abilities and keywords.
|
||||
*/
|
||||
private final void updateChangedText() {
|
||||
final List<CardTraitBase> allAbs = Lists.newLinkedList();
|
||||
allAbs.addAll(this.getSpellAbilities());
|
||||
allAbs.addAll(this.getStaticAbilities());
|
||||
allAbs.addAll(this.getReplacementEffects());
|
||||
allAbs.addAll(this.getTriggers());
|
||||
for (final CardTraitBase ctb : allAbs) {
|
||||
if (ctb.isIntrinsic()) {
|
||||
ctb.changeText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final ImmutableMap<String, String> getChangedTextColorWords() {
|
||||
return ImmutableMap.copyOf(changedTextColors.toMap());
|
||||
}
|
||||
|
||||
public final ImmutableMap<String, String> getChangedTextTypeWords() {
|
||||
return ImmutableMap.copyOf(changedTextTypes.toMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getIntrinsicAbilities.
|
||||
@@ -4542,19 +4651,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
return this.getCharacteristics().getIntrinsicKeyword();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>intrinsicKeyword</code>.
|
||||
* </p>
|
||||
*
|
||||
* @param a
|
||||
* a {@link java.util.ArrayList} object.
|
||||
*/
|
||||
public final void setIntrinsicKeyword(final List<String> a) {
|
||||
this.getCharacteristics().setIntrinsicKeyword(new ArrayList<String>(a));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* setIntrinsicAbilities.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package forge.game.card;
|
||||
|
||||
public class CardChangedWord {
|
||||
|
||||
private final String originalWord,
|
||||
newWord;
|
||||
|
||||
public CardChangedWord(final String originalWord, final String newWord) {
|
||||
this.originalWord = originalWord;
|
||||
this.newWord = newWord;
|
||||
}
|
||||
|
||||
public String getOriginalWord() {
|
||||
return originalWord;
|
||||
}
|
||||
|
||||
public String getNewWord() {
|
||||
return newWord;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package forge.game.card;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.SortedMap;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public final class CardChangedWords {
|
||||
|
||||
private final SortedMap<Long, CardChangedWord> map = Maps.newTreeMap();
|
||||
|
||||
private boolean isDirty = false;
|
||||
private Map<String, String> resultCache = Maps.newHashMap();
|
||||
|
||||
public CardChangedWords() {
|
||||
}
|
||||
|
||||
public Long add(final long timestamp, final String originalWord, final String newWord) {
|
||||
final Long stamp = Long.valueOf(timestamp);
|
||||
map.put(stamp, new CardChangedWord(originalWord, newWord));
|
||||
isDirty = true;
|
||||
return stamp;
|
||||
}
|
||||
|
||||
public void remove(final Long timestamp) {
|
||||
map.remove(timestamp);
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this object to a {@link Map}.
|
||||
*
|
||||
* @return a map of strings to strings, where each changed word in this
|
||||
* object is mapped to its corresponding replacement word.
|
||||
*/
|
||||
public Map<String, String> toMap() {
|
||||
refreshCache();
|
||||
return resultCache;
|
||||
}
|
||||
|
||||
private void refreshCache() {
|
||||
if (isDirty) {
|
||||
resultCache = Maps.newHashMap();
|
||||
for (final CardChangedWord ccw : this.map.values()) {
|
||||
for (final Entry<String, String> e : resultCache.entrySet()) {
|
||||
if (e.getValue().equals(ccw.getOriginalWord())) {
|
||||
e.setValue(ccw.getNewWord());
|
||||
}
|
||||
}
|
||||
|
||||
resultCache.put(ccw.getOriginalWord(), ccw.getNewWord());
|
||||
}
|
||||
for (final String key : ImmutableList.copyOf(resultCache.keySet())) {
|
||||
resultCache.put(key.toLowerCase(), resultCache.get(key).toLowerCase());
|
||||
}
|
||||
isDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import forge.game.cost.Cost;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.replacement.ReplacementHandler;
|
||||
import forge.game.spellability.*;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.trigger.TriggerHandler;
|
||||
import forge.game.trigger.WrappedAbility;
|
||||
@@ -288,11 +289,11 @@ public class CardFactory {
|
||||
card.setState(state);
|
||||
CardFactoryUtil.addAbilityFactoryAbilities(card);
|
||||
for (String stAb : card.getStaticAbilityStrings()) {
|
||||
card.addStaticAbility(stAb);
|
||||
final StaticAbility s = card.addStaticAbility(stAb);
|
||||
s.setIntrinsic(true);
|
||||
}
|
||||
|
||||
|
||||
if ( state == CardCharacteristicName.LeftSplit || state == CardCharacteristicName.RightSplit )
|
||||
if (state == CardCharacteristicName.LeftSplit || state == CardCharacteristicName.RightSplit)
|
||||
{
|
||||
CardCharacteristics original = card.getState(CardCharacteristicName.Original);
|
||||
original.getSpellAbility().addAll(card.getCharacteristics().getSpellAbility());
|
||||
|
||||
@@ -681,8 +681,8 @@ public class CardFactoryUtil {
|
||||
|
||||
return doXMath(n, m, source);
|
||||
}
|
||||
|
||||
public static int playerXProperty(Player player, String s, Card source) {
|
||||
|
||||
public static int playerXProperty(final Player player, final String s, final Card source) {
|
||||
final String[] l = s.split("/");
|
||||
final String m = extractOperators(s);
|
||||
|
||||
@@ -824,7 +824,7 @@ public class CardFactoryUtil {
|
||||
final Player cc = c.getController();
|
||||
final Game game = c.getGame();
|
||||
final Player activePlayer = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
|
||||
final String[] l = expression.split("/");
|
||||
final String m = extractOperators(expression);
|
||||
|
||||
@@ -845,7 +845,7 @@ public class CardFactoryUtil {
|
||||
if (l[0].startsWith("SVar$")) {
|
||||
return doXMath(xCount(c, c.getSVar(l[0].substring(5))), m, c);
|
||||
}
|
||||
|
||||
|
||||
if (l[0].startsWith("Controller$"))
|
||||
return playerXProperty(cc, l[0].substring(11), c);
|
||||
|
||||
@@ -1975,7 +1975,9 @@ public class CardFactoryUtil {
|
||||
// **************************************************
|
||||
// AbilityFactory cards
|
||||
for (String rawAbility : card.getUnparsedAbilities()) {
|
||||
card.addSpellAbility(AbilityFactory.getAbility(rawAbility, card));
|
||||
final SpellAbility intrinsicAbility = AbilityFactory.getAbility(rawAbility, card);
|
||||
card.addSpellAbility(intrinsicAbility);
|
||||
intrinsicAbility.setIntrinsic(true);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
@@ -58,6 +58,7 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
||||
*/
|
||||
public ReplacementEffect(final Map<String, String> map, final Card host, final boolean intrinsic) {
|
||||
this.intrinsic = intrinsic;
|
||||
originalMapParams.putAll(map);
|
||||
mapParams.putAll(map);
|
||||
this.setHostCard(host);
|
||||
}
|
||||
|
||||
@@ -192,6 +192,10 @@ public class ReplacementHandler implements IGameStateObject {
|
||||
} while(tailend != null);
|
||||
}
|
||||
|
||||
if (effectSA.isIntrinsic()) {
|
||||
effectSA.changeText();
|
||||
}
|
||||
|
||||
// Decider gets to choose whether or not to apply the replacement.
|
||||
if (replacementEffect.getMapParams().containsKey("Optional")) {
|
||||
Player optDecider = decider;
|
||||
|
||||
@@ -86,8 +86,11 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab
|
||||
this.setTargetRestrictions(tgt);
|
||||
|
||||
api = api0;
|
||||
if (params0 != null)
|
||||
if (params0 != null) {
|
||||
originalMapParams.putAll(params0);
|
||||
mapParams.putAll(params0);
|
||||
}
|
||||
|
||||
effect = api.getSpellEffect();
|
||||
|
||||
if (effect instanceof ManaEffect || effect instanceof ManaReflectedEffect) {
|
||||
|
||||
@@ -1773,4 +1773,17 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
public void setChosenList(List<AbilitySub> choices) {
|
||||
this.chosenList = choices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeText() {
|
||||
super.changeText();
|
||||
|
||||
if (this.targetRestricions != null) {
|
||||
this.targetRestricions.applyTargetTextChanges(this);
|
||||
}
|
||||
|
||||
if (this.subAbility != null) {
|
||||
this.subAbility.changeText();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -47,7 +48,8 @@ public class TargetRestrictions {
|
||||
|
||||
// What this Object is restricted to targeting
|
||||
private boolean tgtValid = false;
|
||||
private String[] validTgts;
|
||||
private String[] originalValidTgts,
|
||||
validTgts;
|
||||
private String uiPrompt = "";
|
||||
private List<ZoneType> tgtZone = Arrays.asList(ZoneType.Battlefield);
|
||||
|
||||
@@ -86,7 +88,8 @@ public class TargetRestrictions {
|
||||
public TargetRestrictions(final TargetRestrictions target) {
|
||||
this.tgtValid = true;
|
||||
this.uiPrompt = target.getVTSelection();
|
||||
this.validTgts = target.getValidTgts();
|
||||
this.originalValidTgts = target.getValidTgts();
|
||||
this.validTgts = this.originalValidTgts.clone();
|
||||
this.minTargets = target.getMinTargets();
|
||||
this.maxTargets = target.getMaxTargets();
|
||||
this.tgtZone = target.getZone();
|
||||
@@ -120,7 +123,8 @@ public class TargetRestrictions {
|
||||
public TargetRestrictions(final String prompt, final String[] valid, final String min, final String max) {
|
||||
this.tgtValid = true;
|
||||
this.uiPrompt = prompt;
|
||||
this.validTgts = valid;
|
||||
this.originalValidTgts = valid;
|
||||
this.validTgts = this.originalValidTgts.clone();
|
||||
this.minTargets = min;
|
||||
this.maxTargets = max;
|
||||
}
|
||||
@@ -418,7 +422,9 @@ public class TargetRestrictions {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.applyTargetTextChanges(sa);
|
||||
|
||||
final Card srcCard = sa.getHostCard(); // should there be OrginalHost at any moment?
|
||||
if (this.tgtZone.contains(ZoneType.Stack)) {
|
||||
// Stack Zone targets are considered later
|
||||
@@ -476,6 +482,8 @@ public class TargetRestrictions {
|
||||
}
|
||||
}
|
||||
|
||||
this.applyTargetTextChanges(sa);
|
||||
|
||||
final Card srcCard = sa.getHostCard(); // should there be OrginalHost at any moment?
|
||||
if (this.tgtZone.contains(ZoneType.Stack)) {
|
||||
for (final Card c : game.getStackZone().getCards()) {
|
||||
@@ -655,7 +663,7 @@ public class TargetRestrictions {
|
||||
public void setStillToDivide(final int remaining) {
|
||||
this.stillToDivide = remaining;
|
||||
}
|
||||
|
||||
|
||||
public void calculateStillToDivide(String toDistribute, Card source, SpellAbility sa) {
|
||||
// Recalculate this value just in case it's variable
|
||||
if (!this.dividedAsYouChoose) {
|
||||
@@ -698,4 +706,10 @@ public class TargetRestrictions {
|
||||
return this.dividedMap;
|
||||
}
|
||||
|
||||
public final void applyTargetTextChanges(final SpellAbility sa) {
|
||||
for (int i = 0; i < validTgts.length; i++) {
|
||||
validTgts[i] = AbilityUtils.applyTextChangeEffects(originalValidTgts[i], sa.getHostCard());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ public class StaticAbility extends CardTraitBase {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (this.mapParams.containsKey("ChangeText")) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (this.mapParams.containsKey("AddType") || this.mapParams.containsKey("RemoveType")
|
||||
|| this.mapParams.containsKey("RemoveCardTypes") || this.mapParams.containsKey("RemoveSubTypes")
|
||||
|| this.mapParams.containsKey("RemoveSuperTypes") || this.mapParams.containsKey("RemoveCreatureTypes")) {
|
||||
@@ -170,7 +174,9 @@ public class StaticAbility extends CardTraitBase {
|
||||
* the host
|
||||
*/
|
||||
public StaticAbility(final String params, final Card host) {
|
||||
this.mapParams.putAll(this.parseParams(params, host));
|
||||
final Map<String, String> parsedParams = this.parseParams(params, host);
|
||||
this.originalMapParams.putAll(parsedParams);
|
||||
this.mapParams.putAll(parsedParams);
|
||||
this.hostCard = host;
|
||||
this.layer = this.generateLayer();
|
||||
}
|
||||
@@ -183,10 +189,9 @@ public class StaticAbility extends CardTraitBase {
|
||||
* @param host
|
||||
* the host
|
||||
*/
|
||||
public StaticAbility(final HashMap<String, String> params, final Card host) {
|
||||
for (final Map.Entry<String, String> entry : params.entrySet()) {
|
||||
this.mapParams.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
public StaticAbility(final Map<String, String> params, final Card host) {
|
||||
this.originalMapParams.putAll(params);
|
||||
this.mapParams.putAll(params);
|
||||
this.layer = this.generateLayer();
|
||||
this.hostCard = host;
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ public abstract class Trigger extends TriggerReplacementBase {
|
||||
this.intrinsic = intrinsic;
|
||||
|
||||
this.setRunParams(new HashMap<String, Object>());
|
||||
this.originalMapParams.putAll(params);
|
||||
this.mapParams.putAll(params);
|
||||
this.setHostCard(host);
|
||||
}
|
||||
@@ -441,8 +442,8 @@ public abstract class Trigger extends TriggerReplacementBase {
|
||||
|
||||
|
||||
public final Trigger getCopyForHostCard(Card newHost) {
|
||||
TriggerType tt = TriggerType.getTypeFor(this);
|
||||
Trigger copy = tt.createTrigger(mapParams, newHost, intrinsic);
|
||||
final TriggerType tt = TriggerType.getTypeFor(this);
|
||||
final Trigger copy = tt.createTrigger(originalMapParams, newHost, intrinsic);
|
||||
|
||||
if (this.getOverridingAbility() != null) {
|
||||
copy.setOverridingAbility(this.getOverridingAbility());
|
||||
|
||||
@@ -390,6 +390,10 @@ public class TriggerHandler implements IGameStateObject {
|
||||
host.addRemembered(sa.getActivatingPlayer());
|
||||
}
|
||||
|
||||
if (regtrig.isIntrinsic()) {
|
||||
sa.changeText();
|
||||
}
|
||||
|
||||
sa.setStackDescription(sa.toString());
|
||||
if (sa.getApi() == ApiType.Charm && !sa.isWrapper()) {
|
||||
CharmEffect.makeChoices(sa);
|
||||
|
||||
Reference in New Issue
Block a user