diff --git a/Mage.Sets/src/mage/cards/f/FiresOfInvention.java b/Mage.Sets/src/mage/cards/f/FiresOfInvention.java new file mode 100644 index 00000000000..2c23f65279c --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FiresOfInvention.java @@ -0,0 +1,99 @@ +package mage.cards.f; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.continuous.CastFromHandWithoutPayingManaCostEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.watchers.common.CastSpellLastTurnWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FiresOfInvention extends CardImpl { + + private static final FilterCard filter + = new FilterCard("spells with converted mana cost less than or equal to the number of lands you control"); + + static { + filter.add(FiresOfInventionPredicate.instance); + } + + public FiresOfInvention(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); + + // You can cast spells only during your turn and you can cast no more than two spells each turn. + this.addAbility(new SimpleStaticAbility(new FiresOfInventionCastEffect())); + + // You may cast spells with converted mana cost less than or equal to the number of lands you control without paying their mana costs. + this.addAbility(new SimpleStaticAbility(new CastFromHandWithoutPayingManaCostEffect(filter, false))); + } + + private FiresOfInvention(final FiresOfInvention card) { + super(card); + } + + @Override + public FiresOfInvention copy() { + return new FiresOfInvention(this); + } +} + +enum FiresOfInventionPredicate implements ObjectSourcePlayerPredicate> { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return input.getObject().getConvertedManaCost() <= + game.getBattlefield().countAll(StaticFilters.FILTER_LAND, game.getControllerId(input.getSourceId()), game); + } +} + +class FiresOfInventionCastEffect extends ContinuousRuleModifyingEffectImpl { + + FiresOfInventionCastEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "you can cast spells only during your turn and you can cast no more than two spells each turn"; + } + + private FiresOfInventionCastEffect(final FiresOfInventionCastEffect effect) { + super(effect); + } + + @Override + public FiresOfInventionCastEffect copy() { + return new FiresOfInventionCastEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!event.getPlayerId().equals(source.getControllerId())) { + return false; + } + CastSpellLastTurnWatcher watcher = game.getState().getWatcher(CastSpellLastTurnWatcher.class); + if (watcher == null) { + return false; + } + return watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(source.getControllerId()) > 2 + || !game.getActivePlayerId().equals(source.getControllerId()); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/ThroneOfEldraine.java b/Mage.Sets/src/mage/sets/ThroneOfEldraine.java index 4209664fc56..003a9e6a083 100644 --- a/Mage.Sets/src/mage/sets/ThroneOfEldraine.java +++ b/Mage.Sets/src/mage/sets/ThroneOfEldraine.java @@ -83,6 +83,7 @@ public final class ThroneOfEldraine extends ExpansionSet { cards.add(new SetCardInfo("Fervent Champion", 124, Rarity.RARE, mage.cards.f.FerventChampion.class)); cards.add(new SetCardInfo("Fierce Witchstalker", 154, Rarity.COMMON, mage.cards.f.FierceWitchstalker.class)); cards.add(new SetCardInfo("Fireborn Knight", 210, Rarity.UNCOMMON, mage.cards.f.FirebornKnight.class)); + cards.add(new SetCardInfo("Fires of Invention", 125, Rarity.RARE, mage.cards.f.FiresOfInvention.class)); cards.add(new SetCardInfo("Flaxen Intruder", 155, Rarity.UNCOMMON, mage.cards.f.FlaxenIntruder.class)); cards.add(new SetCardInfo("Folio of Fancies", 46, Rarity.RARE, mage.cards.f.FolioOfFancies.class)); cards.add(new SetCardInfo("Foulmire Knight", 90, Rarity.UNCOMMON, mage.cards.f.FoulmireKnight.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CastFromHandWithoutPayingManaCostEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CastFromHandWithoutPayingManaCostEffect.java index dcd3f9695e7..a330989828c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CastFromHandWithoutPayingManaCostEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CastFromHandWithoutPayingManaCostEffect.java @@ -10,7 +10,8 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.cards.Card; import mage.cards.SplitCardHalf; import mage.constants.*; -import mage.filter.common.FilterNonlandCard; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.stack.Spell; import mage.players.Player; @@ -19,13 +20,26 @@ import java.util.UUID; public class CastFromHandWithoutPayingManaCostEffect extends ContinuousEffectImpl { + private final FilterCard filter; + private final boolean fromHand; + public CastFromHandWithoutPayingManaCostEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "You may cast nonland cards from your hand without paying their mana costs"; + this(StaticFilters.FILTER_CARDS_NON_LAND, true); } - public CastFromHandWithoutPayingManaCostEffect(final CastFromHandWithoutPayingManaCostEffect effect) { + public CastFromHandWithoutPayingManaCostEffect(FilterCard filter, boolean fromHand) { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + this.filter = filter; + this.fromHand = fromHand; + staticText = "You may cast " + filter.getMessage() + + (fromHand ? " from your hand" : "") + + " without paying their mana costs"; + } + + private CastFromHandWithoutPayingManaCostEffect(final CastFromHandWithoutPayingManaCostEffect effect) { super(effect); + this.filter = effect.filter; + this.fromHand = effect.fromHand; } @Override @@ -36,12 +50,19 @@ public class CastFromHandWithoutPayingManaCostEffect extends ContinuousEffectImp @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - controller.getAlternativeSourceCosts().add(new AlternativeCostSourceAbility( - null, new CompoundCondition(SourceIsSpellCondition.instance, new IsBeingCastFromHandCondition()), null, new FilterNonlandCard(), true)); - return true; + if (controller == null) { + return false; } - return false; + Condition condition; + if (fromHand) { + condition = new CompoundCondition(SourceIsSpellCondition.instance, IsBeingCastFromHandCondition.instance); + } else { + condition = SourceIsSpellCondition.instance; + } + controller.getAlternativeSourceCosts().add(new AlternativeCostSourceAbility( + null, condition, null, filter, true + )); + return true; } @Override @@ -55,7 +76,8 @@ public class CastFromHandWithoutPayingManaCostEffect extends ContinuousEffectImp } } -class IsBeingCastFromHandCondition implements Condition { +enum IsBeingCastFromHandCondition implements Condition { + instance; @Override public boolean apply(Game game, Ability source) { diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 04807cef091..2888e8840a4 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -133,6 +133,13 @@ public final class StaticFilters { FILTER_CARD_A_NON_LAND.setLockedFilter(true); } + + public static final FilterNonlandCard FILTER_CARDS_NON_LAND = new FilterNonlandCard("nonland cards"); + + static { + FILTER_CARDS_NON_LAND.setLockedFilter(true); + } + public static final FilterInstantOrSorceryCard FILTER_CARD_INSTANT_OR_SORCERY = new FilterInstantOrSorceryCard(); static {