Effect withTargetDescription, other fixes for discrepencies with "target" text with reference (#13867)

* Add withTargetDescription support to all Effects

* use withTargetDescription for effects incorrectly with "target" in text

* CommanderStormAbility add support for non-target rules text

* Heliods Emissary use OrTriggeredAbility

* support all effects withTargetDescription, rename overwriteTargetDescription to targetDescription

* copy target description from old pointer when using setTargetPointer

* Text cleanup/simplifications

* Remove outdated warning
This commit is contained in:
ssk97 2025-07-19 00:11:26 -07:00 committed by GitHub
parent e56960c2ed
commit 1a6c2eede4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 136 additions and 66 deletions

View file

@ -30,7 +30,7 @@ public final class CircleOfFlame extends CardImpl {
// Whenever a creature without flying attacks you or a planeswalker you control, Circle of Flame deals 1 damage to that creature.
this.addAbility(new AttacksAllTriggeredAbility(new DamageTargetEffect(1), false,
this.addAbility(new AttacksAllTriggeredAbility(new DamageTargetEffect(1).withTargetDescription("that creature"), false,
filter, SetTargetPointer.PERMANENT, true));
}

View file

@ -1,7 +1,6 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
import mage.abilities.dynamicvalue.common.SignInversionDynamicValue;
@ -15,6 +14,8 @@ import mage.constants.Duration;
import mage.filter.common.FilterLandCard;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author LevelX2
@ -31,7 +32,7 @@ public final class DrownInFilth extends CardImpl {
effect.setText("Choose target creature. Mill four cards");
this.getSpellAbility().addEffect(effect);
DynamicValue landCards = new SignInversionDynamicValue(new CardsInControllerGraveyardCount(new FilterLandCard()));
this.getSpellAbility().addEffect(new BoostTargetEffect(landCards, landCards, Duration.EndOfTurn));
this.getSpellAbility().addEffect(new BoostTargetEffect(landCards, landCards, Duration.EndOfTurn).withTargetDescription(", then that creature"));
}
private DrownInFilth(final DrownInFilth card) {

View file

@ -1,6 +1,5 @@
package mage.cards.e;
import java.util.UUID;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.keyword.CommanderStormAbility;
import mage.cards.CardImpl;
@ -8,6 +7,8 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetArtifactPermanent;
import java.util.UUID;
/**
*
* @author TheElk801
@ -18,7 +19,7 @@ public final class EchoStorm extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}{U}");
// When you cast this spell, copy it for each time you've cast your commander from the command zone this game. You may choose new targets for the copies.
this.addAbility(new CommanderStormAbility());
this.addAbility(new CommanderStormAbility(true));
// Create a token that's a copy of target artifact.
this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect());

View file

@ -1,6 +1,5 @@
package mage.cards.e;
import java.util.UUID;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.CommanderStormAbility;
import mage.cards.CardImpl;
@ -8,6 +7,8 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.permanent.token.AngelToken;
import java.util.UUID;
/**
*
* @author TheElk801
@ -18,7 +19,7 @@ public final class EmpyrialStorm extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W}{W}");
// When you cast this spell, copy it for each time you've cast your commander from the command zone this game.
this.addAbility(new CommanderStormAbility());
this.addAbility(new CommanderStormAbility(false));
// Create a 4/4 white Angel creature token with flying.
this.getSpellAbility().addEffect(new CreateTokenEffect(new AngelToken()));

View file

@ -1,6 +1,5 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
import mage.abilities.keyword.CommanderStormAbility;
import mage.cards.CardImpl;
@ -9,6 +8,8 @@ import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.TargetSpell;
import java.util.UUID;
/**
*
* @author TheElk801
@ -19,7 +20,7 @@ public final class FuryStorm extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}{R}");
// When you cast this spell, copy it for each time you've cast your commander from the command zone this game. You may choose new targets for the copies.
this.addAbility(new CommanderStormAbility());
this.addAbility(new CommanderStormAbility(true));
// Copy target instant or sorcery spell. You may choose new targets for the copy.
this.getSpellAbility().addEffect(new CopyTargetStackObjectEffect());

View file

@ -1,20 +1,17 @@
package mage.cards.g;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.CommanderStormAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author TheElk801
@ -25,7 +22,7 @@ public final class GenesisStorm extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{G}");
// When you cast this spell, copy it for each time you've cast your commander from the command zone this game.
this.addAbility(new CommanderStormAbility());
this.addAbility(new CommanderStormAbility(false));
// Reveal cards from the top of your library until you reveal a nonland permanent card. You may put that card onto the battlefield. Then put all cards revealed this way that weren't put onto the battlefield on the bottom of your library in a random order.
this.getSpellAbility().addEffect(new GenesisStormEffect());

View file

@ -1,7 +1,6 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAttachedTriggeredAbility;
@ -10,17 +9,13 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.keyword.BestowAbility;
import mage.abilities.meta.OrTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.target.Target;
import mage.constants.*;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
import static mage.filter.StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE;
@ -31,7 +26,7 @@ import static mage.filter.StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE;
public final class HeliodsEmissary extends CardImpl {
public HeliodsEmissary(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{3}{W}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{W}");
this.subtype.add(SubType.ELK);
this.power = new MageInt(3);
@ -40,16 +35,14 @@ public final class HeliodsEmissary extends CardImpl {
// Bestow {6}{W}
this.addAbility(new BestowAbility(this, "{6}{W}"));
// Whenever Heliod's Emissary or enchanted creature attacks, tap target creature an opponent controls.
Ability ability = new AttacksTriggeredAbility(new TapTargetEffect(), false);
Target target = new TargetPermanent(FILTER_OPPONENTS_PERMANENT_CREATURE);
ability.addTarget(target);
this.addAbility(ability);
ability = new AttacksAttachedTriggeredAbility(new TapTargetEffect(), AttachmentType.AURA, false);
target = new TargetPermanent(FILTER_OPPONENTS_PERMANENT_CREATURE);
ability.addTarget(target);
Ability ability = new OrTriggeredAbility(Zone.BATTLEFIELD, new TapTargetEffect(),
false, "Whenever {this} or enchanted creature attacks, ",
new AttacksTriggeredAbility(null, false),
new AttacksAttachedTriggeredAbility(null, AttachmentType.AURA, false));
ability.addTarget(new TargetPermanent(FILTER_OPPONENTS_PERMANENT_CREATURE));
this.addAbility(ability);
// Enchanted creature gets +3/+3.
this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(3,3, Duration.WhileOnBattlefield)));
this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)));
}
private HeliodsEmissary(final HeliodsEmissary card) {

View file

@ -41,7 +41,7 @@ public final class KothOfTheHammer extends CardImpl {
// +1: Untap target Mountain. It becomes a 4/4 red Elemental creature until end of turn. It's still a land.
Ability ability = new LoyaltyAbility(new UntapTargetEffect(), 1);
ability.addEffect(new BecomesCreatureTargetEffect(new KothOfTheHammerToken(), false, true, Duration.EndOfTurn));
ability.addEffect(new BecomesCreatureTargetEffect(new KothOfTheHammerToken(), false, true, Duration.EndOfTurn).withTargetDescription("It"));
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
@ -65,7 +65,7 @@ public final class KothOfTheHammer extends CardImpl {
class KothOfTheHammerToken extends TokenImpl {
public KothOfTheHammerToken() {
super("Elemental", "4/4 red Elemental");
super("Elemental", "4/4 red Elemental creature");
this.cardType.add(CardType.CREATURE);
this.subtype.add(SubType.ELEMENTAL);

View file

@ -1,7 +1,6 @@
package mage.cards.l;
import java.util.UUID;
import mage.abilities.effects.common.PreventDamageToTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FlyingAbility;
@ -11,6 +10,8 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author noxx
@ -23,7 +24,7 @@ public final class LeapOfFaith extends CardImpl {
// Target creature gains flying until end of turn. Prevent all damage that would be dealt to that creature this turn.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn));
this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE));
this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE).withTargetDescription("that creature"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}

View file

@ -61,6 +61,7 @@ class MirrodinBesiegedEffect extends OneShotEffect {
MirrodinBesiegedEffect() {
super(Outcome.Benefit);
this.setText("draw a card, then discard a card. Then if there are fifteen or more artifact cards in your graveyard, target opponent loses the game.");
}
private MirrodinBesiegedEffect(final MirrodinBesiegedEffect effect) {

View file

@ -39,7 +39,7 @@ public final class PalazzoArchers extends CardImpl {
this.addAbility(ReachAbility.getInstance());
// Whenever a creature with flying attacks you or a planeswalker you control, Palazzo Archers deals damage equal to its power to that creature.
this.addAbility(new AttacksAllTriggeredAbility(new DamageTargetEffect(SourcePermanentPowerValue.NOT_NEGATIVE),
this.addAbility(new AttacksAllTriggeredAbility(new DamageTargetEffect(SourcePermanentPowerValue.NOT_NEGATIVE).withTargetDescription("that creature"),
false, filter, SetTargetPointer.PERMANENT, true));
}

View file

@ -25,7 +25,7 @@ public final class PippinsBravery extends CardImpl {
// You may sacrifice a Food. If you do, target creature gets +4/+4 until end of turn. Otherwise, that creature gets +2/+2 until end of turn.
this.getSpellAbility().addEffect(new DoIfCostPaid(
new BoostTargetEffect(4, 4),
new BoostTargetEffect(2, 2),
new BoostTargetEffect(2, 2).withTargetDescription("that creature"),
new SacrificeTargetCost(filter)
));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());

View file

@ -28,17 +28,17 @@ public final class PowerOfPersuasion extends CardImpl {
this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent());
// 1-9 | Return it to its owner's hand.
effect.addTableEntry(1, 9, new ReturnToHandTargetEffect().setText("return it to its owner's hand"));
effect.addTableEntry(1, 9, new ReturnToHandTargetEffect().withTargetDescription("it"));
// 10-19 | Its owner puts it on the top of bottom of their library.
effect.addTableEntry(10, 19, new PutOnTopOrBottomLibraryTargetEffect(false).setText(
"its owner puts it on the top or bottom of their library"
"its owner puts it on their choice of the top or bottom of their library"
));
// 20 | Gain control of it until the end of your next turn.
effect.addTableEntry(20, 20, new GainControlTargetEffect(
Duration.UntilEndOfYourNextTurn, true
).setText("gain control of it until the end of your next turn"));
).withTargetDescription("it"));
}
private PowerOfPersuasion(final PowerOfPersuasion card) {

View file

@ -25,7 +25,7 @@ public final class RevengeOfTheHunted extends CardImpl {
// Until end of turn, target creature gets +6/+6 and gains trample, and all creatures able to block it this turn do so.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new BoostTargetEffect(6, 6, Duration.EndOfTurn));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn).withTargetDescription("and"));
Effect effect = new MustBeBlockedByAllTargetEffect(Duration.EndOfTurn);
effect.setText("and all creatures able to block it this turn do so");
this.getSpellAbility().addEffect(effect);

View file

@ -40,13 +40,14 @@ public final class ScionOfStygia extends CardImpl {
this.addAbility(ability.withFlavorWord("Cone of Cold"));
// 1-9 | Tap that creature.
effect.addTableEntry(1, 9, new TapTargetEffect("tap that creature"));
effect.addTableEntry(1, 9, new TapTargetEffect());
// 10-20 | Tap that creature. It doesn't untap during its controller's next untap step.
effect.addTableEntry(
10, 20, new TapTargetEffect("tap that creature"),
10, 20, new TapTargetEffect(),
new DontUntapInControllersNextUntapStepTargetEffect("it")
);
effect.withTargetDescription("that creature");
}
private ScionOfStygia(final ScionOfStygia card) {

View file

@ -1,6 +1,5 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
@ -18,6 +17,8 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author TheElk801
@ -28,7 +29,7 @@ public final class SkullStorm extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{7}{B}{B}");
// When you cast this spell, copy it for each time you've cast your commander from the command zone this game.
this.addAbility(new CommanderStormAbility());
this.addAbility(new CommanderStormAbility(false));
// Each opponent sacrifices a creature. Each opponent who can't loses half their life, rounded up.
this.getSpellAbility().addEffect(new SkullStormEffect());
@ -48,7 +49,7 @@ class SkullStormEffect extends OneShotEffect {
SkullStormEffect() {
super(Outcome.Benefit);
this.staticText = "Each opponent sacrifices a creature. "
this.staticText = "Each opponent sacrifices a creature of their choice. "
+ "Each opponent who can't loses half their life, rounded up.";
}

View file

@ -1,7 +1,6 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
@ -13,6 +12,8 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author LevelX2
@ -28,8 +29,8 @@ public final class TurnAgainst extends CardImpl {
// Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn));
this.getSpellAbility().addEffect(new UntapTargetEffect());
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn));
this.getSpellAbility().addEffect(new UntapTargetEffect().withTargetDescription("that creature"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).withTargetDescription("It"));
}
private TurnAgainst(final TurnAgainst card) {

View file

@ -132,6 +132,13 @@ public class ConditionalOneShotEffect extends OneShotEffect {
return this;
}
@Override
public ConditionalOneShotEffect withTargetDescription(String target) {
effects.forEach(effect -> effect.withTargetDescription(target));
otherwiseEffects.forEach(effect -> effect.withTargetDescription(target));
return this;
}
@Override
public Condition getCondition() {
return condition;

View file

@ -448,6 +448,12 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
return this;
}
@Override
public ContinuousEffect withTargetDescription(String target) {
super.withTargetDescription(target);
return this;
}
/**
* Auto-generates dependencies on different effects (what's apply first and
* what's apply second)

View file

@ -59,6 +59,11 @@ public interface Effect extends Serializable, Copyable<Effect> {
TargetPointer getTargetPointer();
/**
* Sets the target pointer's description to the given string.
*/
Effect withTargetDescription(String target);
void setValue(String key, Object value);
Object getValue(String key);

View file

@ -93,7 +93,7 @@ public abstract class EffectImpl implements Effect {
// first target pointer is default
throw new IllegalArgumentException("Wrong code usage: target pointer can't be set to null: " + this);
}
targetPointer.setTargetDescription(this.targetPointer.getTargetDescription()); // copies the null if not set
this.targetPointer = targetPointer;
initNewTargetPointer();
return this;
@ -104,6 +104,12 @@ public abstract class EffectImpl implements Effect {
return this.targetPointer;
}
@Override
public Effect withTargetDescription(String target) {
this.targetPointer.setTargetDescription(target);
return this;
}
@Override
public void newId() {
if (!(this instanceof MageSingleton)) {

View file

@ -42,6 +42,12 @@ public abstract class OneShotEffect extends EffectImpl {
return this;
}
@Override
public OneShotEffect withTargetDescription(String target) {
super.withTargetDescription(target);
return this;
}
@Override
abstract public OneShotEffect copy();
}

View file

@ -72,6 +72,12 @@ public class OneShotNonTargetEffect extends OneShotEffect {
return super.setTargetPointer(targetPointer);
}
@Override
public OneShotEffect withTargetDescription(String target) {
effect.withTargetDescription(target);
return super.withTargetDescription(target);
}
@Override
public void setValue(String key, Object value) {
effect.setValue(key, value);

View file

@ -96,4 +96,11 @@ public class CreateDelayedTriggeredAbilityEffect extends OneShotEffect {
this.copyToPointer = copyToPointer;
return this;
}
@Override
public CreateDelayedTriggeredAbilityEffect withTargetDescription(String target) {
ability.getEffects().forEach(effect -> effect.withTargetDescription(target));
super.withTargetDescription(target);
return this;
}
}

View file

@ -160,4 +160,13 @@ public class RollDieWithResultTableEffect extends OneShotEffect {
super.setTargetPointer(targetPointer);
return this;
}
@Override
public RollDieWithResultTableEffect withTargetDescription(String target) {
resultsTable.forEach(tableEntry -> tableEntry.effects.forEach(
effect -> effect.withTargetDescription(target)));
super.withTargetDescription(target);
return this;
}
}

View file

@ -20,8 +20,11 @@ import mage.watchers.common.CommanderPlaysCountWatcher;
*/
public class CommanderStormAbility extends TriggeredAbilityImpl {
public CommanderStormAbility() {
super(Zone.STACK, new CommanderStormEffect());
public CommanderStormAbility(boolean newTargetsText) {
super(Zone.STACK, new CommanderStormEffect().setText("copy it for each time you've "
+ "cast your commander from the command zone this game."
+ (newTargetsText ? " You may choose new targets for the copies." : "")));
this.setTriggerPhrase("When you cast this spell, ");
this.setRuleAtTheTop(true);
}
@ -54,13 +57,6 @@ public class CommanderStormAbility extends TriggeredAbilityImpl {
}
return true;
}
@Override
public String getRule() {
return "When you cast this spell, copy it for each time you've "
+ "cast your commander from the command zone this game. "
+ "You may choose new targets for the copies.";
}
}
class CommanderStormEffect extends OneShotEffect {

View file

@ -18,7 +18,7 @@ public enum ModeChoice {
SULTAI("Sultai"),
MIRRAN("Mirran"),
PHYREXIAN("Phyrexian "),
PHYREXIAN("Phyrexian"),
ODD("odd"),
EVEN("even"),

View file

@ -120,6 +120,7 @@ public class EachTargetPointer extends TargetPointerImpl {
@Override
public String describeTargets(Targets targets, String defaultDescription) {
if (targetDescription != null) return targetDescription;
if (targets.isEmpty()) {
return defaultDescription;
}

View file

@ -148,6 +148,7 @@ public abstract class NthTargetPointer extends TargetPointerImpl {
@Override
public String describeTargets(Targets targets, String defaultDescription) {
if (targetDescription != null) return targetDescription;
if (targets.size() <= this.targetIndex) {
// TODO: need research, is it used for non setup targets ?!
// Typical usage example: trigger sets fixed target pointer

View file

@ -57,9 +57,13 @@ public interface TargetPointer extends Serializable, Copyable<TargetPointer> {
/**
* Describes the appropriate subset of targets for ability text.
*/
default String describeTargets(Targets targets, String defaultDescription) {
return defaultDescription;
}
String describeTargets(Targets targets, String defaultDescription);
/**
* Overwrite the default target description
*/
void setTargetDescription(String description);
String getTargetDescription();
default boolean isPlural(Targets targets) {
return false;

View file

@ -5,6 +5,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.Targets;
import java.util.HashMap;
import java.util.Map;
@ -18,6 +19,7 @@ public abstract class TargetPointerImpl implements TargetPointer {
private Map<String, String> data;
private boolean initialized = false;
protected String targetDescription = null;
protected TargetPointerImpl() {
super();
@ -30,6 +32,7 @@ public abstract class TargetPointerImpl implements TargetPointer {
this.data.putAll(targetPointer.data);
}
this.initialized = targetPointer.initialized;
this.targetDescription = targetPointer.targetDescription;
}
@Override
@ -74,4 +77,18 @@ public abstract class TargetPointerImpl implements TargetPointer {
return this;
}
@Override
public String describeTargets(Targets targets, String defaultDescription) {
return targetDescription != null ? targetDescription : defaultDescription;
}
@Override
public void setTargetDescription(String description) {
targetDescription = description;
}
@Override
public String getTargetDescription() {
return targetDescription;
}
}