* replaces all [source} by {this}. ATTENTION !!!: Only supporting [this} from now on in rule text.

This commit is contained in:
LevelX2 2020-08-22 12:52:49 +02:00
parent d51acbf090
commit c16fb75668
91 changed files with 229 additions and 236 deletions

View file

@ -391,7 +391,7 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener {
List<Object> objectList = new ArrayList<>(); List<Object> objectList = new ArrayList<>();
objectList.add("T: add {R}. 111111111111111111111111111"); objectList.add("T: add {R}. 111111111111111111111111111");
objectList.add("T: add {B}. {source} deals 1 damage to you."); objectList.add("T: add {B}. {this} deals 1 damage to you.");
objectList.add("{T}: add {B}"); objectList.add("{T}: add {B}");
objectList.add("T: add {B}"); objectList.add("T: add {B}");
objectList.add("T: add {B}"); objectList.add("T: add {B}");

View file

@ -1,5 +1,23 @@
package org.mage.card.arcane; package org.mage.card.arcane;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
import javax.imageio.ImageIO;
import javax.swing.*;
import mage.abilities.hint.HintUtils; import mage.abilities.hint.HintUtils;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
import mage.cards.repository.ExpansionRepository; import mage.cards.repository.ExpansionRepository;
@ -22,27 +40,6 @@ import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.util.SVGConstants; import org.apache.batik.util.SVGConstants;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
public final class ManaSymbols { public final class ManaSymbols {
@ -173,7 +170,7 @@ public final class ManaSymbols {
} }
// preload set images // preload set images
List<String> setCodes = ExpansionRepository.instance.getSetCodes(); java.util.List<String> setCodes = ExpansionRepository.instance.getSetCodes();
if (setCodes == null) { if (setCodes == null) {
// the cards db file is probaly not included in the client. It will be created after the first connect to a server. // the cards db file is probaly not included in the client. It will be created after the first connect to a server.
LOGGER.warn("No db information for sets found. Connect to a server to create database file on client side. Then try to restart the client."); LOGGER.warn("No db information for sets found. Connect to a server to create database file on client side. Then try to restart the client.");
@ -713,7 +710,7 @@ public final class ManaSymbols {
} }
public static String getStringManaCost(List<String> manaCost) { public static String getStringManaCost(java.util.List<String> manaCost) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (String s : manaCost) { for (String s : manaCost) {
sb.append(s); sb.append(s);
@ -778,7 +775,6 @@ public final class ManaSymbols {
// replace every {symbol} to <img> link // replace every {symbol} to <img> link
// ignore data backup // ignore data backup
String replaced = value String replaced = value
.replace("{source}", "|source|")
.replace("{this}", "|this|"); .replace("{this}", "|this|");
// not need to add different images (width and height do the work) // not need to add different images (width and height do the work)
@ -808,7 +804,6 @@ public final class ManaSymbols {
// ignored data restore // ignored data restore
replaced = replaced replaced = replaced
.replace("|source|", "{source}")
.replace("|this|", "{this}") .replace("|this|", "{this}")
.replace("@S@", "$"); .replace("@S@", "$");

View file

@ -1,5 +1,18 @@
package mage.player.human; package mage.player.human;
import java.awt.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import mage.MageObject; import mage.MageObject;
import mage.abilities.*; import mage.abilities.*;
import mage.abilities.costs.VariableCost; import mage.abilities.costs.VariableCost;
@ -17,6 +30,8 @@ import mage.cards.decks.Deck;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.constants.*; import mage.constants.*;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterAttackingCreature; import mage.filter.common.FilterAttackingCreature;
import mage.filter.common.FilterBlockingCreature; import mage.filter.common.FilterBlockingCreature;
@ -47,16 +62,6 @@ import mage.util.ManaUtil;
import mage.util.MessageToClient; import mage.util.MessageToClient;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.awt.*;
import java.io.Serializable;
import java.util.List;
import java.util.Queue;
import java.util.*;
import java.util.stream.Collectors;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -301,7 +306,6 @@ public class HumanPlayer extends PlayerImpl {
} }
} }
while (canRespond()) { while (canRespond()) {
if (messageToClient.getSecondMessage() == null) { if (messageToClient.getSecondMessage() == null) {
messageToClient.setSecondMessage(getRelatedObjectName(source, game)); messageToClient.setSecondMessage(getRelatedObjectName(source, game));
@ -490,7 +494,7 @@ public class HumanPlayer extends PlayerImpl {
required = false; required = false;
} }
List<UUID> chosen = target.getTargets(); java.util.List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen); options.put("chosen", (Serializable) chosen);
updateGameStatePriority("choose(5)", game); updateGameStatePriority("choose(5)", game);
@ -656,9 +660,9 @@ public class HumanPlayer extends PlayerImpl {
} }
Map<String, Serializable> options = getOptions(target, null); Map<String, Serializable> options = getOptions(target, null);
List<UUID> chosen = target.getTargets(); java.util.List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen); options.put("chosen", (Serializable) chosen);
List<UUID> choosable = new ArrayList<>(); java.util.List<UUID> choosable = new ArrayList<>();
for (UUID cardId : cards) { for (UUID cardId : cards) {
if (target.canTarget(abilityControllerId, cardId, null, cards, game)) { if (target.canTarget(abilityControllerId, cardId, null, cards, game)) {
choosable.add(cardId); choosable.add(cardId);
@ -730,9 +734,9 @@ public class HumanPlayer extends PlayerImpl {
} }
Map<String, Serializable> options = getOptions(target, null); Map<String, Serializable> options = getOptions(target, null);
List<UUID> chosen = target.getTargets(); java.util.List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen); options.put("chosen", (Serializable) chosen);
List<UUID> choosable = new ArrayList<>(); java.util.List<UUID> choosable = new ArrayList<>();
for (UUID cardId : cards) { for (UUID cardId : cards) {
if (target.canTarget(abilityControllerId, cardId, source, cards, game)) { if (target.canTarget(abilityControllerId, cardId, source, cards, game)) {
choosable.add(cardId); choosable.add(cardId);
@ -1131,7 +1135,7 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game) { public TriggeredAbility chooseTriggeredAbility(java.util.List<TriggeredAbility> abilities, Game game) {
// choose triggered abilitity from list // choose triggered abilitity from list
if (gameInCheckPlayableState(game)) { if (gameInCheckPlayableState(game)) {
return null; return null;
@ -1141,7 +1145,7 @@ public class HumanPlayer extends PlayerImpl {
boolean autoOrderUse = getControllingPlayersUserData(game).isAutoOrderTrigger(); boolean autoOrderUse = getControllingPlayersUserData(game).isAutoOrderTrigger();
while (canRespond()) { while (canRespond()) {
// try to set trigger auto order // try to set trigger auto order
List<TriggeredAbility> abilitiesWithNoOrderSet = new ArrayList<>(); java.util.List<TriggeredAbility> abilitiesWithNoOrderSet = new ArrayList<>();
TriggeredAbility abilityOrderLast = null; TriggeredAbility abilityOrderLast = null;
for (TriggeredAbility ability : abilities) { for (TriggeredAbility ability : abilities) {
if (triggerAutoOrderAbilityFirst.contains(ability.getOriginalId())) { if (triggerAutoOrderAbilityFirst.contains(ability.getOriginalId())) {
@ -1399,7 +1403,7 @@ public class HumanPlayer extends PlayerImpl {
filter.add(new ControllerIdPredicate(attackingPlayerId)); filter.add(new ControllerIdPredicate(attackingPlayerId));
while (canRespond()) { while (canRespond()) {
List<UUID> possibleAttackers = new ArrayList<>(); java.util.List<UUID> possibleAttackers = new ArrayList<>();
for (Permanent possibleAttacker : game.getBattlefield().getActivePermanents(filter, attackingPlayerId, game)) { for (Permanent possibleAttacker : game.getBattlefield().getActivePermanents(filter, attackingPlayerId, game)) {
if (possibleAttacker.canAttack(null, game)) { if (possibleAttacker.canAttack(null, game)) {
possibleAttackers.add(possibleAttacker.getId()); possibleAttackers.add(possibleAttacker.getId());
@ -1682,7 +1686,7 @@ public class HumanPlayer extends PlayerImpl {
prepareForResponse(game); prepareForResponse(game);
if (!isExecutingMacro()) { if (!isExecutingMacro()) {
Map<String, Serializable> options = new HashMap<>(); Map<String, Serializable> options = new HashMap<>();
List<UUID> possibleBlockers = game.getBattlefield().getActivePermanents(filter, playerId, game).stream() java.util.List<UUID> possibleBlockers = game.getBattlefield().getActivePermanents(filter, playerId, game).stream()
.map(p -> p.getId()) .map(p -> p.getId())
.collect(Collectors.toList()); .collect(Collectors.toList());
options.put(Constants.Option.POSSIBLE_BLOCKERS, (Serializable) possibleBlockers); options.put(Constants.Option.POSSIBLE_BLOCKERS, (Serializable) possibleBlockers);
@ -1715,7 +1719,7 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) { public UUID chooseAttackerOrder(java.util.List<Permanent> attackers, Game game) {
if (gameInCheckPlayableState(game)) { if (gameInCheckPlayableState(game)) {
return null; return null;
} }
@ -1740,7 +1744,7 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) { public UUID chooseBlockerOrder(java.util.List<Permanent> blockers, CombatGroup combatGroup, java.util.List<UUID> blockerOrder, Game game) {
if (gameInCheckPlayableState(game)) { if (gameInCheckPlayableState(game)) {
return null; return null;
} }
@ -1809,7 +1813,7 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public void assignDamage(int damage, List<UUID> targets, String singleTargetName, UUID sourceId, Game game) { public void assignDamage(int damage, java.util.List<UUID> targets, String singleTargetName, UUID sourceId, Game game) {
updateGameStatePriority("assignDamage", game); updateGameStatePriority("assignDamage", game);
int remainingDamage = damage; int remainingDamage = damage;
while (remainingDamage > 0 && canRespond()) { while (remainingDamage > 0 && canRespond()) {
@ -1873,7 +1877,7 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public void pickCard(List<Card> cards, Deck deck, Draft draft) { public void pickCard(java.util.List<Card> cards, Deck deck, Draft draft) {
draft.firePickCardEvent(playerId); draft.firePickCardEvent(playerId);
} }
@ -2056,7 +2060,7 @@ public class HumanPlayer extends PlayerImpl {
if (mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and needed targets have to be available if (mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and needed targets have to be available
String modeText = mode.getEffects().getText(mode); String modeText = mode.getEffects().getText(mode);
if (obj != null) { if (obj != null) {
modeText = modeText.replace("{source}", obj.getName()).replace("{this}", obj.getName()); modeText = modeText.replace("{this}", obj.getName());
} }
if (modes.isEachModeMoreThanOnce()) { if (modes.isEachModeMoreThanOnce()) {
if (timesSelected > 0) { if (timesSelected > 0) {
@ -2131,7 +2135,7 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public boolean choosePile(Outcome outcome, String message, List<? extends Card> pile1, List<? extends Card> pile2, Game game) { public boolean choosePile(Outcome outcome, String message, java.util.List<? extends Card> pile1, java.util.List<? extends Card> pile2, Game game) {
if (gameInCheckPlayableState(game)) { if (gameInCheckPlayableState(game)) {
return true; return true;
} }

View file

@ -35,7 +35,7 @@ public final class AbyssalHunter extends CardImpl {
// {B}, {tap}: Tap target creature. Abyssal Hunter deals damage equal to Abyssal Hunter's power to that creature. // {B}, {tap}: Tap target creature. Abyssal Hunter deals damage equal to Abyssal Hunter's power to that creature.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new ManaCostsImpl("{B}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new ManaCostsImpl("{B}"));
Effect effect = new DamageTargetEffect(new SourcePermanentPowerCount()); Effect effect = new DamageTargetEffect(new SourcePermanentPowerCount());
effect.setText("{source} deals damage equal to {source}'s power to that creature."); effect.setText("{this} deals damage equal to {this}'s power to that creature.");
ability.addEffect(effect); ability.addEffect(effect);
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent());

View file

@ -30,7 +30,7 @@ public final class AccumulatedKnowledge extends CardImpl {
// Draw a card, then draw cards equal to the number of cards named Accumulated Knowledge in all graveyards. // Draw a card, then draw cards equal to the number of cards named Accumulated Knowledge in all graveyards.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
Effect effect = new DrawCardSourceControllerEffect(new CardsInAllGraveyardsCount(filter)); Effect effect = new DrawCardSourceControllerEffect(new CardsInAllGraveyardsCount(filter));
effect.setText(", then draw cards equal to the number of cards named {source} in all graveyards"); effect.setText(", then draw cards equal to the number of cards named {this} in all graveyards");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
} }

View file

@ -68,7 +68,7 @@ class ArcTrailEffect extends OneShotEffect {
private ArcTrailEffect() { private ArcTrailEffect() {
super(Outcome.Damage); super(Outcome.Damage);
staticText = "{source} deals 2 damage to any target and 1 damage to another target"; staticText = "{this} deals 2 damage to any target and 1 damage to another target";
} }
@Override @Override

View file

@ -30,7 +30,7 @@ public final class ArmedResponse extends CardImpl {
// Armed Response deals damage to target attacking creature equal to the number of Equipment you control. // Armed Response deals damage to target attacking creature equal to the number of Equipment you control.
Effect effect = new DamageTargetEffect(new PermanentsOnBattlefieldCount(filter)); Effect effect = new DamageTargetEffect(new PermanentsOnBattlefieldCount(filter));
effect.setText("{source} deals damage to target attacking creature equal to the number of Equipment you control"); effect.setText("{this} deals damage to target attacking creature equal to the number of Equipment you control");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetAttackingCreature()); this.getSpellAbility().addTarget(new TargetAttackingCreature());
} }

View file

@ -41,7 +41,7 @@ class BookBurningMillEffect extends OneShotEffect {
public BookBurningMillEffect() { public BookBurningMillEffect() {
super(Outcome.Detriment); super(Outcome.Detriment);
staticText = "Any player may have {source} deal 6 damage to them. If no one does, target player mills six cards"; staticText = "Any player may have {this} deal 6 damage to them. If no one does, target player mills six cards";
} }
public BookBurningMillEffect(final BookBurningMillEffect effect) { public BookBurningMillEffect(final BookBurningMillEffect effect) {

View file

@ -54,7 +54,7 @@ class BrainGorgersCounterSourceEffect extends OneShotEffect {
public BrainGorgersCounterSourceEffect() { public BrainGorgersCounterSourceEffect() {
super(Outcome.AIDontUseIt); super(Outcome.AIDontUseIt);
staticText = "any player may sacrifice a creature. If a player does, counter {source}"; staticText = "any player may sacrifice a creature. If a player does, counter {this}";
} }
public BrainGorgersCounterSourceEffect(final BrainGorgersCounterSourceEffect effect) { public BrainGorgersCounterSourceEffect(final BrainGorgersCounterSourceEffect effect) {

View file

@ -41,7 +41,7 @@ class BrowbeatDrawEffect extends OneShotEffect {
public BrowbeatDrawEffect() { public BrowbeatDrawEffect() {
super(Outcome.DrawCard); super(Outcome.DrawCard);
staticText = "Any player may have {source} deal 5 damage to them. If no one does, target player draws three cards."; staticText = "Any player may have {this} deal 5 damage to them. If no one does, target player draws three cards.";
} }
public BrowbeatDrawEffect(final BrowbeatDrawEffect effect) { public BrowbeatDrawEffect(final BrowbeatDrawEffect effect) {

View file

@ -77,6 +77,6 @@ class ChandrasPyrelingAbility extends TriggeredAbilityImpl {
@Override @Override
public String getRule() { public String getRule() {
return "Whenever a source you control deals noncombat damage to an opponent, {source} gets +1/+0 and gains double strike until end of turn."; return "Whenever a source you control deals noncombat damage to an opponent, {this} gets +1/+0 and gains double strike until end of turn.";
} }
} }

View file

@ -43,7 +43,7 @@ public final class Clickslither extends CardImpl {
this.addAbility(HasteAbility.getInstance()); this.addAbility(HasteAbility.getInstance());
// Sacrifice a Goblin: Clickslither gets +2/+2 and gains trample until end of turn. // Sacrifice a Goblin: Clickslither gets +2/+2 and gains trample until end of turn.
Effect effect = new BoostSourceEffect(2,2,Duration.EndOfTurn); Effect effect = new BoostSourceEffect(2,2,Duration.EndOfTurn);
effect.setText("{source} gets +2/+2"); effect.setText("{this} gets +2/+2");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect,
new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter,true))); new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter,true)));
effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);

View file

@ -40,7 +40,7 @@ public final class CloakAndDagger extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// Whenever a Rogue creature enters the battlefield, you may attach Cloak and Dagger to it. // Whenever a Rogue creature enters the battlefield, you may attach Cloak and Dagger to it.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {this} to it"),
filter, true, SetTargetPointer.PERMANENT, null)); filter, true, SetTargetPointer.PERMANENT, null));
// Equip {3} // Equip {3}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3))); this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3)));

View file

@ -63,7 +63,7 @@ class ConeOfFlameEffect extends OneShotEffect {
public ConeOfFlameEffect() { public ConeOfFlameEffect() {
super(Outcome.Damage); super(Outcome.Damage);
this.staticText = "{source} deals 1 damage to any target, " this.staticText = "{this} deals 1 damage to any target, "
+ "2 damage to another target, " + "2 damage to another target, "
+ "and 3 damage to a third target"; + "and 3 damage to a third target";
} }

View file

@ -48,7 +48,7 @@ class DashHopesCounterSourceEffect extends OneShotEffect {
public DashHopesCounterSourceEffect() { public DashHopesCounterSourceEffect() {
super(Outcome.AIDontUseIt); super(Outcome.AIDontUseIt);
staticText = "any player may pay 5 life. If a player does, counter {source}"; staticText = "any player may pay 5 life. If a player does, counter {this}";
} }
public DashHopesCounterSourceEffect(final DashHopesCounterSourceEffect effect) { public DashHopesCounterSourceEffect(final DashHopesCounterSourceEffect effect) {

View file

@ -127,7 +127,7 @@ class DiseasedVerminPredicate implements ObjectSourcePlayerPredicate<ObjectSourc
@Override @Override
public String toString() { public String toString() {
return "(Player previously dealt damage by {source})"; return "(Player previously dealt damage by {this})";
} }
} }

View file

@ -40,7 +40,7 @@ public final class DivinersWand extends CardImpl {
// Whenever a Wizard creature enters the battlefield, you may attach Diviner's Wand to it. // Whenever a Wizard creature enters the battlefield, you may attach Diviner's Wand to it.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {this} to it"),
filter, true, SetTargetPointer.PERMANENT, null)); filter, true, SetTargetPointer.PERMANENT, null));
// Equip {3} // Equip {3}

View file

@ -85,7 +85,7 @@ class AddCounterAbility extends TriggeredAbilityImpl {
@Override @Override
public String getRule() { public String getRule() {
return "Whenever you cast a spell of the chosen type, put a charge counter on {source}"; return "Whenever you cast a spell of the chosen type, put a charge counter on {this}";
} }
} }

View file

@ -22,7 +22,7 @@ public final class Electrolyze extends CardImpl {
// Electrolyze deals 2 damage divided as you choose among one or two target creatures and/or players. // Electrolyze deals 2 damage divided as you choose among one or two target creatures and/or players.
Effect effect = new DamageMultiEffect(2); Effect effect = new DamageMultiEffect(2);
effect.setText("{source} deals 2 damage divided as you choose among one or two target creatures and/or players"); effect.setText("{this} deals 2 damage divided as you choose among one or two target creatures and/or players");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetAnyTargetAmount(2)); this.getSpellAbility().addTarget(new TargetAnyTargetAmount(2));
// Draw a card. // Draw a card.

View file

@ -29,7 +29,7 @@ public final class EtherealChampion extends CardImpl {
// Pay 1 life: Prevent the next 1 damage that would be dealt to Ethereal Champion this turn. // Pay 1 life: Prevent the next 1 damage that would be dealt to Ethereal Champion this turn.
Effect effect = new PreventDamageToSourceEffect(Duration.EndOfTurn, 1); Effect effect = new PreventDamageToSourceEffect(Duration.EndOfTurn, 1);
effect.setText("Pay 1 life: Prevent the next 1 damage that would be dealt to {source} this turn"); effect.setText("Pay 1 life: Prevent the next 1 damage that would be dealt to {this} this turn");
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new PayLifeCost(1))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new PayLifeCost(1)));
} }

View file

@ -79,7 +79,7 @@ class PlayALandTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public String getRule() { public String getRule() {
return "Whenever you play a land, if it wasn't the first land you played this turn, {source} deals 1 damage to you"; return "Whenever you play a land, if it wasn't the first land you played this turn, {this} deals 1 damage to you";
} }
} }

View file

@ -34,7 +34,7 @@ public final class FeastOfFlesh extends CardImpl {
Effect effect1 = new DamageTargetEffect(value); Effect effect1 = new DamageTargetEffect(value);
effect1.setText("Feast of Flesh deals X damage to target creature"); effect1.setText("Feast of Flesh deals X damage to target creature");
Effect effect2 = new GainLifeEffect(value); Effect effect2 = new GainLifeEffect(value);
effect2.setText("and you gain X life, where X is 1 plus the number of cards named {source} in all graveyards"); effect2.setText("and you gain X life, where X is 1 plus the number of cards named {this} in all graveyards");
this.getSpellAbility().addEffect(effect1); this.getSpellAbility().addEffect(effect1);
this.getSpellAbility().addEffect(effect2); this.getSpellAbility().addEffect(effect2);
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent());

View file

@ -45,7 +45,7 @@ public final class FelhideSpiritbinder extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// <i>Inspired</i> &mdash; Whenever Felhide Spiritbinder becomes untapped, you may pay {1}{R}. If you do, create a token that's a copy of another target creature except it's an enchantment in addition to its other types. It gains haste. Exile it at the beginning of the next end step. // <i>Inspired</i> &mdash; Whenever Felhide Spiritbinder becomes untapped, you may pay {1}{R}. If you do, create a token that's a copy of another target creature except it's an enchantment in addition to its other types. It gains haste. Exile it at the beginning of the next end step.
Ability ability = new InspiredAbility(new DoIfCostPaid(new FelhideSpiritbinderEffect(), new ManaCostsImpl("{1}{R}"), "Use effect of {source}?")); Ability ability = new InspiredAbility(new DoIfCostPaid(new FelhideSpiritbinderEffect(), new ManaCostsImpl("{1}{R}"), "Use effect of {this}?"));
ability.addTarget(new TargetCreaturePermanent(filter)); ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -32,7 +32,7 @@ public final class GalvanicBombardment extends CardImpl {
// Galvanic Bombardment deals X damage to target creature, where X is 2 plus the number of cards named Galvanic Bombardment in your graveyard. // Galvanic Bombardment deals X damage to target creature, where X is 2 plus the number of cards named Galvanic Bombardment in your graveyard.
Effect effect = new DamageTargetEffect(new GalvanicBombardmentCardsInControllerGraveyardCount(filter)); Effect effect = new DamageTargetEffect(new GalvanicBombardmentCardsInControllerGraveyardCount(filter));
effect.setText("{this} deals X damage to target creature, where X is 2 plus the number of cards named {source} in your graveyard"); effect.setText("{this} deals X damage to target creature, where X is 2 plus the number of cards named {this} in your graveyard");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent());
} }

View file

@ -75,7 +75,7 @@ class GhastlyRemainsTriggeredAbility extends BeginningOfUpkeepTriggeredAbility {
@Override @Override
public String getRule() { public String getRule() {
return "At the beginning of your upkeep, if {source} is in your graveyard, you may pay {B}{B}{B}. If you do, return {source} to your hand"; return "At the beginning of your upkeep, if {this} is in your graveyard, you may pay {B}{B}{B}. If you do, return {this} to your hand";
} }
} }

View file

@ -71,7 +71,7 @@ class GiantOysterDontUntapAsLongAsSourceTappedEffect extends DontUntapAsLongAsSo
public GiantOysterDontUntapAsLongAsSourceTappedEffect() { public GiantOysterDontUntapAsLongAsSourceTappedEffect() {
super(); super();
staticText = "For as long as {source} remains tapped, target tapped creature doesn't untap during its controller's untap step"; staticText = "For as long as {this} remains tapped, target tapped creature doesn't untap during its controller's untap step";
} }
public GiantOysterDontUntapAsLongAsSourceTappedEffect(final GiantOysterDontUntapAsLongAsSourceTappedEffect effect) { public GiantOysterDontUntapAsLongAsSourceTappedEffect(final GiantOysterDontUntapAsLongAsSourceTappedEffect effect) {

View file

@ -74,7 +74,7 @@ class GigapedeTriggerdAbility extends BeginningOfUpkeepTriggeredAbility{
@Override @Override
public String getRule() { public String getRule() {
return "At the beginning of your upkeep, if {source} is in your graveyard, you may discard a card. If you do, return {source} to your hand"; return "At the beginning of your upkeep, if {this} is in your graveyard, you may discard a card. If you do, return {this} to your hand";
} }
} }

View file

@ -36,7 +36,7 @@ public final class HerosBlade extends CardImpl {
// Whenever a legendary creature enters the battlefield under your control, you may attach Hero's Blade to it. // Whenever a legendary creature enters the battlefield under your control, you may attach Hero's Blade to it.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {this} to it"),
filter, true, SetTargetPointer.PERMANENT, null, true)); filter, true, SetTargetPointer.PERMANENT, null, true));
// Equip {4} // Equip {4}

View file

@ -137,7 +137,7 @@ class HuatliWarriorPoetDamageEffect extends OneShotEffect {
if (staticText != null && !staticText.isEmpty()) { if (staticText != null && !staticText.isEmpty()) {
return staticText; return staticText;
} }
return "{source} deals " return "{this} deals "
+ amount.toString() + amount.toString()
+ " damage divided as you choose among any number of target " + " damage divided as you choose among any number of target "
+ mode.getTargets().get(0).getTargetName() + mode.getTargets().get(0).getTargetName()

View file

@ -95,7 +95,7 @@ class IchoridTriggerdAbility extends BeginningOfUpkeepTriggeredAbility{
@Override @Override
public String getRule() { public String getRule() {
return "At the beginning of your upkeep, if {source} is in your graveyard, you may exile a black creature card other than {source} from your graveyard. If you do, return {source} to the battlefield."; return "At the beginning of your upkeep, if {this} is in your graveyard, you may exile a black creature card other than {this} from your graveyard. If you do, return {this} to the battlefield.";
} }
} }

View file

@ -33,7 +33,7 @@ public final class Kindle extends CardImpl {
// Kindle deals X damage to any target, where X is 2 plus the number of cards named Kindle in all graveyards. // Kindle deals X damage to any target, where X is 2 plus the number of cards named Kindle in all graveyards.
Effect effect = new DamageTargetEffect(new KindleCardsInAllGraveyardsCount(filter)); Effect effect = new DamageTargetEffect(new KindleCardsInAllGraveyardsCount(filter));
effect.setText("{this} deals X damage to any target, where X is 2 plus the number of cards named {source} in all graveyards"); effect.setText("{this} deals X damage to any target, where X is 2 plus the number of cards named {this} in all graveyards");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addTarget(new TargetAnyTarget());
} }

View file

@ -60,7 +60,7 @@ class KjeldoranRoyalGuardEffect extends ReplacementEffectImpl {
KjeldoranRoyalGuardEffect() { KjeldoranRoyalGuardEffect() {
super(Duration.EndOfTurn, Outcome.RedirectDamage); super(Duration.EndOfTurn, Outcome.RedirectDamage);
staticText = "All combat damage that would be dealt to you by unblocked creatures this turn is dealt to {source} instead"; staticText = "All combat damage that would be dealt to you by unblocked creatures this turn is dealt to {this} instead";
} }
KjeldoranRoyalGuardEffect(final KjeldoranRoyalGuardEffect effect) { KjeldoranRoyalGuardEffect(final KjeldoranRoyalGuardEffect effect) {

View file

@ -32,7 +32,7 @@ public final class KjeldoranWarCry extends CardImpl {
// Creatures you control get +X/+X until end of turn, where X is 1 plus the number of cards named Kjeldoran War Cry in all graveyards. // Creatures you control get +X/+X until end of turn, where X is 1 plus the number of cards named Kjeldoran War Cry in all graveyards.
IntPlusDynamicValue value = new IntPlusDynamicValue(1, new CardsInAllGraveyardsCount(filter)); IntPlusDynamicValue value = new IntPlusDynamicValue(1, new CardsInAllGraveyardsCount(filter));
Effect effect = new BoostControlledEffect(value, value, Duration.EndOfTurn, new FilterCreaturePermanent("creatures"), false, true); Effect effect = new BoostControlledEffect(value, value, Duration.EndOfTurn, new FilterCreaturePermanent("creatures"), false, true);
effect.setText("Creatures you control get +X/+X until end of turn, where X is 1 plus the number of cards named {source} in all graveyards"); effect.setText("Creatures you control get +X/+X until end of turn, where X is 1 plus the number of cards named {this} in all graveyards");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
} }

View file

@ -31,7 +31,7 @@ public final class LifeBurst extends CardImpl {
// Target player gains 4 life, then gains 4 life for each card named Life Burst in each graveyard. // Target player gains 4 life, then gains 4 life for each card named Life Burst in each graveyard.
this.getSpellAbility().addEffect(new GainLifeTargetEffect(4)); this.getSpellAbility().addEffect(new GainLifeTargetEffect(4));
Effect effect = new GainLifeTargetEffect(new MultipliedValue(new CardsInAllGraveyardsCount(filter), 4)); Effect effect = new GainLifeTargetEffect(new MultipliedValue(new CardsInAllGraveyardsCount(filter), 4));
effect.setText(", then gains 4 life for each card named {source} in each graveyard"); effect.setText(", then gains 4 life for each card named {this} in each graveyard");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayer());
} }

View file

@ -55,7 +55,7 @@ public final class LyzoldaTheBloodWitch extends CardImpl {
Effect effect = new ConditionalOneShotEffect( Effect effect = new ConditionalOneShotEffect(
new DamageTargetEffect(2), new DamageTargetEffect(2),
new SacrificedWasCondition(redFilter), new SacrificedWasCondition(redFilter),
"{source} deals 2 damage to any target if the sacrificed creature was red"); "{this} deals 2 damage to any target if the sacrificed creature was red");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}"));
effect = new ConditionalOneShotEffect( effect = new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1), new DrawCardSourceControllerEffect(1),

View file

@ -135,6 +135,6 @@ class MindreaverNamePredicate implements Predicate<MageObject> {
@Override @Override
public String toString() { public String toString() {
return "spell with the same name as a card exiled with {source}"; return "spell with the same name as a card exiled with {this}";
} }
} }

View file

@ -87,7 +87,7 @@ class NetherShadowTriggerdAbility extends BeginningOfUpkeepTriggeredAbility{
@Override @Override
public String getRule() { public String getRule() {
return "At the beginning of your upkeep, if {source} is in your graveyard with three or more creature cards above it, you may put {source} onto the battlefield."; return "At the beginning of your upkeep, if {this} is in your graveyard with three or more creature cards above it, you may put {this} onto the battlefield.";
} }

View file

@ -39,7 +39,7 @@ public final class ObsidianBattleAxe extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// Whenever a Warrior creature enters the battlefield, you may attach Obsidian Battle-Axe to it. // Whenever a Warrior creature enters the battlefield, you may attach Obsidian Battle-Axe to it.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {this} to it"),
filter, true, SetTargetPointer.PERMANENT, null)); filter, true, SetTargetPointer.PERMANENT, null));
// Equip {3} // Equip {3}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3))); this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3)));

View file

@ -128,6 +128,9 @@ class OdricMasterTacticianChooseBlockersEffect extends ContinuousRuleModifyingEf
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (source.isControlledBy(event.getPlayerId())) {
return false; // Don't replace the own call to selectBlockers
}
ChooseBlockersRedundancyWatcher watcher = game.getState().getWatcher(ChooseBlockersRedundancyWatcher.class); ChooseBlockersRedundancyWatcher watcher = game.getState().getWatcher(ChooseBlockersRedundancyWatcher.class);
if (watcher == null) { if (watcher == null) {
return false; return false;

View file

@ -170,6 +170,6 @@ class PowerLowerEqualSourcePredicate implements ObjectPlayerPredicate<ObjectPlay
@Override @Override
public String toString() { public String toString() {
return "creature with power less than or equal to {source}'s power"; return "creature with power less than or equal to {this}'s power";
} }
} }

View file

@ -32,7 +32,7 @@ public final class OranRiefInvoker extends CardImpl {
// {8}: Oran-Rief Invoker gets +5/+5 and gains trample until end of turn. // {8}: Oran-Rief Invoker gets +5/+5 and gains trample until end of turn.
Effect effect = new BoostSourceEffect(5, 5, Duration.EndOfTurn); Effect effect = new BoostSourceEffect(5, 5, Duration.EndOfTurn);
effect.setText("{source} gets +5/+5"); effect.setText("{this} gets +5/+5");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(8)); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(8));
effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and gains trample until end of turn"); effect.setText("and gains trample until end of turn");

View file

@ -97,6 +97,6 @@ class CounterSourceEffect extends OneShotEffect {
if (staticText != null && !staticText.isEmpty()) { if (staticText != null && !staticText.isEmpty()) {
return staticText; return staticText;
} }
return "any player may discard three cards. If a player does, counter {source}"; return "any player may discard three cards. If a player does, counter {this}";
} }
} }

View file

@ -68,7 +68,7 @@ public final class RinAndSeriInseparable extends CardImpl {
// {R}{G}{W}, {T}: Rin and Seri, Inseparable deals damage to any target equal to the number of Dogs you control. You gain life equal to the number of Cats you control. // {R}{G}{W}, {T}: Rin and Seri, Inseparable deals damage to any target equal to the number of Dogs you control. You gain life equal to the number of Cats you control.
DynamicValue dogCount = new PermanentsOnBattlefieldCount(dogPermanentFilter); DynamicValue dogCount = new PermanentsOnBattlefieldCount(dogPermanentFilter);
Effect damageEffect = new DamageTargetEffect(dogCount); Effect damageEffect = new DamageTargetEffect(dogCount);
damageEffect.setText("{source} deals damage to any target equal to the number of Dogs you control"); damageEffect.setText("{this} deals damage to any target equal to the number of Dogs you control");
DynamicValue catCount = new PermanentsOnBattlefieldCount(catPermanentFilter); DynamicValue catCount = new PermanentsOnBattlefieldCount(catPermanentFilter);
Effect lifeGainEffect = new GainLifeEffect(catCount); Effect lifeGainEffect = new GainLifeEffect(catCount);
lifeGainEffect.setText("You gain life equal to the number of Cats you control"); lifeGainEffect.setText("You gain life equal to the number of Cats you control");

View file

@ -38,7 +38,7 @@ public final class SaiOfTheShinobi extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1)));
// Whenever a creature enters the battlefield under your control, you may attach Sai of the Shinobi to it. // Whenever a creature enters the battlefield under your control, you may attach Sai of the Shinobi to it.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {this} to it"),
filter, true, SetTargetPointer.PERMANENT, null, true)); filter, true, SetTargetPointer.PERMANENT, null, true));
// Equip {2} // Equip {2}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2)));

View file

@ -47,7 +47,7 @@ public final class ShieldedByFaith extends CardImpl {
// Whenever a creature enters the battlefield, you may attach Shielded by Faith to that creature. // Whenever a creature enters the battlefield, you may attach Shielded by Faith to that creature.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Benefit, "attach {source} to that creature"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Benefit, "attach {this} to that creature"),
new FilterCreaturePermanent("a creature"), true, SetTargetPointer.PERMANENT, null, false)); new FilterCreaturePermanent("a creature"), true, SetTargetPointer.PERMANENT, null, false));
} }

View file

@ -41,7 +41,7 @@ class SkullcageEffect extends OneShotEffect {
public SkullcageEffect() { public SkullcageEffect() {
super(Outcome.Damage); super(Outcome.Damage);
staticText = "{source} deals 2 damage to that player unless they have exactly three or exactly four cards in hand"; staticText = "{this} deals 2 damage to that player unless they have exactly three or exactly four cards in hand";
} }
public SkullcageEffect(final SkullcageEffect effect) { public SkullcageEffect(final SkullcageEffect effect) {

View file

@ -41,7 +41,7 @@ class SkullscorchDiscardEffect extends OneShotEffect {
public SkullscorchDiscardEffect() { public SkullscorchDiscardEffect() {
super(Outcome.DrawCard); super(Outcome.DrawCard);
staticText = "Target player discards two cards at random unless that player has {source} deal 4 damage to them"; staticText = "Target player discards two cards at random unless that player has {this} deal 4 damage to them";
} }
public SkullscorchDiscardEffect(final SkullscorchDiscardEffect effect) { public SkullscorchDiscardEffect(final SkullscorchDiscardEffect effect) {

View file

@ -32,7 +32,7 @@ public final class StormriderRig extends CardImpl {
// Whenever a creature enters the battlefield under your control, you may attach Stormrider Rig to it. // Whenever a creature enters the battlefield under your control, you may attach Stormrider Rig to it.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {this} to it"),
StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, true, SetTargetPointer.PERMANENT, null, true)); StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, true, SetTargetPointer.PERMANENT, null, true));
// Equip {2} // Equip {2}

View file

@ -29,7 +29,7 @@ public final class TakeInventory extends CardImpl {
// Draw a card, then draw cards equal to the number of cards named Take Inventory in your graveyard. // Draw a card, then draw cards equal to the number of cards named Take Inventory in your graveyard.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
Effect effect = new DrawCardSourceControllerEffect(new CardsInControllerGraveyardCount(filter)); Effect effect = new DrawCardSourceControllerEffect(new CardsInControllerGraveyardCount(filter));
effect.setText(", then draw cards equal to the number of cards named {source} in your graveyard"); effect.setText(", then draw cards equal to the number of cards named {this} in your graveyard");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
} }

View file

@ -45,7 +45,7 @@ class TemporalExtortionCounterSourceEffect extends OneShotEffect {
public TemporalExtortionCounterSourceEffect() { public TemporalExtortionCounterSourceEffect() {
super(Outcome.AIDontUseIt); super(Outcome.AIDontUseIt);
staticText = "any player may pay half their life, rounded up. If a player does, counter {source}"; staticText = "any player may pay half their life, rounded up. If a player does, counter {this}";
} }
public TemporalExtortionCounterSourceEffect(final TemporalExtortionCounterSourceEffect effect) { public TemporalExtortionCounterSourceEffect(final TemporalExtortionCounterSourceEffect effect) {

View file

@ -51,7 +51,7 @@ public final class ThornbiteStaff extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// Whenever a Shaman creature enters the battlefield, you may attach Thornbite Staff to it. // Whenever a Shaman creature enters the battlefield, you may attach Thornbite Staff to it.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {this} to it"),
filter, true, SetTargetPointer.PERMANENT, null)); filter, true, SetTargetPointer.PERMANENT, null));
// Equip {4} // Equip {4}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4))); this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4)));

View file

@ -35,10 +35,10 @@ public final class Tornado extends CardImpl {
// {2}{G}, Pay 3 life for each velocity counter on Tornado: Destroy target permanent and put a velocity counter on Tornado. Activate this ability only once each turn. // {2}{G}, Pay 3 life for each velocity counter on Tornado: Destroy target permanent and put a velocity counter on Tornado. Activate this ability only once each turn.
Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{2}{G}")); Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{2}{G}"));
DynamicValue lifeToPayAmount = new MultipliedValue(new CountersSourceCount(CounterType.VELOCITY), 3); DynamicValue lifeToPayAmount = new MultipliedValue(new CountersSourceCount(CounterType.VELOCITY), 3);
ability.addCost(new PayLifeCost(lifeToPayAmount, "3 life for each velocity counter on {source}")); ability.addCost(new PayLifeCost(lifeToPayAmount, "3 life for each velocity counter on {this}"));
ability.addTarget(new TargetPermanent()); ability.addTarget(new TargetPermanent());
Effect effect = new AddCountersSourceEffect(CounterType.VELOCITY.createInstance()); Effect effect = new AddCountersSourceEffect(CounterType.VELOCITY.createInstance());
effect.setText("and put a velocity counter on {source}"); effect.setText("and put a velocity counter on {this}");
ability.addEffect(effect); ability.addEffect(effect);
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -63,7 +63,7 @@ class VeteranBodyguardEffect extends PreventionEffectImpl {
VeteranBodyguardEffect() { VeteranBodyguardEffect() {
super(Duration.WhileOnBattlefield); super(Duration.WhileOnBattlefield);
staticText = "all combat damage that would be dealt to you by unblocked creatures is dealt to {source} instead"; staticText = "all combat damage that would be dealt to you by unblocked creatures is dealt to {this} instead";
} }
VeteranBodyguardEffect(final VeteranBodyguardEffect effect) { VeteranBodyguardEffect(final VeteranBodyguardEffect effect) {

View file

@ -46,7 +46,7 @@ public final class VeteransArmaments extends CardImpl {
// Whenever a Soldier creature enters the battlefield, you may attach Veteran's Armaments to it. // Whenever a Soldier creature enters the battlefield, you may attach Veteran's Armaments to it.
this.addAbility(new EntersBattlefieldAllTriggeredAbility( this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {this} to it"),
filter, true, SetTargetPointer.PERMANENT, null)); filter, true, SetTargetPointer.PERMANENT, null));
// Equip {2} // Equip {2}

View file

@ -46,7 +46,7 @@ class ViselingEffect extends OneShotEffect {
public ViselingEffect() { public ViselingEffect() {
super(Outcome.Damage); super(Outcome.Damage);
this.staticText = "{source} deals X damage to that player, where X is the number of cards in their hand minus 4"; this.staticText = "{this} deals X damage to that player, where X is the number of cards in their hand minus 4";
} }
public ViselingEffect(final ViselingEffect effect) { public ViselingEffect(final ViselingEffect effect) {

View file

@ -70,6 +70,6 @@ class WickedAkubaPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePl
@Override @Override
public String toString() { public String toString() {
return "(Player dealt damage by {source} this turn)"; return "(Player dealt damage by {this} this turn)";
} }
} }

View file

@ -24,7 +24,7 @@ public class HeavyArbalestTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves"); addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {4}", "Elite Vanguard"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {4}", "Elite Vanguard");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals 2 damage", playerB); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals 2 damage", playerB);
setStopAt(3, PhaseStep.BEGIN_COMBAT); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -48,7 +48,7 @@ public class HeavyArbalestTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves"); addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {4}", "Elite Vanguard"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {4}", "Elite Vanguard");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals 2 damage", playerB); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals 2 damage", playerB);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {4}", "Llanowar Elves"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {4}", "Llanowar Elves");
setStopAt(5, PhaseStep.BEGIN_COMBAT); setStopAt(5, PhaseStep.BEGIN_COMBAT);

View file

@ -62,7 +62,7 @@ public class ChampionTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Crafter"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Crafter");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals 3 damage to ", "Lightning Crafter"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals 3 damage to ", "Lightning Crafter");
setStopAt(3, PhaseStep.BEGIN_COMBAT); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();

View file

@ -63,7 +63,7 @@ public class SatyrFiredancerTest extends CardTestPlayerBase {
// {T}: Prodigal Pyromancer deals 1 damage to any target. // {T}: Prodigal Pyromancer deals 1 damage to any target.
addCard(Zone.BATTLEFIELD, playerA, "Prodigal Pyromancer", 1); addCard(Zone.BATTLEFIELD, playerA, "Prodigal Pyromancer", 1);
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB);
addTarget(playerA, playerB); addTarget(playerA, playerB);
setStopAt(3, PhaseStep.END_TURN); setStopAt(3, PhaseStep.END_TURN);

View file

@ -32,7 +32,7 @@ public class UginTest extends CardTestPlayerBase {
// -7: Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands. // -7: Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands.
addCard(Zone.HAND, playerB, "Nissa, Vastwood Seer"); addCard(Zone.HAND, playerB, "Nissa, Vastwood Seer");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {source} deals 3 damage", playerB); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage", playerB);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Nissa, Vastwood Seer"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Nissa, Vastwood Seer");
playLand(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Forest"); playLand(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Forest");

View file

@ -19,7 +19,7 @@ public class HavengulLichTest extends CardTestPlayerBase {
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", "Prodigal Pyromancer"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", "Prodigal Pyromancer");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prodigal Pyromancer"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prodigal Pyromancer");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {this} deals", playerB);
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
@ -61,8 +61,8 @@ public class HavengulLichTest extends CardTestPlayerBase {
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: You may", "Prodigal Pyromancer"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: You may", "Prodigal Pyromancer");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prodigal Pyromancer"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prodigal Pyromancer");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB);
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); // only inm turn 1, so Havengul Lich has the abilit ylost now activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB); // only inm turn 1, so Havengul Lich has the abilit ylost now
setStopAt(3, PhaseStep.BEGIN_COMBAT); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();

View file

@ -46,7 +46,7 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flametongue Kavu"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flametongue Kavu");
addTarget(playerB, "Soldier of the Pantheon"); addTarget(playerB, "Soldier of the Pantheon");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.", activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.",
TestPlayer.NO_TARGET, "When {this} enters the battlefield, {source} deals 4 damage to target creature."); TestPlayer.NO_TARGET, "When {this} enters the battlefield, {this} deals 4 damage to target creature.");
playerA.addChoice("Flametongue Kavu"); playerA.addChoice("Flametongue Kavu");
setStopAt(2, PhaseStep.BEGIN_COMBAT); setStopAt(2, PhaseStep.BEGIN_COMBAT);
@ -73,7 +73,7 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flametongue Kavu"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flametongue Kavu");
addTarget(playerB, "Soldier of the Pantheon"); addTarget(playerB, "Soldier of the Pantheon");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.", activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.",
TestPlayer.NO_TARGET, "When {this} enters the battlefield, {source} deals 4 damage to target creature."); TestPlayer.NO_TARGET, "When {this} enters the battlefield, {this} deals 4 damage to target creature.");
playerA.addChoice("Flametongue Kavu"); playerA.addChoice("Flametongue Kavu");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cloudshift", "Flametongue Kavu"); castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cloudshift", "Flametongue Kavu");
@ -117,7 +117,7 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
activateAbility(2, PhaseStep.END_COMBAT, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn."); activateAbility(2, PhaseStep.END_COMBAT, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.");
playerA.addChoice("Mogg Fanatic"); playerA.addChoice("Mogg Fanatic");
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice {this}: {source} deals 1 damage to ", "Soldier of the Pantheon"); activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice {this}: {this} deals 1 damage to ", "Soldier of the Pantheon");
setStopAt(2, PhaseStep.END_TURN); setStopAt(2, PhaseStep.END_TURN);
execute(); execute();

View file

@ -13,7 +13,7 @@ public class ChandrasMagmuttTest extends CardTestPlayerBase {
// {T}: Chandra's Magmutt deals 1 damage to target player or planeswalker.< // {T}: Chandra's Magmutt deals 1 damage to target player or planeswalker.<
addCard(Zone.BATTLEFIELD, playerA, "Chandra's Magmutt"); addCard(Zone.BATTLEFIELD, playerA, "Chandra's Magmutt");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB);
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
setStrictChooseMode(true); setStrictChooseMode(true);
@ -32,7 +32,7 @@ public class ChandrasMagmuttTest extends CardTestPlayerBase {
// 6: You get an emblem with "At the beginning of combat on your turn, create a 1/1 white Soldier creature token, then put a +1/+1 counter on each creature you control." // 6: You get an emblem with "At the beginning of combat on your turn, create a 1/1 white Soldier creature token, then put a +1/+1 counter on each creature you control."
addCard(Zone.BATTLEFIELD, playerB, "Basri Ket"); addCard(Zone.BATTLEFIELD, playerB, "Basri Ket");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Basri Ket"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Basri Ket");
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
setStrictChooseMode(true); setStrictChooseMode(true);
execute(); execute();

View file

@ -28,7 +28,7 @@ public class SyrCarahTheBoldTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Island", 1); addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
// 1 - triggers on ability damage // 1 - triggers on ability damage
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkLife("damage 1", 1, PhaseStep.PRECOMBAT_MAIN, playerB, 20 - 1); checkLife("damage 1", 1, PhaseStep.PRECOMBAT_MAIN, playerB, 20 - 1);
@ -72,7 +72,7 @@ public class SyrCarahTheBoldTest extends CardTestPlayerBase {
checkExileCount("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0); checkExileCount("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0);
// activate damage - 2x damage with copy // activate damage - 2x damage with copy
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB);
setChoice(playerA, "No"); // no new target for copy setChoice(playerA, "No"); // no new target for copy
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkLife("damage 2", 1, PhaseStep.PRECOMBAT_MAIN, playerB, 20 - 1 - 1); checkLife("damage 2", 1, PhaseStep.PRECOMBAT_MAIN, playerB, 20 - 1 - 1);

View file

@ -23,7 +23,7 @@ public class BloodCultistTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Devilthorn Fox", 1); // 3/1 addCard(Zone.BATTLEFIELD, playerB, "Devilthorn Fox", 1); // 3/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Devilthorn Fox"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Devilthorn Fox");
setStopAt(3, PhaseStep.BEGIN_COMBAT); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -46,7 +46,7 @@ public class BloodCultistTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Indulgent Aristocrat", 1); // 1/1 addCard(Zone.BATTLEFIELD, playerB, "Indulgent Aristocrat", 1); // 1/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Devilthorn Fox"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Devilthorn Fox");
attack(5, playerA, "Blood Cultist"); attack(5, playerA, "Blood Cultist");
block(5, playerB, "Indulgent Aristocrat", "Blood Cultist"); block(5, playerB, "Indulgent Aristocrat", "Blood Cultist");
@ -73,8 +73,8 @@ public class BloodCultistTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Shambling Ghoul", 1); // 2/3 addCard(Zone.BATTLEFIELD, playerB, "Shambling Ghoul", 1); // 2/3
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Devilthorn Fox"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Devilthorn Fox");
activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Shambling Ghoul"); activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Shambling Ghoul");
attack(5, playerA, "Silvercoat Lion"); attack(5, playerA, "Silvercoat Lion");
block(5, playerB, "Shambling Ghoul", "Silvercoat Lion"); block(5, playerB, "Shambling Ghoul", "Silvercoat Lion");
@ -101,8 +101,8 @@ public class BloodCultistTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Shambling Ghoul", 1); // 2/3 addCard(Zone.BATTLEFIELD, playerB, "Shambling Ghoul", 1); // 2/3
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Devilthorn Fox"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Devilthorn Fox");
activateAbility(5, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {source} deals", "Shambling Ghoul"); activateAbility(5, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {this} deals", "Shambling Ghoul");
attack(5, playerA, "Silvercoat Lion"); attack(5, playerA, "Silvercoat Lion");
block(5, playerB, "Shambling Ghoul", "Silvercoat Lion"); block(5, playerB, "Shambling Ghoul", "Silvercoat Lion");
@ -127,7 +127,7 @@ public class BloodCultistTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Shambling Ghoul", 1); // 2/3 addCard(Zone.BATTLEFIELD, playerB, "Shambling Ghoul", 1); // 2/3
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Shambling Ghoul"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Shambling Ghoul");
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Shambling Ghoul"); castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Shambling Ghoul");
setStopAt(3, PhaseStep.END_TURN); setStopAt(3, PhaseStep.END_TURN);

View file

@ -28,7 +28,7 @@ public class DiesExiledTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk"); addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kumano's Blessing", "Prodigal Pyromancer"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kumano's Blessing", "Prodigal Pyromancer");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {source} deals 1 damage to", "Sejiri Merfolk"); activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {this} deals 1 damage to", "Sejiri Merfolk");
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
@ -53,7 +53,7 @@ public class DiesExiledTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Frostwielder"); addCard(Zone.BATTLEFIELD, playerA, "Frostwielder");
addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk"); addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals 1 damage to ", "Sejiri Merfolk"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals 1 damage to ", "Sejiri Merfolk");
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -78,7 +78,7 @@ public class DiesExiledTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Kumano, Master Yamabushi"); addCard(Zone.BATTLEFIELD, playerA, "Kumano, Master Yamabushi");
addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk"); addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{R}: {source} deals 1 damage to ", "Sejiri Merfolk"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{R}: {this} deals 1 damage to ", "Sejiri Merfolk");
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();

View file

@ -26,7 +26,7 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyality counters addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyality counters
addCard(Zone.BATTLEFIELD, playerA, kira); addCard(Zone.BATTLEFIELD, playerA, kira);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {source} deals 3 damage", kira); // Ugin ability activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage", kira); // Ugin ability
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -44,7 +44,7 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Unsummon", 1); addCard(Zone.HAND, playerA, "Unsummon", 1);
addCard(Zone.BATTLEFIELD, playerA, kira); addCard(Zone.BATTLEFIELD, playerA, kira);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {source} deals 3 damage", kira); // Ugin ability activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage", kira); // Ugin ability
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Unsummon", kira); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Unsummon", kira);
@ -62,8 +62,8 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyality counters addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyality counters
addCard(Zone.BATTLEFIELD, playerA, kira); addCard(Zone.BATTLEFIELD, playerA, kira);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {source} deals 3 damage to", kira); // Ugin ability activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage to", kira); // Ugin ability
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {source} deals 3 damage to", kira); // Ugin ability activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage to", kira); // Ugin ability
setStopAt(3, PhaseStep.END_TURN); setStopAt(3, PhaseStep.END_TURN);
execute(); execute();

View file

@ -31,7 +31,7 @@ public class UnscytheKillerOfKingsTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk"); addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Prodigal Pyromancer"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Prodigal Pyromancer");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {source} deals 1 damage to ", "Sejiri Merfolk"); activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {this} deals 1 damage to ", "Sejiri Merfolk");
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
@ -52,7 +52,7 @@ public class UnscytheKillerOfKingsTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Lightning Bolt"); addCard(Zone.HAND, playerA, "Lightning Bolt");
addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm"); addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals 1 damage to ", "Craw Wurm"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals 1 damage to ", "Craw Wurm");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Equip", "Prodigal Pyromancer"); activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Equip", "Prodigal Pyromancer");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Craw Wurm", "Equip", StackClause.WHILE_NOT_ON_STACK); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Craw Wurm", "Equip", StackClause.WHILE_NOT_ON_STACK);

View file

@ -98,7 +98,7 @@ public class GameIsADrawTest extends CardTestPlayerBase {
setChoice(playerA, "PlayerA"); setChoice(playerA, "PlayerA");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Stuffy Doll"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Stuffy Doll");
activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {source} deals"); activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {this} deals");
setStopAt(3, PhaseStep.END_TURN); setStopAt(3, PhaseStep.END_TURN);
execute(); execute();

View file

@ -191,8 +191,8 @@ public class TestAliases extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
showAvailableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA); showAvailableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Silvercoat Lion"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Silvercoat Lion");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Silvercoat Lion"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Silvercoat Lion");
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
@ -209,8 +209,8 @@ public class TestAliases extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion@lion", 1); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion@lion", 1);
showAvailableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA); showAvailableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "@lion"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "@lion");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "@lion"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "@lion");
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();

View file

@ -1,6 +1,18 @@
package mage.verify; package mage.verify;
import com.google.common.base.CharMatcher; import com.google.common.base.CharMatcher;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.effects.keyword.ScryEffect;
@ -35,19 +47,6 @@ import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.images.DownloadPicturesService; import org.mage.plugins.card.images.DownloadPicturesService;
import org.reflections.Reflections; import org.reflections.Reflections;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* @author JayDi85 * @author JayDi85
*/ */
@ -553,8 +552,9 @@ public class VerifyCardDataTest {
// missing // missing
for (ExpansionSet set : xmageSets) { for (ExpansionSet set : xmageSets) {
if (skipListHaveName(SKIP_LIST_SCRYFALL_DOWNLOAD_SETS, set.getCode())) if (skipListHaveName(SKIP_LIST_SCRYFALL_DOWNLOAD_SETS, set.getCode())) {
continue; continue;
}
if (!scryfallSets.contains(set.getCode())) { if (!scryfallSets.contains(set.getCode())) {
errorsList.add("Error: scryfall download missing setting: " + set.getCode() + " - " + set.getName()); errorsList.add("Error: scryfall download missing setting: " + set.getCode() + " - " + set.getName());
@ -944,7 +944,6 @@ public class VerifyCardDataTest {
Reflections reflections = new Reflections("mage."); Reflections reflections = new Reflections("mage.");
Set<Class<? extends Plane>> planesClassesList = reflections.getSubTypesOf(Plane.class); Set<Class<? extends Plane>> planesClassesList = reflections.getSubTypesOf(Plane.class);
// 1. correct class name // 1. correct class name
for (Class<? extends Plane> planeClass : planesClassesList) { for (Class<? extends Plane> planeClass : planesClassesList) {
if (!planeClass.getName().endsWith("Plane")) { if (!planeClass.getName().endsWith("Plane")) {
@ -1086,7 +1085,7 @@ public class VerifyCardDataTest {
// fix names (e.g. Urzas to Urza's) // fix names (e.g. Urzas to Urza's)
if (expected != null && expected.contains("Urzas")) { if (expected != null && expected.contains("Urzas")) {
expected = new ArrayList<>(expected); expected = new ArrayList<>(expected);
for (ListIterator<String> it = ((List<String>) expected).listIterator(); it.hasNext(); ) { for (ListIterator<String> it = ((List<String>) expected).listIterator(); it.hasNext();) {
if (it.next().equals("Urzas")) { if (it.next().equals("Urzas")) {
it.set("Urza's"); it.set("Urza's");
} }
@ -1205,7 +1204,6 @@ public class VerifyCardDataTest {
// replace special text and symbols // replace special text and symbols
newRule = newRule newRule = newRule
.replace("{this}", cardName) .replace("{this}", cardName)
.replace("{source}", cardName)
.replace("", "-") .replace("", "-")
.replace("", "-") .replace("", "-")
.replace("&mdash;", "-"); .replace("&mdash;", "-");
@ -1302,7 +1300,6 @@ public class VerifyCardDataTest {
} }
}*/ }*/
private void checkWrongAbilitiesText(Card card, MtgJsonCard ref, int cardIndex) { private void checkWrongAbilitiesText(Card card, MtgJsonCard ref, int cardIndex) {
// checks missing or wrong text // checks missing or wrong text
if (!card.getExpansionSetCode().equals(FULL_ABILITIES_CHECK_SET_CODE)) { if (!card.getExpansionSetCode().equals(FULL_ABILITIES_CHECK_SET_CODE)) {

View file

@ -1,5 +1,10 @@
package mage.abilities; package mage.abilities;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import mage.MageIdentifier;
import mage.MageObject; import mage.MageObject;
import mage.abilities.costs.*; import mage.abilities.costs.*;
import mage.abilities.costs.common.PayLifeCost; import mage.abilities.costs.common.PayLifeCost;
@ -31,12 +36,6 @@ import mage.util.ThreadLocalStringBuilder;
import mage.watchers.Watcher; import mage.watchers.Watcher;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import mage.MageIdentifier;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -801,7 +800,6 @@ public abstract class AbilityImpl implements Ability {
String replace = rule; String replace = rule;
if (rule != null && source != null && !source.isEmpty()) { if (rule != null && source != null && !source.isEmpty()) {
replace = rule.replace("{this}", source); replace = rule.replace("{this}", source);
replace = replace.replace("{source}", source);
} }
return replace; return replace;
} }

View file

@ -1,5 +1,6 @@
package mage.abilities; package mage.abilities;
import java.util.*;
import mage.abilities.costs.OptionalAdditionalModeSourceCosts; import mage.abilities.costs.OptionalAdditionalModeSourceCosts;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -11,8 +12,6 @@ import mage.players.Player;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import java.util.*;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -446,10 +445,7 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
} }
public String getText(String sourceName) { public String getText(String sourceName) {
String text = getText(); return getText().replace("{this}", sourceName);
text = text.replace("{this}", sourceName);
text = text.replace("{source}", sourceName);
return text;
} }
public boolean isEachModeOnlyOnce() { public boolean isEachModeOnlyOnce() {

View file

@ -32,7 +32,7 @@ public enum ProwlCostWasPaidCondition implements Condition {
@Override @Override
public String toString() { public String toString() {
return "{source}'s prowl cost was paid"; return "{this}'s prowl cost was paid";
} }
} }

View file

@ -55,6 +55,6 @@ public class SourcePermanentPowerCount implements DynamicValue {
@Override @Override
public String getMessage() { public String getMessage() {
return "{source}'s power"; return "{this}'s power";
} }
} }

View file

@ -52,6 +52,6 @@ public class SourcePermanentToughnessValue implements DynamicValue {
@Override @Override
public String getMessage() { public String getMessage() {
return "{source}'s toughness"; return "{this}'s toughness";
} }
} }

View file

@ -19,7 +19,7 @@ public class DamageAllEffect extends OneShotEffect {
private FilterPermanent filter; private FilterPermanent filter;
private DynamicValue amount; private DynamicValue amount;
private String sourceName = "{source}"; private String sourceName = "{this}";
public DamageAllEffect(int amount, FilterPermanent filter) { public DamageAllEffect(int amount, FilterPermanent filter) {
this(StaticValue.get(amount), filter); this(StaticValue.get(amount), filter);

View file

@ -19,7 +19,7 @@ import mage.game.permanent.Permanent;
public class DamageAttachedEffect extends OneShotEffect { public class DamageAttachedEffect extends OneShotEffect {
protected DynamicValue amount; protected DynamicValue amount;
private String sourceName = "{source}"; private String sourceName = "{this}";
public DamageAttachedEffect(int amount) { public DamageAttachedEffect(int amount) {
super(Outcome.Damage); super(Outcome.Damage);

View file

@ -19,7 +19,7 @@ public class DamageControllerEffect extends OneShotEffect {
protected DynamicValue amount; protected DynamicValue amount;
protected boolean preventable; protected boolean preventable;
private String sourceName = "{source}"; private String sourceName = "{this}";
public DamageControllerEffect(int amount, String whoDealDamageName) { public DamageControllerEffect(int amount, String whoDealDamageName) {
this(amount, true, whoDealDamageName); this(amount, true, whoDealDamageName);

View file

@ -22,7 +22,7 @@ public class DamageEverythingEffect extends OneShotEffect {
private DynamicValue amount; private DynamicValue amount;
private FilterPermanent filter; private FilterPermanent filter;
private UUID damageSource; private UUID damageSource;
private String sourceName = "{source}"; private String sourceName = "{this}";
public DamageEverythingEffect(int amount) { public DamageEverythingEffect(int amount) {
this(StaticValue.get(amount), new FilterCreaturePermanent()); this(StaticValue.get(amount), new FilterCreaturePermanent());

View file

@ -22,7 +22,7 @@ import java.util.UUID;
public class DamageMultiEffect extends OneShotEffect { public class DamageMultiEffect extends OneShotEffect {
protected DynamicValue amount; protected DynamicValue amount;
private String sourceName = "{source}"; private String sourceName = "{this}";
private final Set<MageObjectReference> damagedSet = new HashSet<>(); private final Set<MageObjectReference> damagedSet = new HashSet<>();
public DamageMultiEffect(int amount) { public DamageMultiEffect(int amount) {

View file

@ -17,7 +17,7 @@ import java.util.UUID;
public class DamagePlayersEffect extends OneShotEffect { public class DamagePlayersEffect extends OneShotEffect {
private DynamicValue amount; private DynamicValue amount;
private TargetController controller; private TargetController controller;
private String sourceName = "{source}"; private String sourceName = "{this}";
public DamagePlayersEffect(int amount) { public DamagePlayersEffect(int amount) {
this(Outcome.Damage, StaticValue.get(amount)); this(Outcome.Damage, StaticValue.get(amount));

View file

@ -47,7 +47,7 @@ public class DamageSelfEffect extends OneShotEffect {
return staticText; return staticText;
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("{source} deals ").append(amount).append(" damage to itself"); sb.append("{this} deals ").append(amount).append(" damage to itself");
return sb.toString(); return sb.toString();
} }
} }

View file

@ -24,7 +24,7 @@ public class DamageTargetEffect extends OneShotEffect {
protected boolean preventable; protected boolean preventable;
protected String targetDescription; protected String targetDescription;
protected boolean useOnlyTargetPointer; protected boolean useOnlyTargetPointer;
protected String sourceName = "{source}"; protected String sourceName = "{this}";
public DamageTargetEffect(int amount) { public DamageTargetEffect(int amount) {
this(StaticValue.get(amount), true); this(StaticValue.get(amount), true);

View file

@ -1,5 +1,6 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import java.util.Locale;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
@ -13,8 +14,6 @@ import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.Locale;
public class DoIfCostPaid extends OneShotEffect { public class DoIfCostPaid extends OneShotEffect {
protected Effects executingEffects = new Effects(); protected Effects executingEffects = new Effects();
@ -85,11 +84,10 @@ public class DoIfCostPaid extends OneShotEffect {
} }
message = getCostText() + (effectText.isEmpty() ? "" : " and " + effectText) + "?"; message = getCostText() + (effectText.isEmpty() ? "" : " and " + effectText) + "?";
message = Character.toUpperCase(message.charAt(0)) + message.substring(1); message = Character.toUpperCase(message.charAt(0)) + message.substring(1);
CardUtil.replaceSourceName(message, mageObject.getName());
} else { } else {
message = chooseUseText; message = chooseUseText;
} }
message = CardUtil.replaceSourceName(message, mageObject.getLogName()); message = CardUtil.replaceSourceName(message, mageObject.getName());
boolean result = true; boolean result = true;
Outcome payOutcome = executingEffects.getOutcome(source, this.outcome); Outcome payOutcome = executingEffects.getOutcome(source, this.outcome);
if (cost.canPay(source, source.getSourceId(), player.getId(), game) if (cost.canPay(source, source.getSourceId(), player.getId(), game)

View file

@ -18,7 +18,7 @@ public class DontUntapAsLongAsSourceTappedEffect extends ConditionalContinuousRu
public DontUntapAsLongAsSourceTappedEffect() { public DontUntapAsLongAsSourceTappedEffect() {
super(new DontUntapInControllersUntapStepTargetEffect(Duration.Custom), SourceTappedCondition.instance); super(new DontUntapInControllersUntapStepTargetEffect(Duration.Custom), SourceTappedCondition.instance);
staticText = "It doesn't untap during its controller's untap step for as long as {source} remains tapped."; staticText = "It doesn't untap during its controller's untap step for as long as {this} remains tapped.";
} }
public DontUntapAsLongAsSourceTappedEffect(final DontUntapAsLongAsSourceTappedEffect effect) { public DontUntapAsLongAsSourceTappedEffect(final DontUntapAsLongAsSourceTappedEffect effect) {

View file

@ -60,7 +60,7 @@ public class PreventDamageToSourceEffect extends PreventionEffectImpl {
} else { } else {
sb.append("Prevent the next ").append(amountToPrevent).append(" damage that would be dealt to "); sb.append("Prevent the next ").append(amountToPrevent).append(" damage that would be dealt to ");
} }
sb.append("{source} "); sb.append("{this} ");
if (duration == EndOfTurn) { if (duration == EndOfTurn) {
sb.append("this turn"); sb.append("this turn");
} else { } else {

View file

@ -27,7 +27,7 @@ public class ProtectionChosenColorAttachedEffect extends ContinuousEffectImpl {
public ProtectionChosenColorAttachedEffect(boolean notRemoveItself) { public ProtectionChosenColorAttachedEffect(boolean notRemoveItself) {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.notRemoveItself = notRemoveItself; this.notRemoveItself = notRemoveItself;
staticText = "{source} has protection from the chosen color" + (notRemoveItself ? ". This effect doesn't remove {this}" : ""); staticText = "{this} has protection from the chosen color" + (notRemoveItself ? ". This effect doesn't remove {this}" : "");
} }
public ProtectionChosenColorAttachedEffect(final ProtectionChosenColorAttachedEffect effect) { public ProtectionChosenColorAttachedEffect(final ProtectionChosenColorAttachedEffect effect) {

View file

@ -25,7 +25,7 @@ public class ProtectionChosenColorSourceEffect extends ContinuousEffectImpl {
public ProtectionChosenColorSourceEffect() { public ProtectionChosenColorSourceEffect() {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
staticText = "{source} has protection from the chosen color"; staticText = "{this} has protection from the chosen color";
} }
public ProtectionChosenColorSourceEffect(final ProtectionChosenColorSourceEffect effect) { public ProtectionChosenColorSourceEffect(final ProtectionChosenColorSourceEffect effect) {

View file

@ -12,7 +12,7 @@ public enum Duration {
EndOfTurn("until end of turn", true, true), EndOfTurn("until end of turn", true, true),
UntilYourNextTurn("until your next turn", true, true), UntilYourNextTurn("until your next turn", true, true),
UntilEndOfYourNextTurn("until the end of your next turn", true, true), UntilEndOfYourNextTurn("until the end of your next turn", true, true),
UntilSourceLeavesBattlefield("until {source} leaves the battlefield", true, false), // supported for continuous layered effects UntilSourceLeavesBattlefield("until {this} leaves the battlefield", true, false), // supported for continuous layered effects
EndOfCombat("until end of combat", true, true), EndOfCombat("until end of combat", true, true),
EndOfStep("until end of phase step", true, true), EndOfStep("until end of phase step", true, true),
Custom("", true, true); Custom("", true, true);

View file

@ -1,5 +1,11 @@
package mage.util; package mage.util;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import mage.MageObject; import mage.MageObject;
import mage.Mana; import mage.Mana;
import mage.abilities.Abilities; import mage.abilities.Abilities;
@ -25,13 +31,6 @@ import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.util.functions.CopyTokenFunction; import mage.util.functions.CopyTokenFunction;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/** /**
* @author nantuko * @author nantuko
*/ */
@ -242,7 +241,8 @@ public final class CardUtil {
* @param spellAbility * @param spellAbility
* @param manaCostsToReduce costs to reduce * @param manaCostsToReduce costs to reduce
* @param convertToGeneric colored mana does reduce generic mana if no * @param convertToGeneric colored mana does reduce generic mana if no
* appropriate colored mana is in the costs included * appropriate colored mana is in the costs
* included
*/ */
public static void adjustCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce, boolean convertToGeneric) { public static void adjustCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce, boolean convertToGeneric) {
ManaCosts<ManaCost> previousCost = spellAbility.getManaCostsToPay(); ManaCosts<ManaCost> previousCost = spellAbility.getManaCostsToPay();
@ -462,9 +462,7 @@ public final class CardUtil {
} }
public static String replaceSourceName(String message, String sourceName) { public static String replaceSourceName(String message, String sourceName) {
message = message.replace("{this}", sourceName); return message.replace("{this}", sourceName);
message = message.replace("{source}", sourceName);
return message;
} }
public static String booleanToFlipName(boolean flip) { public static String booleanToFlipName(boolean flip) {
@ -767,8 +765,12 @@ public final class CardUtil {
// +0/-1 must be -0/-1 // +0/-1 must be -0/-1
String signedP = String.format("%1$+d", power); String signedP = String.format("%1$+d", power);
String signedT = String.format("%1$+d", toughness); String signedT = String.format("%1$+d", toughness);
if (signedP.equals("+0") && signedT.startsWith("-")) signedP = "-0"; if (signedP.equals("+0") && signedT.startsWith("-")) {
if (signedT.equals("+0") && signedP.startsWith("-")) signedT = "-0"; signedP = "-0";
}
if (signedT.equals("+0") && signedP.startsWith("-")) {
signedT = "-0";
}
return signedP + "/" + signedT; return signedP + "/" + signedT;
} }