From 6fa21415fe5f3ca7f1250b9594278eb78a7a3b66 Mon Sep 17 00:00:00 2001 From: htrajan Date: Thu, 11 Jun 2020 15:36:52 -0700 Subject: [PATCH] Implement Basri cards (#6622) * Implement Basri Ket * Implement Basri's Lieutenant --- Mage.Sets/src/mage/cards/b/BasriKet.java | 119 ++++++++++++++++++ .../src/mage/cards/b/BasrisLieutenant.java | 77 ++++++++++++ Mage.Sets/src/mage/sets/CoreSet2021.java | 2 + .../game/command/emblems/BasriKetEmblem.java | 31 +++++ .../emblems/LilianaWakerOfTheDeadEmblem.java | 4 - 5 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/b/BasriKet.java create mode 100644 Mage.Sets/src/mage/cards/b/BasrisLieutenant.java create mode 100644 Mage/src/main/java/mage/game/command/emblems/BasriKetEmblem.java diff --git a/Mage.Sets/src/mage/cards/b/BasriKet.java b/Mage.Sets/src/mage/cards/b/BasriKet.java new file mode 100644 index 0000000000..ea8957545d --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BasriKet.java @@ -0,0 +1,119 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.command.emblems.BasriKetEmblem; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.SoldierToken; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class BasriKet extends CardImpl { + + public BasriKet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{1}{W}{W}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.BASRI); + this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3)); + + // +1: Put a +1/+1 counter on up to one target creature. It gains indestructible until end of turn. + Ability ability = new LoyaltyAbility(new AddCountersTargetEffect( + CounterType.P1P1.createInstance() + ).setText("Put a +1/+1 counter on up to one target creature"), 1); + ability.addEffect(new GainAbilityTargetEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn + ).setText("It gains indestructible until end of turn")); + ability.addTarget(new TargetCreaturePermanent(0, 1)); + this.addAbility(ability); + + // −2: Whenever one or more nontoken creatures attack this turn, create that many 1/1 white Soldier creature tokens that are tapped and attacking. + this.addAbility(new LoyaltyAbility(new CreateDelayedTriggeredAbilityEffect(new BasriKetTriggeredAbility()), -2)); + + // −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." + this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new BasriKetEmblem()), -6)); + } + + private BasriKet(final BasriKet card) { + super(card); + } + + @Override + public BasriKet copy() { + return new BasriKet(this); + } +} + +class BasriKetTriggeredAbility extends DelayedTriggeredAbility { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature"); + + static { + filter.add(Predicates.not(TokenPredicate.instance)); + } + + public BasriKetTriggeredAbility() { + super(null, Duration.EndOfTurn, false); + } + + public BasriKetTriggeredAbility(BasriKetTriggeredAbility ability) { + super(ability); + } + + @Override + public BasriKetTriggeredAbility copy() { + return new BasriKetTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + int attackingNonTokens = 0; + for (UUID attacker : game.getCombat().getAttackers()) { + Permanent permanent = game.getPermanent(attacker); + if (filter.match(permanent, game)) { + attackingNonTokens++; + } + } + if (attackingNonTokens > 0) { + this.getEffects().clear(); + addEffect(new CreateTokenEffect(new SoldierToken(), attackingNonTokens, true, true)); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever one or more nontoken creatures attack this turn, create that many 1/1 white Soldier creature tokens that are tapped and attacking."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BasrisLieutenant.java b/Mage.Sets/src/mage/cards/b/BasrisLieutenant.java new file mode 100644 index 0000000000..330eec1325 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BasrisLieutenant.java @@ -0,0 +1,77 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.DiesThisOrAnotherCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.abilities.keyword.VigilanceAbility; +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.FilterObject; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.MulticoloredPredicate; +import mage.filter.predicate.permanent.CounterPredicate; +import mage.game.permanent.token.KnightToken; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class BasrisLieutenant extends CardImpl { + + private static final FilterObject multicoloredFilter = new FilterObject<>("multicolored"); + private static final FilterCreaturePermanent controlledCreatureWithP1P1CounterFilter = new FilterCreaturePermanent("creature you control"); + + static { + multicoloredFilter.add(MulticoloredPredicate.instance); + controlledCreatureWithP1P1CounterFilter.add(TargetController.YOU.getControllerPredicate()); + controlledCreatureWithP1P1CounterFilter.add(new CounterPredicate(CounterType.P1P1)); + } + + public BasrisLieutenant(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Vigilance, protection from multicolored + this.addAbility(VigilanceAbility.getInstance()); + + // protection from multicolored + this.addAbility(new ProtectionAbility(multicoloredFilter)); + + // When Basri's Lieutenant enters the battlefield, put a +1/+1 counter on target creature you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + + // Whenever Basri's Lieutenant or another creature you control dies, if it had a +1/+1 counter on it, create a 2/2 white Knight creature token with vigilance. + this.addAbility(new DiesThisOrAnotherCreatureTriggeredAbility( + new CreateTokenEffect(new KnightToken()).setText("if it had a +1/+1 counter on it, create a 2/2 white Knight creature token with vigilance"), + false, + controlledCreatureWithP1P1CounterFilter + )); + } + + private BasrisLieutenant(final BasrisLieutenant card) { + super(card); + } + + @Override + public BasrisLieutenant copy() { + return new BasrisLieutenant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/CoreSet2021.java b/Mage.Sets/src/mage/sets/CoreSet2021.java index 951c9c1a31..dde0bf23f9 100644 --- a/Mage.Sets/src/mage/sets/CoreSet2021.java +++ b/Mage.Sets/src/mage/sets/CoreSet2021.java @@ -40,8 +40,10 @@ public final class CoreSet2021 extends ExpansionSet { cards.add(new SetCardInfo("Azusa, Lost but Seeking", 173, Rarity.RARE, mage.cards.a.AzusaLostButSeeking.class)); cards.add(new SetCardInfo("Bad Deal", 89, Rarity.UNCOMMON, mage.cards.b.BadDeal.class)); cards.add(new SetCardInfo("Baneslayer Angel", 6, Rarity.MYTHIC, mage.cards.b.BaneslayerAngel.class)); + cards.add(new SetCardInfo("Basri Ket", 7, Rarity.MYTHIC, mage.cards.b.BasriKet.class)); cards.add(new SetCardInfo("Basri's Acolyte", 8, Rarity.COMMON, mage.cards.b.BasrisAcolyte.class)); cards.add(new SetCardInfo("Basri's Aegis", 322, Rarity.RARE, mage.cards.b.BasrisAegis.class)); + cards.add(new SetCardInfo("Basri's Lieutenant", 9, Rarity.RARE, mage.cards.b.BasrisLieutenant.class)); cards.add(new SetCardInfo("Basri's Solidarity", 10, Rarity.UNCOMMON, mage.cards.b.BasrisSolidarity.class)); cards.add(new SetCardInfo("Basri, Devoted Paladin", 320, Rarity.MYTHIC, mage.cards.b.BasriDevotedPaladin.class)); cards.add(new SetCardInfo("Bolt Hound", 131, Rarity.UNCOMMON, mage.cards.b.BoltHound.class)); diff --git a/Mage/src/main/java/mage/game/command/emblems/BasriKetEmblem.java b/Mage/src/main/java/mage/game/command/emblems/BasriKetEmblem.java new file mode 100644 index 0000000000..e8fb405fc7 --- /dev/null +++ b/Mage/src/main/java/mage/game/command/emblems/BasriKetEmblem.java @@ -0,0 +1,31 @@ +package mage.game.command.emblems; + +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.command.Emblem; +import mage.game.permanent.token.SoldierToken; + +public final class BasriKetEmblem extends Emblem { + /** + * 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." + */ + + public BasriKetEmblem() { + setName("Emblem Basri"); + Ability ability = new BeginningOfCombatTriggeredAbility( + Zone.COMMAND, + new CreateTokenEffect(new SoldierToken()), + TargetController.YOU, false, false); + ability.addEffect( + new AddCountersAllEffect(CounterType.P1P1.createInstance(), StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED) + .setText(", then put a +1/+1 counter on each creature you control") + ); + this.getAbilities().add(ability); + } +} diff --git a/Mage/src/main/java/mage/game/command/emblems/LilianaWakerOfTheDeadEmblem.java b/Mage/src/main/java/mage/game/command/emblems/LilianaWakerOfTheDeadEmblem.java index 7ae6e94fe4..dead907e5b 100644 --- a/Mage/src/main/java/mage/game/command/emblems/LilianaWakerOfTheDeadEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/LilianaWakerOfTheDeadEmblem.java @@ -5,9 +5,7 @@ import mage.abilities.common.BeginningOfCombatTriggeredAbility; import mage.abilities.effects.common.ReturnCreatureFromGraveyardToBattlefieldAndGainHasteEffect; import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.FilterCard; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureCard; import mage.game.command.Emblem; import mage.target.common.TargetCardInGraveyard; @@ -16,8 +14,6 @@ public final class LilianaWakerOfTheDeadEmblem extends Emblem { * Emblem with "At the beginning of combat on your turn, put target creature card from a graveyard onto the battlefield under your control. It gains haste." */ - private static final FilterCard filter = new FilterCreatureCard("creature card from a graveyard"); - public LilianaWakerOfTheDeadEmblem() { setName("Emblem Liliana"); Ability ability = new BeginningOfCombatTriggeredAbility(