diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java index 8c8b301af6a..f62801a02f9 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java @@ -25,6 +25,7 @@ public class Brawl extends Constructed { setCodes.addAll(Standard.makeLegalSets()); banned.add("Golos, Tireless Pilgrim"); + banned.add("Lutri, the Spellchaser"); banned.add("Oko, Thief of Crowns"); banned.add("Sorcerous Spyglass"); } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java index dda9400490e..8836549e401 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java @@ -50,6 +50,7 @@ public class Commander extends Constructed { banned.add("Leovold, Emissary of Trest"); banned.add("Library of Alexandria"); banned.add("Limited Resources"); + banned.add("Lutri, the Spellchaser"); banned.add("Mox Emerald"); banned.add("Mox Jet"); banned.add("Mox Pearl"); diff --git a/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java b/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java new file mode 100644 index 00000000000..d0a33d48bf0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java @@ -0,0 +1,97 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.CastFromEverywhereSourceCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.CopyTargetSpellEffect; +import mage.abilities.keyword.CompanionAbility; +import mage.abilities.keyword.CompanionCondition; +import mage.abilities.keyword.FlashAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.filter.FilterSpell; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.target.TargetSpell; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LutriTheSpellchaser extends CardImpl { + + private static final FilterSpell filter + = new FilterInstantOrSorcerySpell("instant or sorcery spell you control"); + + static { + filter.add(TargetController.YOU.getControllerPredicate()); + } + + public LutriTheSpellchaser(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U/R}{U/R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.OTTER); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Companion — Each nonland card in your starting deck has a different name. + this.addAbility(new CompanionAbility(LutriTheSpellchaserCompanionCondition.instance)); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // When Lutri, the Spellchaser enters the battlefield, if you cast it, copy target instant or sorcery spell you control. You may choose new targets for the copy. + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new CopyTargetSpellEffect(), false), + CastFromEverywhereSourceCondition.instance, "When {this} enters the battlefield, " + + "if you cast it, copy target instant or sorcery spell you control. " + + "You may choose new targets for the copy." + ); + ability.addTarget(new TargetSpell(filter)); + this.addAbility(ability); + } + + private LutriTheSpellchaser(final LutriTheSpellchaser card) { + super(card); + } + + @Override + public LutriTheSpellchaser copy() { + return new LutriTheSpellchaser(this); + } +} + +enum LutriTheSpellchaserCompanionCondition implements CompanionCondition { + instance; + + @Override + public String getRule() { + return "Each nonland card in your starting deck has a different name"; + } + + @Override + public boolean isLegal(Set deck) { + Map cardMap = new HashMap(); + deck.stream() + .filter(card -> !card.isLand()) + .map(MageObject::getName) + .forEach(s -> { + cardMap.putIfAbsent(s, 0); + cardMap.compute(s, (str, i) -> i + 1); + }); + return cardMap.values().stream().noneMatch(i -> i > 1); + } +} diff --git a/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java b/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java index eb972d16bf6..0106b9f286e 100644 --- a/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java +++ b/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java @@ -193,6 +193,7 @@ public final class IkoriaLairOfBehemoths extends ExpansionSet { cards.add(new SetCardInfo("Lore Drakkis", 194, Rarity.UNCOMMON, mage.cards.l.LoreDrakkis.class)); cards.add(new SetCardInfo("Luminous Broodmoth", 316, Rarity.MYTHIC, mage.cards.l.LuminousBroodmoth.class)); cards.add(new SetCardInfo("Lurking Deadeye", 94, Rarity.COMMON, mage.cards.l.LurkingDeadeye.class)); + cards.add(new SetCardInfo("Lutri, the Spellchaser", 227, Rarity.RARE, mage.cards.l.LutriTheSpellchaser.class)); cards.add(new SetCardInfo("Majestic Auricorn", 22, Rarity.UNCOMMON, mage.cards.m.MajesticAuricorn.class)); cards.add(new SetCardInfo("Maned Serval", 23, Rarity.COMMON, mage.cards.m.ManedServal.class)); cards.add(new SetCardInfo("Memory Leak", 95, Rarity.COMMON, mage.cards.m.MemoryLeak.class));