diff --git a/Mage.Sets/src/mage/cards/v/VeilOfSummer.java b/Mage.Sets/src/mage/cards/v/VeilOfSummer.java new file mode 100644 index 0000000000..8dfec6a28e --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeilOfSummer.java @@ -0,0 +1,144 @@ +package mage.cards.v; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CantBeCounteredControlledEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControllerEffect; +import mage.abilities.keyword.HexproofFromBlackAbility; +import mage.abilities.keyword.HexproofFromBlueAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.WatcherScope; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class VeilOfSummer extends CardImpl { + + public VeilOfSummer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}"); + + // Draw a card if an opponent has cast a blue or black spell this turn. Spells you control can't be countered this turn. You and permanents you control gain hexproof from blue and from black until end of turn. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new DrawCardSourceControllerEffect(1), + VeilOfSummerCondition.instance, "Draw a card " + + "if an opponent has cast a blue or black spell this turn." + )); + this.getSpellAbility().addEffect(new CantBeCounteredControlledEffect( + StaticFilters.FILTER_SPELL, Duration.EndOfTurn + ).setText("Spells you control can't be countered this turn.")); + this.getSpellAbility().addEffect(new VeilOfSummerEffect()); + this.getSpellAbility().addWatcher(new VeilOfSummerWatcher()); + } + + private VeilOfSummer(final VeilOfSummer card) { + super(card); + } + + @Override + public VeilOfSummer copy() { + return new VeilOfSummer(this); + } +} + +enum VeilOfSummerCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + VeilOfSummerWatcher watcher = game.getState().getWatcher(VeilOfSummerWatcher.class); + return watcher != null && watcher.opponentCastBlueBlackSpell(source.getControllerId()); + } +} + +class VeilOfSummerWatcher extends Watcher { + + private final Set opponentsCastBlueBlackSpell = new HashSet(); + + VeilOfSummerWatcher() { + super(WatcherScope.GAME); + } + + private VeilOfSummerWatcher(final VeilOfSummerWatcher watcher) { + super(watcher); + this.opponentsCastBlueBlackSpell.addAll(watcher.opponentsCastBlueBlackSpell); + } + + @Override + public VeilOfSummerWatcher copy() { + return new VeilOfSummerWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (GameEvent.EventType.SPELL_CAST == event.getType()) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell == null) { + return; + } + if (spell.getColor(game).isBlack() || spell.getColor(game).isBlack()) { + opponentsCastBlueBlackSpell.addAll(game.getOpponents(spell.getControllerId())); + } + } + } + + @Override + public void reset() { + super.reset(); + opponentsCastBlueBlackSpell.clear(); + } + + boolean opponentCastBlueBlackSpell(UUID playerId) { + return opponentsCastBlueBlackSpell.contains(playerId); + } +} + +class VeilOfSummerEffect extends OneShotEffect { + + VeilOfSummerEffect() { + super(Outcome.Benefit); + staticText = "You and permanents you control gain hexproof from blue and from black until end of turn"; + } + + private VeilOfSummerEffect(final VeilOfSummerEffect effect) { + super(effect); + } + + @Override + public VeilOfSummerEffect copy() { + return new VeilOfSummerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + game.addEffect(new GainAbilityControlledEffect( + HexproofFromBlueAbility.getInstance(), Duration.EndOfTurn + ), source); + game.addEffect(new GainAbilityControlledEffect( + HexproofFromBlackAbility.getInstance(), Duration.EndOfTurn + ), source); + game.addEffect(new GainAbilityControllerEffect( + HexproofFromBlueAbility.getInstance(), Duration.EndOfTurn + ), source); + game.addEffect(new GainAbilityControllerEffect( + HexproofFromBlackAbility.getInstance(), Duration.EndOfTurn + ), source); + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/CoreSet2020.java b/Mage.Sets/src/mage/sets/CoreSet2020.java index 7bd14eda74..93ececd0ca 100644 --- a/Mage.Sets/src/mage/sets/CoreSet2020.java +++ b/Mage.Sets/src/mage/sets/CoreSet2020.java @@ -189,6 +189,7 @@ public final class CoreSet2020 extends ExpansionSet { cards.add(new SetCardInfo("Unchained Berserker", 164, Rarity.UNCOMMON, mage.cards.u.UnchainedBerserker.class)); cards.add(new SetCardInfo("Unsummon", 78, Rarity.COMMON, mage.cards.u.Unsummon.class)); cards.add(new SetCardInfo("Vampire of the Dire Moon", 120, Rarity.UNCOMMON, mage.cards.v.VampireOfTheDireMoon.class)); + cards.add(new SetCardInfo("Veil of Summer", 198, Rarity.UNCOMMON, mage.cards.v.VeilOfSummer.class)); cards.add(new SetCardInfo("Vial of Dragonfire", 241, Rarity.COMMON, mage.cards.v.VialOfDragonfire.class)); cards.add(new SetCardInfo("Vilis, Broker of Blood", 122, Rarity.RARE, mage.cards.v.VilisBrokerOfBlood.class)); cards.add(new SetCardInfo("Vivien, Arkbow Ranger", 199, Rarity.MYTHIC, mage.cards.v.VivienArkbowRanger.class)); diff --git a/Mage/src/main/java/mage/abilities/keyword/HexproofFromBlueAbility.java b/Mage/src/main/java/mage/abilities/keyword/HexproofFromBlueAbility.java new file mode 100644 index 0000000000..4f65271fa0 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/HexproofFromBlueAbility.java @@ -0,0 +1,44 @@ +package mage.abilities.keyword; + +import mage.abilities.MageSingleton; +import mage.abilities.common.SimpleStaticAbility; +import mage.constants.Zone; + +import java.io.ObjectStreamException; + +/** + * Hexproof from blue (This creature or player can't be the target of black + * spells or abilities your opponents control.) + * + * @author igoudt + */ +public class HexproofFromBlueAbility extends SimpleStaticAbility implements MageSingleton { + + private static final HexproofFromBlueAbility instance; + + static { + instance = new HexproofFromBlueAbility(); + } + + private Object readResolve() throws ObjectStreamException { + return instance; + } + + public static HexproofFromBlueAbility getInstance() { + return instance; + } + + private HexproofFromBlueAbility() { + super(Zone.BATTLEFIELD, null); + } + + @Override + public HexproofFromBlueAbility copy() { + return instance; + } + + @Override + public String getRule() { + return "hexproof from blue (This creature can't be the target of blue spells or abilities your opponents control.)"; + } +} diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 725e077df0..0af2dc5e51 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -1008,14 +1008,6 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { } } - if (abilities.containsKey(HexproofFromBlackAbility.getInstance().getId())) { - if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game) - && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game) - && source.getColor(game).isBlack()) { - return false; - } - } - if (abilities.containsKey(HexproofFromWhiteAbility.getInstance().getId())) { if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game) && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game) @@ -1024,6 +1016,22 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { } } + if (abilities.containsKey(HexproofFromBlueAbility.getInstance().getId())) { + if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game) + && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game) + && source.getColor(game).isBlue()) { + return false; + } + } + + if (abilities.containsKey(HexproofFromBlackAbility.getInstance().getId())) { + if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game) + && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game) + && source.getColor(game).isBlack()) { + return false; + } + } + if (abilities.containsKey(HexproofFromMonocoloredAbility.getInstance().getId())) { if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game) && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game)