diff --git a/Mage.Sets/src/mage/cards/t/TheTricksterGodsHeist.java b/Mage.Sets/src/mage/cards/t/TheTricksterGodsHeist.java new file mode 100644 index 00000000000..a0c8ccd13da --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheTricksterGodsHeist.java @@ -0,0 +1,135 @@ +package mage.cards.t; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SagaAbility; +import mage.abilities.effects.Effects; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.common.continuous.ExchangeControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TheTricksterGodsHeist extends CardImpl { + + public TheTricksterGodsHeist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{B}"); + + this.subtype.add(SubType.SAGA); + + // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.) + SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III); + + // I — You may exchange control of two target creatures. + sagaAbility.addChapterEffect( + this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, + new ExchangeControlTargetEffect( + Duration.EndOfGame, "exchange control of two target creatures" + ), new TargetCreaturePermanent(2), true + ); + + // II — You may exchange control of two target nonbasic, noncreature permanents that share a card type. + sagaAbility.addChapterEffect( + this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, + new ExchangeControlTargetEffect( + Duration.EndOfGame, "exchange control of two target nonbasic, " + + "noncreature permanents that share a card type" + ), new TargetCreaturePermanent(2), true + ); + + // III — Target player loses 3 life and you gain 3 life. + sagaAbility.addChapterEffect( + this, SagaChapter.CHAPTER_III, SagaChapter.CHAPTER_III, + new Effects( + new LoseLifeTargetEffect(3), + new GainLifeEffect(3).concatBy("and") + ), new TargetPlayer() + ); + + this.addAbility(sagaAbility); + } + + private TheTricksterGodsHeist(final TheTricksterGodsHeist card) { + super(card); + } + + @Override + public TheTricksterGodsHeist copy() { + return new TheTricksterGodsHeist(this); + } +} + +class TheTricksterGodsHeistTarget extends TargetPermanent { + private static final FilterPermanent filter + = new FilterPermanent("nonbasic, noncreature permanents that share a card type"); + + static { + filter.add(Predicates.not(SuperType.BASIC.getPredicate())); + filter.add(Predicates.not(CardType.CREATURE.getPredicate())); + } + + TheTricksterGodsHeistTarget() { + super(2, 2, filter, false); + } + + private TheTricksterGodsHeistTarget(final TheTricksterGodsHeistTarget target) { + super(target); + } + + @Override + public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { + if (!super.canTarget(controllerId, id, source, game)) { + return false; + } + if (getTargets().isEmpty()) { + return true; + } + Permanent targetOne = game.getPermanent(getTargets().get(0)); + Permanent targetTwo = game.getPermanent(id); + if (targetOne == null || targetTwo == null) { + return false; + } + return targetOne.shareTypes(targetTwo); + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + Set cardTypes = new HashSet<>(); + MageObject targetSource = game.getObject(sourceId); + if (targetSource == null) { + return false; + } + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) { + if (!permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) { + continue; + } + for (CardType cardType : permanent.getCardType()) { + if (cardTypes.contains(cardType)) { + return true; + } + } + cardTypes.addAll(permanent.getCardType()); + } + return false; + } + + @Override + public TheTricksterGodsHeistTarget copy() { + return new TheTricksterGodsHeistTarget(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Kaldheim.java b/Mage.Sets/src/mage/sets/Kaldheim.java index 776add85ca9..1c13e4efbf6 100644 --- a/Mage.Sets/src/mage/sets/Kaldheim.java +++ b/Mage.Sets/src/mage/sets/Kaldheim.java @@ -107,6 +107,7 @@ public final class Kaldheim extends ExpansionSet { cards.add(new SetCardInfo("Sulfurous Mine", 270, Rarity.COMMON, mage.cards.s.SulfurousMine.class)); cards.add(new SetCardInfo("Surtland Elementalist", 375, Rarity.RARE, mage.cards.s.SurtlandElementalist.class)); cards.add(new SetCardInfo("Surtland Flinger", 377, Rarity.RARE, mage.cards.s.SurtlandFlinger.class)); + cards.add(new SetCardInfo("The Trickster-God's Heist", 232, Rarity.UNCOMMON, mage.cards.t.TheTricksterGodsHeist.class)); cards.add(new SetCardInfo("The World Tree", 275, Rarity.RARE, mage.cards.t.TheWorldTree.class)); cards.add(new SetCardInfo("Thornmantle Striker", 387, Rarity.UNCOMMON, mage.cards.t.ThornmantleStriker.class)); cards.add(new SetCardInfo("Toski, Bearer of Secrets", 197, Rarity.RARE, mage.cards.t.ToskiBearerOfSecrets.class)); diff --git a/Mage/src/main/java/mage/abilities/common/SagaAbility.java b/Mage/src/main/java/mage/abilities/common/SagaAbility.java index ae61682b79a..34d1cac6562 100644 --- a/Mage/src/main/java/mage/abilities/common/SagaAbility.java +++ b/Mage/src/main/java/mage/abilities/common/SagaAbility.java @@ -52,7 +52,11 @@ public class SagaAbility extends SimpleStaticAbility { } public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect, Target target) { - addChapterEffect(card, fromChapter, toChapter, new Effects(effect), new Targets(target)); + addChapterEffect(card, fromChapter, toChapter, effect, target, false); + } + + public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect, Target target, boolean optional) { + addChapterEffect(card, fromChapter, toChapter, new Effects(effect), new Targets(target), optional); } public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Target target) { @@ -60,9 +64,13 @@ public class SagaAbility extends SimpleStaticAbility { } public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Targets targets) { + addChapterEffect(card, fromChapter, toChapter, effects, targets, false); + } + + public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Targets targets, boolean optional) { ChapterTriggeredAbility ability; for (int i = fromChapter.getNumber(); i <= toChapter.getNumber(); i++) { - ability = new ChapterTriggeredAbility(null, SagaChapter.getChapter(i), toChapter); + ability = new ChapterTriggeredAbility(null, SagaChapter.getChapter(i), toChapter, optional); for (Effect effect : effects) { if (effect != null) { ability.addEffect(effect.copy()); @@ -113,8 +121,8 @@ class ChapterTriggeredAbility extends TriggeredAbilityImpl { private SagaChapter chapterFrom, chapterTo; - public ChapterTriggeredAbility(Effect effect, SagaChapter chapterFrom, SagaChapter chapterTo) { - super(Zone.ALL, effect, false); + public ChapterTriggeredAbility(Effect effect, SagaChapter chapterFrom, SagaChapter chapterTo, boolean optional) { + super(Zone.ALL, effect, optional); this.chapterFrom = chapterFrom; this.chapterTo = chapterTo; }