* 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<>();
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}");

View file

@ -1,5 +1,23 @@
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.cards.repository.CardInfo;
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.log4j.Logger;
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;
public final class ManaSymbols {
@ -77,22 +74,22 @@ public final class ManaSymbols {
withoutSymbols.add("P09");
withoutSymbols.add("P10");
withoutSymbols.add("P11");
}
private static final Map<String, Dimension> setImagesExist = new HashMap<>();
private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}");
private static final String[] symbols = new String[]{
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
"B", "BG", "BR", "BP", "2B",
"G", "GU", "GW", "GP", "2G",
"R", "RG", "RW", "RP", "2R",
"S", "T", "Q",
"U", "UB", "UR", "UP", "2U",
"W", "WB", "WU", "WP", "2W",
"X", "C", "E"};
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
"B", "BG", "BR", "BP", "2B",
"G", "GU", "GW", "GP", "2G",
"R", "RG", "RW", "RP", "2R",
"S", "T", "Q",
"U", "UB", "UR", "UP", "2U",
"W", "WB", "WU", "WP", "2W",
"X", "C", "E"};
private static final JLabel labelRender = new JLabel(); // render mana text
@ -173,7 +170,7 @@ public final class ManaSymbols {
}
// preload set images
List<String> setCodes = ExpansionRepository.instance.getSetCodes();
java.util.List<String> setCodes = ExpansionRepository.instance.getSetCodes();
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.
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();
for (String s : manaCost) {
sb.append(s);
@ -778,7 +775,6 @@ public final class ManaSymbols {
// replace every {symbol} to <img> link
// ignore data backup
String replaced = value
.replace("{source}", "|source|")
.replace("{this}", "|this|");
// not need to add different images (width and height do the work)
@ -790,7 +786,7 @@ public final class ManaSymbols {
replaced = replaced.replace(CardInfo.SPLIT_MANA_SEPARATOR_FULL, CardInfo.SPLIT_MANA_SEPARATOR_RENDER);
replaced = REPLACE_SYMBOLS_PATTERN.matcher(replaced).replaceAll(
"<img src='" + filePathToUrl(htmlImagesPath) + "$1$2" + ".png' alt='$1$2' width="
+ symbolSize + " height=" + symbolSize + '>');
+ symbolSize + " height=" + symbolSize + '>');
// replace hint icons
if (replaced.contains(HintUtils.HINT_ICON_GOOD)) {
@ -808,7 +804,6 @@ public final class ManaSymbols {
// ignored data restore
replaced = replaced
.replace("|source|", "{source}")
.replace("|this|", "{this}")
.replace("@S@", "$");

View file

@ -1,5 +1,18 @@
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.abilities.*;
import mage.abilities.costs.VariableCost;
@ -17,6 +30,8 @@ import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
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.common.FilterAttackingCreature;
import mage.filter.common.FilterBlockingCreature;
@ -47,16 +62,6 @@ import mage.util.ManaUtil;
import mage.util.MessageToClient;
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
*/
@ -301,7 +306,6 @@ public class HumanPlayer extends PlayerImpl {
}
}
while (canRespond()) {
if (messageToClient.getSecondMessage() == null) {
messageToClient.setSecondMessage(getRelatedObjectName(source, game));
@ -490,7 +494,7 @@ public class HumanPlayer extends PlayerImpl {
required = false;
}
List<UUID> chosen = target.getTargets();
java.util.List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen);
updateGameStatePriority("choose(5)", game);
@ -656,9 +660,9 @@ public class HumanPlayer extends PlayerImpl {
}
Map<String, Serializable> options = getOptions(target, null);
List<UUID> chosen = target.getTargets();
java.util.List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen);
List<UUID> choosable = new ArrayList<>();
java.util.List<UUID> choosable = new ArrayList<>();
for (UUID cardId : cards) {
if (target.canTarget(abilityControllerId, cardId, null, cards, game)) {
choosable.add(cardId);
@ -730,9 +734,9 @@ public class HumanPlayer extends PlayerImpl {
}
Map<String, Serializable> options = getOptions(target, null);
List<UUID> chosen = target.getTargets();
java.util.List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen);
List<UUID> choosable = new ArrayList<>();
java.util.List<UUID> choosable = new ArrayList<>();
for (UUID cardId : cards) {
if (target.canTarget(abilityControllerId, cardId, source, cards, game)) {
choosable.add(cardId);
@ -801,9 +805,9 @@ public class HumanPlayer extends PlayerImpl {
if (!isExecutingMacro()) {
String selectedNames = target.getTargetedName(game);
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage()
+ "<br> Amount remaining: " + target.getAmountRemaining()
+ (selectedNames.isEmpty() ? "" : ", selected: " + selectedNames),
getRelatedObjectName(source, game)),
+ "<br> Amount remaining: " + target.getAmountRemaining()
+ (selectedNames.isEmpty() ? "" : ", selected: " + selectedNames),
getRelatedObjectName(source, game)),
possibleTargets,
required,
getOptions(target, null));
@ -817,7 +821,7 @@ public class HumanPlayer extends PlayerImpl {
boolean removeMode = target.getTargets().contains(targetId)
&& chooseUse(outcome, "What do you want to do with " + (targetObject != null ? targetObject.getLogName() : " target") + "?", "",
"Remove from selected", "Add extra amount (remaining " + target.getAmountRemaining() + ")", source, game);
"Remove from selected", "Add extra amount (remaining " + target.getAmountRemaining() + ")", source, game);
if (removeMode) {
target.remove(targetId);
@ -959,9 +963,9 @@ public class HumanPlayer extends PlayerImpl {
if (!skippedAtLeastOnce
|| (playerId.equals(game.getActivePlayerId())
&& !controllingPlayer
.getUserData()
.getUserSkipPrioritySteps()
.isStopOnAllEndPhases())) {
.getUserData()
.getUserSkipPrioritySteps()
.isStopOnAllEndPhases())) {
skippedAtLeastOnce = true;
if (passWithManaPoolCheck(game)) {
return false;
@ -993,9 +997,9 @@ public class HumanPlayer extends PlayerImpl {
if (haveNewObjectsOnStack
&& (playerId.equals(game.getActivePlayerId())
&& controllingPlayer
.getUserData()
.getUserSkipPrioritySteps()
.isStopOnStackNewObjects())) {
.getUserData()
.getUserSkipPrioritySteps()
.isStopOnStackNewObjects())) {
// new objects on stack -- disable "pass until stack resolved"
passedUntilStackResolved = false;
} else {
@ -1131,7 +1135,7 @@ public class HumanPlayer extends PlayerImpl {
}
@Override
public TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game) {
public TriggeredAbility chooseTriggeredAbility(java.util.List<TriggeredAbility> abilities, Game game) {
// choose triggered abilitity from list
if (gameInCheckPlayableState(game)) {
return null;
@ -1141,7 +1145,7 @@ public class HumanPlayer extends PlayerImpl {
boolean autoOrderUse = getControllingPlayersUserData(game).isAutoOrderTrigger();
while (canRespond()) {
// try to set trigger auto order
List<TriggeredAbility> abilitiesWithNoOrderSet = new ArrayList<>();
java.util.List<TriggeredAbility> abilitiesWithNoOrderSet = new ArrayList<>();
TriggeredAbility abilityOrderLast = null;
for (TriggeredAbility ability : abilities) {
if (triggerAutoOrderAbilityFirst.contains(ability.getOriginalId())) {
@ -1399,7 +1403,7 @@ public class HumanPlayer extends PlayerImpl {
filter.add(new ControllerIdPredicate(attackingPlayerId));
while (canRespond()) {
List<UUID> possibleAttackers = new ArrayList<>();
java.util.List<UUID> possibleAttackers = new ArrayList<>();
for (Permanent possibleAttacker : game.getBattlefield().getActivePermanents(filter, attackingPlayerId, game)) {
if (possibleAttacker.canAttack(null, game)) {
possibleAttackers.add(possibleAttacker.getId());
@ -1413,8 +1417,8 @@ public class HumanPlayer extends PlayerImpl {
if (passedAllTurns
|| passedUntilEndStepBeforeMyTurn
|| (!getControllingPlayersUserData(game)
.getUserSkipPrioritySteps()
.isStopOnDeclareAttackers()
.getUserSkipPrioritySteps()
.isStopOnDeclareAttackers()
&& (passedTurn
|| passedTurnSkipStack
|| passedUntilEndOfTurn
@ -1682,7 +1686,7 @@ public class HumanPlayer extends PlayerImpl {
prepareForResponse(game);
if (!isExecutingMacro()) {
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())
.collect(Collectors.toList());
options.put(Constants.Option.POSSIBLE_BLOCKERS, (Serializable) possibleBlockers);
@ -1715,7 +1719,7 @@ public class HumanPlayer extends PlayerImpl {
}
@Override
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) {
public UUID chooseAttackerOrder(java.util.List<Permanent> attackers, Game game) {
if (gameInCheckPlayableState(game)) {
return null;
}
@ -1740,7 +1744,7 @@ public class HumanPlayer extends PlayerImpl {
}
@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)) {
return null;
}
@ -1809,7 +1813,7 @@ public class HumanPlayer extends PlayerImpl {
}
@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);
int remainingDamage = damage;
while (remainingDamage > 0 && canRespond()) {
@ -1873,7 +1877,7 @@ public class HumanPlayer extends PlayerImpl {
}
@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);
}
@ -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
String modeText = mode.getEffects().getText(mode);
if (obj != null) {
modeText = modeText.replace("{source}", obj.getName()).replace("{this}", obj.getName());
modeText = modeText.replace("{this}", obj.getName());
}
if (modes.isEachModeMoreThanOnce()) {
if (timesSelected > 0) {
@ -2131,7 +2135,7 @@ public class HumanPlayer extends PlayerImpl {
}
@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)) {
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.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new ManaCostsImpl("{B}"));
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.addCost(new TapSourceCost());
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.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
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);
}

View file

@ -68,7 +68,7 @@ class ArcTrailEffect extends OneShotEffect {
private ArcTrailEffect() {
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

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.
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().addTarget(new TargetAttackingCreature());
}

View file

@ -41,7 +41,7 @@ class BookBurningMillEffect extends OneShotEffect {
public BookBurningMillEffect() {
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) {

View file

@ -54,7 +54,7 @@ class BrainGorgersCounterSourceEffect extends OneShotEffect {
public BrainGorgersCounterSourceEffect() {
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) {

View file

@ -41,7 +41,7 @@ class BrowbeatDrawEffect extends OneShotEffect {
public BrowbeatDrawEffect() {
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) {

View file

@ -77,6 +77,6 @@ class ChandrasPyrelingAbility extends TriggeredAbilityImpl {
@Override
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());
// Sacrifice a Goblin: Clickslither gets +2/+2 and gains trample until end of turn.
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,
new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter,true)));
effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);

View file

@ -40,7 +40,7 @@ public final class CloakAndDagger extends CardImpl {
this.addAbility(ability);
// Whenever a Rogue creature enters the battlefield, you may attach Cloak and Dagger to it.
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));
// Equip {3}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3)));

View file

@ -63,7 +63,7 @@ class ConeOfFlameEffect extends OneShotEffect {
public ConeOfFlameEffect() {
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, "
+ "and 3 damage to a third target";
}

View file

@ -48,7 +48,7 @@ class DashHopesCounterSourceEffect extends OneShotEffect {
public DashHopesCounterSourceEffect() {
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) {

View file

@ -127,7 +127,7 @@ class DiseasedVerminPredicate implements ObjectSourcePlayerPredicate<ObjectSourc
@Override
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.
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));
// Equip {3}

View file

@ -85,7 +85,7 @@ class AddCounterAbility extends TriggeredAbilityImpl {
@Override
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.
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().addTarget(new TargetAnyTargetAmount(2));
// 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.
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)));
}

View file

@ -79,7 +79,7 @@ class PlayALandTriggeredAbility extends TriggeredAbilityImpl {
@Override
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);
effect1.setText("Feast of Flesh deals X damage to target creature");
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(effect2);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());

View file

@ -45,7 +45,7 @@ public final class FelhideSpiritbinder extends CardImpl {
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.
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));
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.
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().addTarget(new TargetCreaturePermanent());
}

View file

@ -75,7 +75,7 @@ class GhastlyRemainsTriggeredAbility extends BeginningOfUpkeepTriggeredAbility {
@Override
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() {
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) {

View file

@ -74,7 +74,7 @@ class GigapedeTriggerdAbility extends BeginningOfUpkeepTriggeredAbility{
@Override
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.
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));
// Equip {4}

View file

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

View file

@ -95,7 +95,7 @@ class IchoridTriggerdAbility extends BeginningOfUpkeepTriggeredAbility{
@Override
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.
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().addTarget(new TargetAnyTarget());
}

View file

@ -60,7 +60,7 @@ class KjeldoranRoyalGuardEffect extends ReplacementEffectImpl {
KjeldoranRoyalGuardEffect() {
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) {

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.
IntPlusDynamicValue value = new IntPlusDynamicValue(1, new CardsInAllGraveyardsCount(filter));
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);
}

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.
this.getSpellAbility().addEffect(new GainLifeTargetEffect(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().addTarget(new TargetPlayer());
}

View file

@ -55,7 +55,7 @@ public final class LyzoldaTheBloodWitch extends CardImpl {
Effect effect = new ConditionalOneShotEffect(
new DamageTargetEffect(2),
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}"));
effect = new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1),

View file

@ -135,6 +135,6 @@ class MindreaverNamePredicate implements Predicate<MageObject> {
@Override
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
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);
// Whenever a Warrior creature enters the battlefield, you may attach Obsidian Battle-Axe to it.
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));
// Equip {3}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3)));

View file

@ -128,6 +128,9 @@ class OdricMasterTacticianChooseBlockersEffect extends ContinuousRuleModifyingEf
@Override
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);
if (watcher == null) {
return false;

View file

@ -170,6 +170,6 @@ class PowerLowerEqualSourcePredicate implements ObjectPlayerPredicate<ObjectPlay
@Override
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.
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));
effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and gains trample until end of turn");

View file

@ -97,6 +97,6 @@ class CounterSourceEffect extends OneShotEffect {
if (staticText != null && !staticText.isEmpty()) {
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.
DynamicValue dogCount = new PermanentsOnBattlefieldCount(dogPermanentFilter);
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);
Effect lifeGainEffect = new GainLifeEffect(catCount);
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)));
// Whenever a creature enters the battlefield under your control, you may attach Sai of the Shinobi to it.
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));
// Equip {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.
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));
}

View file

@ -41,7 +41,7 @@ class SkullcageEffect extends OneShotEffect {
public SkullcageEffect() {
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) {

View file

@ -41,7 +41,7 @@ class SkullscorchDiscardEffect extends OneShotEffect {
public SkullscorchDiscardEffect() {
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) {

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.
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));
// 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.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
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);
}

View file

@ -45,7 +45,7 @@ class TemporalExtortionCounterSourceEffect extends OneShotEffect {
public TemporalExtortionCounterSourceEffect() {
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) {

View file

@ -51,7 +51,7 @@ public final class ThornbiteStaff extends CardImpl {
this.addAbility(ability);
// Whenever a Shaman creature enters the battlefield, you may attach Thornbite Staff to it.
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));
// Equip {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.
Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{2}{G}"));
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());
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);
this.addAbility(ability);
}

View file

@ -63,7 +63,7 @@ class VeteranBodyguardEffect extends PreventionEffectImpl {
VeteranBodyguardEffect() {
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) {

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.
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));
// Equip {2}

View file

@ -46,7 +46,7 @@ class ViselingEffect extends OneShotEffect {
public ViselingEffect() {
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) {

View file

@ -70,6 +70,6 @@ class WickedAkubaPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePl
@Override
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");
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);
execute();
@ -48,7 +48,7 @@ public class HeavyArbalestTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves");
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");
setStopAt(5, PhaseStep.BEGIN_COMBAT);

View file

@ -62,7 +62,7 @@ public class ChampionTest extends CardTestPlayerBase {
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);
execute();

View file

@ -63,7 +63,7 @@ public class SatyrFiredancerTest extends CardTestPlayerBase {
// {T}: Prodigal Pyromancer deals 1 damage to any target.
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);
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.
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");
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");
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);
execute();
@ -61,8 +61,8 @@ public class HavengulLichTest extends CardTestPlayerBase {
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: You may", "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}: {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);
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);
execute();

View file

@ -46,7 +46,7 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flametongue Kavu");
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.",
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");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
@ -73,7 +73,7 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flametongue Kavu");
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.",
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");
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.");
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);
execute();

View file

@ -13,7 +13,7 @@ public class ChandrasMagmuttTest extends CardTestPlayerBase {
// {T}: Chandra's Magmutt deals 1 damage to target player or planeswalker.<
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);
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."
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);
setStrictChooseMode(true);
execute();

View file

@ -28,7 +28,7 @@ public class SyrCarahTheBoldTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
// 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);
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);
// 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
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
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
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);
execute();
@ -46,7 +46,7 @@ public class BloodCultistTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Indulgent Aristocrat", 1); // 1/1
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");
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
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Devilthorn Fox");
activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Shambling Ghoul");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Devilthorn Fox");
activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Shambling Ghoul");
attack(5, playerA, "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
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blood Cultist");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", "Devilthorn Fox");
activateAbility(5, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {source} deals", "Shambling Ghoul");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", "Devilthorn Fox");
activateAbility(5, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {this} deals", "Shambling Ghoul");
attack(5, playerA, "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
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");
setStopAt(3, PhaseStep.END_TURN);

View file

@ -28,7 +28,7 @@ public class DiesExiledTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
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);
execute();
@ -53,7 +53,7 @@ public class DiesExiledTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Frostwielder");
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);
execute();
@ -78,7 +78,7 @@ public class DiesExiledTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Kumano, Master Yamabushi");
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);
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, 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);
execute();
@ -44,7 +44,7 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Unsummon", 1);
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);
@ -62,8 +62,8 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyality counters
addCard(Zone.BATTLEFIELD, playerA, kira);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {source} deals 3 damage to", kira); // Ugin ability
activateAbility(3, 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: {this} deals 3 damage to", kira); // Ugin ability
setStopAt(3, PhaseStep.END_TURN);
execute();

View file

@ -31,7 +31,7 @@ public class UnscytheKillerOfKingsTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
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);
execute();
@ -52,7 +52,7 @@ public class UnscytheKillerOfKingsTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Lightning Bolt");
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");
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");
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);
execute();

View file

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

View file

@ -1,6 +1,18 @@
package mage.verify;
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.abilities.Ability;
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.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
*/
@ -553,8 +552,9 @@ public class VerifyCardDataTest {
// missing
for (ExpansionSet set : xmageSets) {
if (skipListHaveName(SKIP_LIST_SCRYFALL_DOWNLOAD_SETS, set.getCode()))
if (skipListHaveName(SKIP_LIST_SCRYFALL_DOWNLOAD_SETS, set.getCode())) {
continue;
}
if (!scryfallSets.contains(set.getCode())) {
errorsList.add("Error: scryfall download missing setting: " + set.getCode() + " - " + set.getName());
@ -944,7 +944,6 @@ public class VerifyCardDataTest {
Reflections reflections = new Reflections("mage.");
Set<Class<? extends Plane>> planesClassesList = reflections.getSubTypesOf(Plane.class);
// 1. correct class name
for (Class<? extends Plane> planeClass : planesClassesList) {
if (!planeClass.getName().endsWith("Plane")) {
@ -1086,7 +1085,7 @@ public class VerifyCardDataTest {
// fix names (e.g. Urzas to Urza's)
if (expected != null && expected.contains("Urzas")) {
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")) {
it.set("Urza's");
}
@ -1145,9 +1144,9 @@ public class VerifyCardDataTest {
// ability/effect must have description or not
boolean mustCheck = card.getAbilities().containsClass(objectClass)
|| card.getAbilities().stream()
.map(Ability::getAllEffects)
.flatMap(Collection::stream)
.anyMatch(effect -> effect.getClass().isAssignableFrom(objectClass));
.map(Ability::getAllEffects)
.flatMap(Collection::stream)
.anyMatch(effect -> effect.getClass().isAssignableFrom(objectClass));
mustCheck = false; // TODO: enable and fix all problems with effect and ability hints
if (mustCheck) {
boolean needHint = ref.text.contains(objectHint);
@ -1205,7 +1204,6 @@ public class VerifyCardDataTest {
// replace special text and symbols
newRule = newRule
.replace("{this}", cardName)
.replace("{source}", cardName)
.replace("", "-")
.replace("", "-")
.replace("&mdash;", "-");
@ -1248,7 +1246,7 @@ public class VerifyCardDataTest {
}
/*
/*
for(String rule : card.getRules()) {
rule = rule.replaceAll("(?i)<i>.+</i>", ""); // Ignoring reminder text in italic
// TODO: add Equip {3} checks
@ -1302,7 +1300,6 @@ public class VerifyCardDataTest {
}
}*/
private void checkWrongAbilitiesText(Card card, MtgJsonCard ref, int cardIndex) {
// checks missing or wrong text
if (!card.getExpansionSetCode().equals(FULL_ABILITIES_CHECK_SET_CODE)) {

View file

@ -1,5 +1,10 @@
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.abilities.costs.*;
import mage.abilities.costs.common.PayLifeCost;
@ -31,12 +36,6 @@ import mage.util.ThreadLocalStringBuilder;
import mage.watchers.Watcher;
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
*/
@ -74,7 +73,7 @@ public abstract class AbilityImpl implements Ability {
protected List<Hint> hints = new ArrayList<>();
protected Outcome customOutcome = null; // uses for AI decisions instead effects
protected MageIdentifier identifier; // used to identify specific ability (e.g. to match with corresponding watcher)
public AbilityImpl(AbilityType abilityType, Zone zone) {
this.id = UUID.randomUUID();
this.originalId = id;
@ -801,7 +800,6 @@ public abstract class AbilityImpl implements Ability {
String replace = rule;
if (rule != null && source != null && !source.isEmpty()) {
replace = rule.replace("{this}", source);
replace = replace.replace("{source}", source);
}
return replace;
}
@ -1318,5 +1316,5 @@ public abstract class AbilityImpl implements Ability {
public AbilityImpl setIdentifier(MageIdentifier identifier) {
this.identifier = identifier;
return this;
}
}
}

View file

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

View file

@ -32,7 +32,7 @@ public enum ProwlCostWasPaidCondition implements Condition {
@Override
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
public String getMessage() {
return "{source}'s power";
return "{this}'s power";
}
}

View file

@ -52,6 +52,6 @@ public class SourcePermanentToughnessValue implements DynamicValue {
@Override
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 DynamicValue amount;
private String sourceName = "{source}";
private String sourceName = "{this}";
public DamageAllEffect(int amount, FilterPermanent filter) {
this(StaticValue.get(amount), filter);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -47,7 +47,7 @@ public class DamageSelfEffect extends OneShotEffect {
return staticText;
}
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();
}
}

View file

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

View file

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

View file

@ -18,7 +18,7 @@ public class DontUntapAsLongAsSourceTappedEffect extends ConditionalContinuousRu
public DontUntapAsLongAsSourceTappedEffect() {
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) {

View file

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

View file

@ -27,7 +27,7 @@ public class ProtectionChosenColorAttachedEffect extends ContinuousEffectImpl {
public ProtectionChosenColorAttachedEffect(boolean notRemoveItself) {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
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) {

View file

@ -25,7 +25,7 @@ public class ProtectionChosenColorSourceEffect extends ContinuousEffectImpl {
public ProtectionChosenColorSourceEffect() {
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) {

View file

@ -12,7 +12,7 @@ public enum Duration {
EndOfTurn("until end of turn", true, true),
UntilYourNextTurn("until 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),
EndOfStep("until end of phase step", true, true),
Custom("", true, true);

View file

@ -1,5 +1,11 @@
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.Mana;
import mage.abilities.Abilities;
@ -25,13 +31,6 @@ import mage.players.Player;
import mage.target.Target;
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
*/
@ -40,10 +39,10 @@ public final class CardUtil {
private static final String SOURCE_EXILE_ZONE_TEXT = "SourceExileZone";
static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
static final String[] ordinalStrings = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eightth", "ninth",
"tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"};
"tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"};
public static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
@ -242,7 +241,8 @@ public final class CardUtil {
* @param spellAbility
* @param manaCostsToReduce costs to reduce
* @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) {
ManaCosts<ManaCost> previousCost = spellAbility.getManaCostsToPay();
@ -462,9 +462,7 @@ public final class CardUtil {
}
public static String replaceSourceName(String message, String sourceName) {
message = message.replace("{this}", sourceName);
message = message.replace("{source}", sourceName);
return message;
return message.replace("{this}", sourceName);
}
public static String booleanToFlipName(boolean flip) {
@ -767,8 +765,12 @@ public final class CardUtil {
// +0/-1 must be -0/-1
String signedP = String.format("%1$+d", power);
String signedT = String.format("%1$+d", toughness);
if (signedP.equals("+0") && signedT.startsWith("-")) signedP = "-0";
if (signedT.equals("+0") && signedP.startsWith("-")) signedT = "-0";
if (signedP.equals("+0") && signedT.startsWith("-")) {
signedP = "-0";
}
if (signedT.equals("+0") && signedP.startsWith("-")) {
signedT = "-0";
}
return signedP + "/" + signedT;
}