From e820d9f4f082335de131ea64089def1d954db86f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 7 Mar 2022 20:48:35 -0500 Subject: [PATCH] reworked champion ability --- Mage.Sets/src/mage/cards/b/BoggartMob.java | 2 +- .../src/mage/cards/c/ChangelingBerserker.java | 2 +- .../src/mage/cards/c/ChangelingHero.java | 2 +- .../src/mage/cards/c/ChangelingTitan.java | 2 +- .../src/mage/cards/l/LightningCrafter.java | 12 +- .../src/mage/cards/m/MistbindClique.java | 2 +- Mage.Sets/src/mage/cards/n/NovaChaser.java | 2 +- .../src/mage/cards/s/SupremeExemplar.java | 2 +- .../src/mage/cards/t/ThoughtweftTrio.java | 2 +- .../src/mage/cards/u/UnstoppableAsh.java | 14 +- .../src/mage/cards/w/WanderwineProphets.java | 2 +- .../src/mage/cards/w/WrensRunPackmaster.java | 2 +- .../abilities/keyword/ChampionAbility.java | 134 ++++++++---------- 13 files changed, 79 insertions(+), 101 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BoggartMob.java b/Mage.Sets/src/mage/cards/b/BoggartMob.java index 711f4c89f75..d7425701433 100644 --- a/Mage.Sets/src/mage/cards/b/BoggartMob.java +++ b/Mage.Sets/src/mage/cards/b/BoggartMob.java @@ -33,7 +33,7 @@ public final class BoggartMob extends CardImpl { this.toughness = new MageInt(5); // Champion a Goblin - this.addAbility(new ChampionAbility(this, SubType.GOBLIN, false)); + this.addAbility(new ChampionAbility(this, SubType.GOBLIN)); // Whenever a Goblin you control deals combat damage to a player, you may create a 1/1 black Goblin Rogue creature token. this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/c/ChangelingBerserker.java b/Mage.Sets/src/mage/cards/c/ChangelingBerserker.java index 80845e7b462..9559c1ce355 100644 --- a/Mage.Sets/src/mage/cards/c/ChangelingBerserker.java +++ b/Mage.Sets/src/mage/cards/c/ChangelingBerserker.java @@ -30,7 +30,7 @@ public final class ChangelingBerserker extends CardImpl { this.addAbility(HasteAbility.getInstance()); // Champion a creature - this.addAbility(new ChampionAbility(this, true)); + this.addAbility(new ChampionAbility(this)); } private ChangelingBerserker(final ChangelingBerserker card) { diff --git a/Mage.Sets/src/mage/cards/c/ChangelingHero.java b/Mage.Sets/src/mage/cards/c/ChangelingHero.java index a8f1c038fee..51d00ce67af 100644 --- a/Mage.Sets/src/mage/cards/c/ChangelingHero.java +++ b/Mage.Sets/src/mage/cards/c/ChangelingHero.java @@ -27,7 +27,7 @@ public final class ChangelingHero extends CardImpl { this.addAbility(new ChangelingAbility()); // Champion a creature - this.addAbility(new ChampionAbility(this, true)); + this.addAbility(new ChampionAbility(this)); // Lifelink this.addAbility(LifelinkAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/c/ChangelingTitan.java b/Mage.Sets/src/mage/cards/c/ChangelingTitan.java index 85905b743aa..40e80e26d90 100644 --- a/Mage.Sets/src/mage/cards/c/ChangelingTitan.java +++ b/Mage.Sets/src/mage/cards/c/ChangelingTitan.java @@ -26,7 +26,7 @@ public final class ChangelingTitan extends CardImpl { this.addAbility(new ChangelingAbility()); // Champion a creature - this.addAbility(new ChampionAbility(this, true)); + this.addAbility(new ChampionAbility(this)); } private ChangelingTitan(final ChangelingTitan card) { diff --git a/Mage.Sets/src/mage/cards/l/LightningCrafter.java b/Mage.Sets/src/mage/cards/l/LightningCrafter.java index a3e22d3711b..a83e8999256 100644 --- a/Mage.Sets/src/mage/cards/l/LightningCrafter.java +++ b/Mage.Sets/src/mage/cards/l/LightningCrafter.java @@ -1,8 +1,5 @@ - package mage.cards.l; -import java.util.EnumSet; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -16,22 +13,23 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.target.common.TargetAnyTarget; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class LightningCrafter extends CardImpl { public LightningCrafter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.GOBLIN); this.subtype.add(SubType.SHAMAN); this.power = new MageInt(3); this.toughness = new MageInt(3); // Champion a Goblin or Shaman - this.addAbility(new ChampionAbility(this, EnumSet.of(SubType.GOBLIN, SubType.SHAMAN), false)); - + this.addAbility(new ChampionAbility(this, SubType.GOBLIN, SubType.SHAMAN)); + // {T}: Lightning Crafter deals 3 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new TapSourceCost()); ability.addTarget(new TargetAnyTarget()); diff --git a/Mage.Sets/src/mage/cards/m/MistbindClique.java b/Mage.Sets/src/mage/cards/m/MistbindClique.java index fa35005954a..0ee7c840823 100644 --- a/Mage.Sets/src/mage/cards/m/MistbindClique.java +++ b/Mage.Sets/src/mage/cards/m/MistbindClique.java @@ -38,7 +38,7 @@ public final class MistbindClique extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // Champion a Faerie - this.addAbility(new ChampionAbility(this, SubType.FAERIE, false)); + this.addAbility(new ChampionAbility(this, SubType.FAERIE)); // When a Faerie is championed with Mistbind Clique, tap all lands target player controls. this.addAbility(new MistbindCliqueAbility()); diff --git a/Mage.Sets/src/mage/cards/n/NovaChaser.java b/Mage.Sets/src/mage/cards/n/NovaChaser.java index 40cafdb4bbe..bab7d5850e8 100644 --- a/Mage.Sets/src/mage/cards/n/NovaChaser.java +++ b/Mage.Sets/src/mage/cards/n/NovaChaser.java @@ -27,7 +27,7 @@ public final class NovaChaser extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Champion an Elemental - this.addAbility(new ChampionAbility(this, SubType.ELEMENTAL, false)); + this.addAbility(new ChampionAbility(this, SubType.ELEMENTAL)); } private NovaChaser(final NovaChaser card) { diff --git a/Mage.Sets/src/mage/cards/s/SupremeExemplar.java b/Mage.Sets/src/mage/cards/s/SupremeExemplar.java index e4d6e38058c..698bfdd351c 100644 --- a/Mage.Sets/src/mage/cards/s/SupremeExemplar.java +++ b/Mage.Sets/src/mage/cards/s/SupremeExemplar.java @@ -33,7 +33,7 @@ public final class SupremeExemplar extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Champion an Elemental - this.addAbility(new ChampionAbility(this, SubType.ELEMENTAL, false)); + this.addAbility(new ChampionAbility(this, SubType.ELEMENTAL)); } private SupremeExemplar(final SupremeExemplar card) { diff --git a/Mage.Sets/src/mage/cards/t/ThoughtweftTrio.java b/Mage.Sets/src/mage/cards/t/ThoughtweftTrio.java index 610a79d651c..4ba212246e3 100644 --- a/Mage.Sets/src/mage/cards/t/ThoughtweftTrio.java +++ b/Mage.Sets/src/mage/cards/t/ThoughtweftTrio.java @@ -34,7 +34,7 @@ public final class ThoughtweftTrio extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // Champion a Kithkin - this.addAbility(new ChampionAbility(this, SubType.KITHKIN, false)); + this.addAbility(new ChampionAbility(this, SubType.KITHKIN)); // Thoughtweft Trio can block any number of creatures. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAdditionalCreatureEffect(0))); diff --git a/Mage.Sets/src/mage/cards/u/UnstoppableAsh.java b/Mage.Sets/src/mage/cards/u/UnstoppableAsh.java index 91e013ad7fe..9ee9c39e64d 100644 --- a/Mage.Sets/src/mage/cards/u/UnstoppableAsh.java +++ b/Mage.Sets/src/mage/cards/u/UnstoppableAsh.java @@ -1,8 +1,5 @@ - package mage.cards.u; -import java.util.EnumSet; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.BecomesBlockedAllTriggeredAbility; import mage.abilities.effects.Effect; @@ -17,10 +14,10 @@ import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; +import java.util.UUID; + /** - * * @author jeffwadsworth - * */ public final class UnstoppableAsh extends CardImpl { @@ -31,7 +28,7 @@ public final class UnstoppableAsh extends CardImpl { } public UnstoppableAsh(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.TREEFOLK); this.subtype.add(SubType.WARRIOR); @@ -42,13 +39,12 @@ public final class UnstoppableAsh extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Champion a Treefolk or Warrior - this.addAbility(new ChampionAbility(this, EnumSet.of(SubType.TREEFOLK, SubType.WARRIOR), false)); - + this.addAbility(new ChampionAbility(this, SubType.TREEFOLK, SubType.WARRIOR)); + // Whenever a creature you control becomes blocked, it gets +0/+5 until end of turn. Effect effect = new BoostTargetEffect(0, 5, Duration.EndOfTurn); effect.setText("it gets +0/+5 until end of turn"); this.addAbility(new BecomesBlockedAllTriggeredAbility(effect, false, filter, true)); - } private UnstoppableAsh(final UnstoppableAsh card) { diff --git a/Mage.Sets/src/mage/cards/w/WanderwineProphets.java b/Mage.Sets/src/mage/cards/w/WanderwineProphets.java index 7ef1432adf4..ed1ab990f6e 100644 --- a/Mage.Sets/src/mage/cards/w/WanderwineProphets.java +++ b/Mage.Sets/src/mage/cards/w/WanderwineProphets.java @@ -35,7 +35,7 @@ public final class WanderwineProphets extends CardImpl { this.toughness = new MageInt(4); // Champion a Merfolk - this.addAbility(new ChampionAbility(this, SubType.MERFOLK, false)); + this.addAbility(new ChampionAbility(this, SubType.MERFOLK)); // Whenever Wanderwine Prophets deals combat damage to a player, you may sacrifice a Merfolk. If you do, take an extra turn after this one. Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DoIfCostPaid( new AddExtraTurnControllerEffect(), diff --git a/Mage.Sets/src/mage/cards/w/WrensRunPackmaster.java b/Mage.Sets/src/mage/cards/w/WrensRunPackmaster.java index e9b17d621af..7993a58885e 100644 --- a/Mage.Sets/src/mage/cards/w/WrensRunPackmaster.java +++ b/Mage.Sets/src/mage/cards/w/WrensRunPackmaster.java @@ -34,7 +34,7 @@ public final class WrensRunPackmaster extends CardImpl { this.toughness = new MageInt(5); // Champion an Elf - this.addAbility(new ChampionAbility(this, SubType.ELF, false)); + this.addAbility(new ChampionAbility(this, SubType.ELF)); // {2}{G}: Create a 2/2 green Wolf creature token. this.addAbility(new SimpleActivatedAbility( diff --git a/Mage/src/main/java/mage/abilities/keyword/ChampionAbility.java b/Mage/src/main/java/mage/abilities/keyword/ChampionAbility.java index c0e785dd9af..75dc41b3793 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ChampionAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ChampionAbility.java @@ -1,11 +1,5 @@ - package mage.abilities.keyword; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.StaticAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -15,12 +9,11 @@ import mage.abilities.costs.CostImpl; import mage.abilities.effects.common.ReturnFromExileForSourceEffect; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; import mage.cards.Card; -import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AnotherPredicate; import mage.game.Game; @@ -30,6 +23,10 @@ import mage.players.Player; import mage.target.common.TargetControlledPermanent; import mage.util.CardUtil; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + /* * @author LevelX2 * @@ -49,16 +46,7 @@ import mage.util.CardUtil; */ public class ChampionAbility extends StaticAbility { - protected EnumSet subtypes; - protected String objectDescription; - - public ChampionAbility(Card card, SubType subtype, boolean requiresCreature) { - this(card, EnumSet.of(subtype), requiresCreature); - } - - public ChampionAbility(Card card, boolean requiresCreature) { - this(card, EnumSet.noneOf(SubType.class), requiresCreature); - } + protected final String objectDescription; /** * Champion one or more creature types or if the subtype array is empty @@ -66,55 +54,56 @@ public class ChampionAbility extends StaticAbility { * * @param card * @param subtypes subtypes to champion with, if empty all creatures can be - * used - * @param requiresCreature for cards that specifically require championing - * another creature + * used */ - public ChampionAbility(Card card, EnumSet subtypes, boolean requiresCreature) { + public ChampionAbility(Card card, SubType... subtypes) { super(Zone.BATTLEFIELD, null); - this.subtypes = subtypes; - StringBuilder sb = new StringBuilder("another "); - List> subtypesPredicates = new ArrayList<>(); - if (!subtypes.isEmpty()) { - int i = 0; - for (SubType subtype : this.subtypes) { - subtypesPredicates.add(subtype.getPredicate()); - if (i == 0) { - sb.append(subtype); - } else { - sb.append(" or ").append(subtype); - } - i++; - } - } else { - sb.append("creature"); + List subTypes = Arrays.asList(subtypes); + FilterControlledPermanent filter; + switch (subTypes.size()) { + case 0: + this.objectDescription = "creature"; + filter = StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE; + break; + case 1: + SubType subType = subTypes.get(0); + this.objectDescription = subType.getDescription(); + filter = new FilterControlledPermanent(subType, "another " + subType + " you control"); + filter.add(AnotherPredicate.instance); + break; + case 2: + SubType subType1 = subTypes.get(0); + SubType subType2 = subTypes.get(1); + this.objectDescription = subType1.getDescription() + " or " + subType2.getDescription(); + filter = new FilterControlledPermanent(); + filter.add(Predicates.or( + subType1.getPredicate(), + subType2.getPredicate() + )); + filter.add(AnotherPredicate.instance); + break; + default: + throw new UnsupportedOperationException("can't have more than two subtypes currently"); } - this.objectDescription = sb.toString(); - FilterControlledPermanent filter = new FilterControlledPermanent(objectDescription); - if (!subtypesPredicates.isEmpty()) { - filter.add(Predicates.or(subtypesPredicates)); - } - if (requiresCreature) { - filter.add(CardType.CREATURE.getPredicate()); - } - filter.add(AnotherPredicate.instance); // When this permanent enters the battlefield, sacrifice it unless you exile another [object] you control. Ability ability1 = new EntersBattlefieldTriggeredAbility( - new SacrificeSourceUnlessPaysEffect(new ChampionExileCost(filter, card.getName() + " championed permanents")), false); + new SacrificeSourceUnlessPaysEffect(new ChampionExileCost(filter)), false + ); ability1.setRuleVisible(false); addSubAbility(ability1); // When this permanent leaves the battlefield, return the exiled card to the battlefield under its owner's control. - Ability ability2 = new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false); + Ability ability2 = new LeavesBattlefieldTriggeredAbility( + new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false + ); ability2.setRuleVisible(false); addSubAbility(ability2); } public ChampionAbility(final ChampionAbility ability) { super(ability); - this.subtypes = ability.subtypes; this.objectDescription = ability.objectDescription; } @@ -125,46 +114,41 @@ public class ChampionAbility extends StaticAbility { @Override public String getRule() { - StringBuilder sb = new StringBuilder("Champion ").append(objectDescription); - sb.append(" (When this enters the battlefield, sacrifice it unless you exile another "); - sb.append(objectDescription); - sb.append(" you control. When this leaves the battlefield, that card returns to the battlefield.)"); - return sb.toString(); + return "Champion " + CardUtil.addArticle(objectDescription) + + " (When this enters the battlefield, sacrifice it unless you exile another " + objectDescription + + " you control. When this leaves the battlefield, that card returns to the battlefield.)"; } } class ChampionExileCost extends CostImpl { - private String exileZone; - - public ChampionExileCost(FilterControlledPermanent filter, String exileZone) { + ChampionExileCost(FilterControlledPermanent filter) { this.addTarget(new TargetControlledPermanent(1, 1, filter, true)); this.text = "exile " + filter.getMessage() + " you control"; - this.exileZone = exileZone; } - public ChampionExileCost(ChampionExileCost cost) { + private ChampionExileCost(ChampionExileCost cost) { super(cost); - this.exileZone = cost.exileZone; } @Override public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { Player controller = game.getPlayer(controllerId); - MageObject sourceObject = ability.getSourceObject(game); - if (controller != null && sourceObject != null) { - if (targets.choose(Outcome.Exile, controllerId, source.getSourceId(), game)) { - UUID exileId = CardUtil.getExileZoneId(game, ability.getSourceId(), ability.getSourceObjectZoneChangeCounter()); // exileId important for return effect - for (UUID targetId : targets.get(0).getTargets()) { - Permanent permanent = game.getPermanent(targetId); - if (permanent == null) { - return false; - } - paid |= controller.moveCardToExileWithInfo(permanent, exileId, sourceObject.getIdName() + " championed permanents", source, game, Zone.BATTLEFIELD, true); - if (paid) { - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_CHAMPIONED, permanent.getId(), source, controllerId)); - } - } + if (controller == null || !targets.choose(Outcome.Exile, controllerId, source.getSourceId(), game)) { + return paid; + } + for (UUID targetId : targets.get(0).getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent == null) { + return false; + } + paid |= controller.moveCardsToExile( + permanent, source, game, true, + CardUtil.getExileZoneId(game, source), + CardUtil.getSourceName(game, source) + ); + if (paid) { + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_CHAMPIONED, permanent.getId(), source, controllerId)); } } return paid;