more text fixes (DRC is now 100%)

This commit is contained in:
theelk801 2025-06-01 21:19:16 -04:00
parent 5e83c3c3f0
commit 699b8d59dc
21 changed files with 130 additions and 99 deletions

View file

@ -1,8 +1,5 @@
package mage.cards.a;
import java.util.Optional;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
@ -10,14 +7,20 @@ import mage.abilities.costs.common.PayEnergyCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.CastFromHandWithoutPayingManaCostEffect;
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.Optional;
import java.util.UUID;
/**
* @author sobiech
@ -28,14 +31,12 @@ public final class AetherfluxConduit extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
// Whenever you cast a spell, you get an amount of {E} equal to the amount of mana spent to cast that spell.
this.addAbility(new SpellCastControllerTriggeredAbility(
new AetherfluxConduitEffect(),false
));
this.addAbility(new SpellCastControllerTriggeredAbility(new AetherfluxConduitManaEffect(), false));
// {T}, Pay fifty {E}: Draw seven cards. You may cast any number of spells from your hand without paying their mana costs.
final Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(7), new TapSourceCost());
ability.addCost(new PayEnergyCost(50).setText("Pay fifty {E}"));
ability.addEffect(new CastFromHandWithoutPayingManaCostEffect());
ability.addEffect(new AetherfluxConduitCastEffect());
this.addAbility(ability);
}
@ -48,19 +49,21 @@ public final class AetherfluxConduit extends CardImpl {
return new AetherfluxConduit(this);
}
}
class AetherfluxConduitEffect extends OneShotEffect {
AetherfluxConduitEffect() {
class AetherfluxConduitManaEffect extends OneShotEffect {
AetherfluxConduitManaEffect() {
super(Outcome.Benefit);
this.staticText = "you get an amount of {E} <i>(energy counters)</i> equal to the amount of mana spent to cast that spell";
}
private AetherfluxConduitEffect(AetherfluxConduitEffect effect) {
private AetherfluxConduitManaEffect(AetherfluxConduitManaEffect effect) {
super(effect);
}
@Override
public AetherfluxConduitEffect copy() {
return new AetherfluxConduitEffect(this);
public AetherfluxConduitManaEffect copy() {
return new AetherfluxConduitManaEffect(this);
}
@Override
@ -72,3 +75,31 @@ class AetherfluxConduitEffect extends OneShotEffect {
}
}
class AetherfluxConduitCastEffect extends OneShotEffect {
AetherfluxConduitCastEffect() {
super(Outcome.Benefit);
staticText = "You may cast any number of spells from your hand without paying their mana costs";
}
private AetherfluxConduitCastEffect(final AetherfluxConduitCastEffect effect) {
super(effect);
}
@Override
public AetherfluxConduitCastEffect copy() {
return new AetherfluxConduitCastEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
CardUtil.castMultipleWithAttributeForFree(
player, source, game, new CardsImpl(player.getHand()), StaticFilters.FILTER_CARD
);
return true;
}
}

View file

@ -42,7 +42,9 @@ public final class CollisionCourse extends CardImpl {
// Choose one --
// * Collision Course deals X damage to target creature, where X is the number of permanents you control that are creatures and/or Vehicles.
this.getSpellAbility().addEffect(new DamageTargetEffect(xValue));
this.getSpellAbility().addEffect(new DamageTargetEffect(xValue)
.setText("{this} deals X damage to target creature, where X is " +
"the number of permanents you control that are creatures and/or Vehicles"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addHint(hint);

View file

@ -1,43 +1,29 @@
package mage.cards.e;
import java.util.UUID;
import java.util.function.Predicate;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.common.DamageAllEffect;
import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author Jmlundeen
*/
public final class ExplosiveGetaway extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("artifact or creature");
static {
filter.add(Predicates.or(
CardType.ARTIFACT.getPredicate(),
CardType.CREATURE.getPredicate()
));
}
public ExplosiveGetaway(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{W}");
// Exile up to one target artifact or creature. Return it to the battlefield under its owner's control at the beginning of the next end step.
this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect().withTextThatCard(false));
this.getSpellAbility().addTarget(new TargetPermanent(0, 1, filter));
this.getSpellAbility().addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE));
// Explosive Getaway deals 4 damage to each creature.
this.getSpellAbility().addEffect(new DamageAllEffect(4, StaticFilters.FILTER_PERMANENT_ALL_CREATURES).concatBy("<br>"));
this.getSpellAbility().addEffect(new DamageAllEffect(4, StaticFilters.FILTER_PERMANENT_CREATURE).concatBy("<br>"));
}
private ExplosiveGetaway(final ExplosiveGetaway card) {

View file

@ -53,7 +53,7 @@ class ArtifactOrActivatedManaBuilder extends ConditionalManaBuilder {
@Override
public String getRule() {
return "Spend this mana only to cast an artifact spells or activate an ability";
return "Spend this mana only to cast an artifact spell or activate an ability";
}
}
@ -61,7 +61,7 @@ class ArtifactOrActivatedConditionalMana extends ConditionalMana {
public ArtifactOrActivatedConditionalMana(Mana mana) {
super(mana);
staticText = "Spend this mana only to cast an artifact spells or activate an ability";
staticText = "Spend this mana only to cast an artifact spell or activate an ability";
addCondition(new ArtifactOrActivatedManaCondition());
}
}

View file

@ -83,7 +83,7 @@ class HashatonScarabsFistEffect extends OneShotEffect {
HashatonScarabsFistEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "create a tapped token that`s a copy of that card, except it`s a 4/4 black Zombie";
this.staticText = "create a tapped token that's a copy of that card, except it's a 4/4 black Zombie";
}
private HashatonScarabsFistEffect(OneShotEffect effect) {

View file

@ -9,7 +9,7 @@ import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.combat.AttacksIfAbleTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.HasteAbility;
@ -22,7 +22,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.permanent.token.GoblinToken;
@ -36,7 +36,8 @@ import java.util.UUID;
*/
public final class HowlsquadHeavy extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.GOBLIN));
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.GOBLIN);
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
private static final Hint hint = new ValueHint("Goblins you control", xValue);
public HowlsquadHeavy(UUID ownerId, CardSetInfo setInfo) {
@ -51,10 +52,9 @@ public final class HowlsquadHeavy extends CardImpl {
this.addAbility(new StartYourEnginesAbility());
// Other Goblins you control have haste.
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
HasteAbility.getInstance(), Duration.WhileOnBattlefield,
StaticFilters.FILTER_PERMANENT_CREATURE_GOBLINS, true
)));
this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect(
HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true
).setText("other Goblins you control have haste")));
// At the beginning of combat on your turn, create a 1/1 red Goblin creature token. That token attacks this combat if able.
this.addAbility(new BeginningOfCombatTriggeredAbility(new HowlsquadHeavyEffect()));

View file

@ -68,7 +68,7 @@ class LifecraftEngineAddSubTypeAllEffect extends ContinuousEffectImpl {
public LifecraftEngineAddSubTypeAllEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
staticText = "Vehicle creatures you control are the chosen type in addition to their other types.";
staticText = "Vehicle creatures you control are the chosen creature type in addition to their other types.";
}
private LifecraftEngineAddSubTypeAllEffect(final LifecraftEngineAddSubTypeAllEffect effect) {

View file

@ -34,11 +34,11 @@ public final class MarchOfTheWorldOoze extends CardImpl {
// Creatures you control have base power and toughness 6/6 and are Oozes in addition to their other types.
Ability ability = new SimpleStaticAbility(new SetBasePowerToughnessAllEffect(
6, 6, Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURE
6, 6, Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES
));
ability.addEffect(new AddCardSubtypeAllEffect(
StaticFilters.FILTER_CONTROLLED_CREATURE, SubType.OOZE, null
).concatBy("and"));
StaticFilters.FILTER_CONTROLLED_CREATURES, SubType.OOZE, null
).setText("and are Oozes in addition to their other types"));
this.addAbility(ability);
// Whenever an opponent casts a spell, if it's not their turn, you create a 3/3 green Elephant creature token.

View file

@ -41,7 +41,7 @@ public final class MarketbackWalker extends CardImpl {
));
// When this creature dies, draw a card for each +1/+1 counter on it.
this.addAbility(new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(xValue)));
this.addAbility(new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(xValue).setText("draw a card for each +1/+1 counter on it")));
}
private MarketbackWalker(final MarketbackWalker card) {

View file

@ -42,7 +42,7 @@ public final class MarshalsPathcruiser extends CardImpl {
new AddCardTypeSourceEffect(Duration.Custom, CardType.ARTIFACT, CardType.CREATURE),
new ManaCostsImpl<>("{W}{U}{B}{R}{G}")
);
ability.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)));
ability.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)).setText("Put two +1/+1 counters on it"));
this.addAbility(ability);
// Crew 5

View file

@ -43,7 +43,7 @@ class PanharmoniconEffect extends ReplacementEffectImpl {
PanharmoniconEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "If an artifact or creature entering the battlefield causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time";
staticText = "If an artifact or creature entering causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time";
}
private PanharmoniconEffect(final PanharmoniconEffect effect) {

View file

@ -1,6 +1,5 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.OneOrMoreCombatDamagePlayerTriggeredAbility;
@ -9,9 +8,9 @@ import mage.abilities.costs.common.PayEnergyCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
@ -19,8 +18,9 @@ import mage.game.permanent.token.NalaarAetherjetToken;
import mage.game.permanent.token.Token;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author Jmlundeen
*/
public final class PiaNalaarChiefMechanic extends CardImpl {
@ -64,7 +64,7 @@ class PiaNalaarChiefMechanicEffect extends OneShotEffect {
public PiaNalaarChiefMechanicEffect() {
super(Outcome.Benefit);
staticText = "you may pay one or more {E}. If you do, create an X/X colorless Vehicle artifact token " +
"named Nalaar Aetherjet with flying and crew 2, where X is the amount of {E} spent this way";
"named Nalaar Aetherjet with flying and crew 2, where X is the amount of {E} paid this way";
}
public PiaNalaarChiefMechanicEffect(final PiaNalaarChiefMechanicEffect effect) {

View file

@ -9,6 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
@ -30,8 +31,13 @@ public class PriestOfTheCrossing extends CardImpl {
// At the beginning of each end step, put X +1/+1 counters on each creature you control, where X is the number of creatures that died under your control this turn.
this.addAbility(new BeginningOfEndStepTriggeredAbility(
new AddCountersAllEffect(CounterType.P1P1.createInstance(), CreaturesYouControlDiedCount.instance, StaticFilters.FILTER_CONTROLLED_CREATURE)
.setText("put X +1/+1 counters on each creature you control, where X is the number of creatures that died under your control this turn")));
TargetController.ANY,
new AddCountersAllEffect(
CounterType.P1P1.createInstance(), CreaturesYouControlDiedCount.instance,
StaticFilters.FILTER_CONTROLLED_CREATURE
).setText("put X +1/+1 counters on each creature you control, where X is " +
"the number of creatures that died under your control this turn"), false
));
}
public PriestOfTheCrossing(PriestOfTheCrossing card) {

View file

@ -1,6 +1,5 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
@ -11,12 +10,12 @@ import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
@ -24,13 +23,14 @@ import mage.game.Game;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author Jmlundeen
*/
public final class SaheeliRadiantCreator extends CardImpl {
private static final FilterSpell filter = new FilterSpell("Artificer or artifact spell");
private static final FilterSpell filter = new FilterSpell("an Artificer or artifact spell");
static {
filter.add(Predicates.or(

View file

@ -17,7 +17,10 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
@ -27,6 +30,13 @@ import java.util.UUID;
*/
public final class VoyagerGlidecar extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("other untapped creatures you control");
static {
filter.add(AnotherPredicate.instance);
filter.add(TappedPredicate.UNTAPPED);
}
public VoyagerGlidecar(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{W}");
@ -42,9 +52,7 @@ public final class VoyagerGlidecar extends CardImpl {
new AddCardTypeSourceEffect(
Duration.EndOfTurn, CardType.ARTIFACT, CardType.CREATURE
).setText("until end of turn, this Vehicle becomes an artifact creature"),
new TapTargetCost(new TargetControlledPermanent(
3, StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURES
))
new TapTargetCost(new TargetControlledPermanent(3, filter))
);
ability.addEffect(new GainAbilitySourceEffect(
FlyingAbility.getInstance(), Duration.EndOfTurn

View file

@ -24,6 +24,7 @@ import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.util.CardUtil;
/**
*
@ -54,7 +55,7 @@ public final class WinterCursedRider extends CardImpl {
WardAbility wardAbility = new WardAbility(new PayLifeCost(2));
this.addAbility(new SimpleStaticAbility(
new GainAbilityAllEffect(wardAbility, Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACTS)
.setText("Artifacts you control have " + "\"" + wardAbility.getRuleWithoutHint() + "\"")
.setText("Artifacts you control have " + "\"" + CardUtil.getTextWithFirstCharUpperCase(wardAbility.getRuleWithoutHint()) + "\"")
));
// Exhaust -- {2}{U}{B}, {T}, Exile X artifact cards from your graveyard: Each other nonartifact creature gets -X/-X until end of turn.
Ability ability = new ExhaustAbility(new BoostAllEffect(xValue, xValue, Duration.EndOfTurn, filter, true),

View file

@ -75,7 +75,7 @@ public class VerifyCardDataTest {
private static final Logger logger = Logger.getLogger(VerifyCardDataTest.class);
private static final String FULL_ABILITIES_CHECK_SET_CODES = "INR"; // check ability text due mtgjson, can use multiple sets like MAT;CMD or * for all
private static final String FULL_ABILITIES_CHECK_SET_CODES = "DRC"; // check ability text due mtgjson, can use multiple sets like MAT;CMD or * for all
private static final boolean CHECK_ONLY_ABILITIES_TEXT = false; // use when checking text locally, suppresses unnecessary checks and output messages
private static final boolean CHECK_COPYABLE_FIELDS = true; // disable for better verify test performance

View file

@ -30,8 +30,8 @@ public class PutIntoGraveFromBattlefieldAllTriggeredAbility extends TriggeredAbi
this.filter = filter;
this.onlyToControllerGraveyard = onlyToControllerGraveyard;
this.setTargetPointer = setTargetPointer;
setTriggerPhrase("Whenever " + filter.getMessage() + " is put into " + (onlyToControllerGraveyard ? "your" : "a")
+ " graveyard from the battlefield, ");
setTriggerPhrase("Whenever " + filter.getMessage() + " is put into " +
(onlyToControllerGraveyard ? "your" : "a") + " graveyard, ");
}
protected PutIntoGraveFromBattlefieldAllTriggeredAbility(final PutIntoGraveFromBattlefieldAllTriggeredAbility ability) {

View file

@ -9,6 +9,7 @@ import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.util.CardUtil;
/**
* @author LevelX2
@ -20,7 +21,7 @@ public class ExileCardYouChooseTargetOpponentEffect extends OneShotEffect {
public ExileCardYouChooseTargetOpponentEffect(FilterCard filter) {
super(Outcome.Discard);
this.staticText = "target opponent reveals their hand. You choose "
+ filter.getMessage() + (filter.getMessage().contains("from it") ? "" : " from it") + " and exile that card";
+ CardUtil.addArticle(filter.getMessage()) + (filter.getMessage().contains("from it") ? "" : " from it") + " and exile that card";
this.filter = filter;
}

View file

@ -7,10 +7,11 @@ import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
/**
* @author emerald000
@ -76,19 +77,20 @@ public class AddCardTypeSourceEffect extends ContinuousEffectImpl {
}
StringBuilder sb = new StringBuilder();
sb.append("{this} becomes ");
boolean article = false;
for (CardType cardType : addedCardTypes) {
if (!article) {
if (cardType.toString().startsWith("A") || cardType.toString().startsWith("E")) {
sb.append("an ");
} else {
sb.append("a ");
sb.append(CardUtil.addArticle(
addedCardTypes
.stream()
.map(CardType::toString)
.map(String::toLowerCase)
.collect(Collectors.joining(" "))
));
if (!addedCardTypes.contains(CardType.ARTIFACT) || !addedCardTypes.contains(CardType.CREATURE)) {
sb.append(" in addition to its other types");
}
article = true;
if (!this.getDuration().toString().isEmpty()) {
sb.append(' ');
sb.append(this.getDuration());
}
sb.append(cardType.toString().toLowerCase(Locale.ENGLISH)).append(" ");
}
sb.append("in addition to its other types ").append(this.getDuration().toString());
return sb.toString();
}
}

View file

@ -12,15 +12,14 @@ import mage.game.Game;
*/
public class ExhaustAbility extends ActivatedAbilityImpl {
private boolean withReminderText = true;
private final boolean withReminderText;
public ExhaustAbility(Effect effect, Cost cost) {
super(Zone.BATTLEFIELD, effect, cost);
this(effect, cost, true);
}
public ExhaustAbility(Effect effect, Cost cost, boolean withReminderText) {
super(Zone.BATTLEFIELD, effect, cost);
this.setRuleVisible(false);
this.withReminderText = withReminderText;
}
@ -30,11 +29,6 @@ public class ExhaustAbility extends ActivatedAbilityImpl {
this.withReminderText = ability.withReminderText;
}
public ExhaustAbility withReminderText(boolean withReminderText) {
this.withReminderText = withReminderText;
return this;
}
@Override
public ExhaustAbility copy() {
return new ExhaustAbility(this);