From 85bc7549fa04dc4099bac214159fca302169a5d1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 4 Jun 2016 12:21:47 +0200 Subject: [PATCH] * Added Custodi Squire (2 votes), Nightshade Assassin (2 votes), Seize the Day (2 votes) from the Card Requests - JUNE list. --- .../mage/sets/coldsnap/FuryOfTheHorde.java | 136 +--------------- .../sets/conspiracy/BiteOfTheBlackRose.java | 6 +- .../mage/sets/conspiracy/CoercivePortal.java | 21 ++- .../mage/sets/conspiracy/CustodiSquire.java | 151 ++++++++++++++++++ .../mage/sets/conspiracy/SplitDecision.java | 9 +- .../mage/sets/conspiracy/TyrantsChoice.java | 17 +- .../mage/sets/eventide/WavesOfAggression.java | 133 +-------------- .../src/mage/sets/odyssey/SeizeTheDay.java | 68 ++++++++ .../seventhedition/RelentlessAssault.java | 134 +--------------- .../sets/timespiral/NightshadeAssassin.java | 131 +++++++++++++++ .../common/AddCombatAndMainPhaseEffect.java | 126 +++++++++++++++ .../common/UntapAllThatAttackedEffect.java | 80 ++++++++++ Utils/mtg-sets-data.txt | 2 +- 13 files changed, 595 insertions(+), 419 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/conspiracy/CustodiSquire.java create mode 100644 Mage.Sets/src/mage/sets/odyssey/SeizeTheDay.java create mode 100644 Mage.Sets/src/mage/sets/timespiral/NightshadeAssassin.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/AddCombatAndMainPhaseEffect.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java diff --git a/Mage.Sets/src/mage/sets/coldsnap/FuryOfTheHorde.java b/Mage.Sets/src/mage/sets/coldsnap/FuryOfTheHorde.java index 3ccfc928ca..f0817fa18d 100644 --- a/Mage.Sets/src/mage/sets/coldsnap/FuryOfTheHorde.java +++ b/Mage.Sets/src/mage/sets/coldsnap/FuryOfTheHorde.java @@ -27,29 +27,18 @@ */ package mage.sets.coldsnap; -import java.util.Set; import java.util.UUID; import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; import mage.abilities.costs.AlternativeCostSourceAbility; import mage.abilities.costs.common.ExileFromHandCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AddCombatAndMainPhaseEffect; +import mage.abilities.effects.common.UntapAllThatAttackedEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.TurnPhase; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.game.turn.TurnMod; import mage.target.common.TargetCardInHand; -import mage.watchers.Watcher; import mage.watchers.common.AttackedThisTurnWatcher; /** @@ -72,8 +61,8 @@ public class FuryOfTheHorde extends CardImpl { this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(2, filter)))); // Untap all creatures that attacked this turn. After this main phase, there is an additional combat phase followed by an additional main phase. - this.getSpellAbility().addEffect(new FuryOfTheHordeUntapEffect()); - this.getSpellAbility().addEffect(new FuryOfTheHordeAddPhasesEffect()); + this.getSpellAbility().addEffect(new UntapAllThatAttackedEffect()); + this.getSpellAbility().addEffect(new AddCombatAndMainPhaseEffect()); this.getSpellAbility().addWatcher(new AttackedThisTurnWatcher()); } @@ -87,120 +76,3 @@ public class FuryOfTheHorde extends CardImpl { return new FuryOfTheHorde(this); } } - -class FuryOfTheHordeUntapEffect extends OneShotEffect { - - public FuryOfTheHordeUntapEffect() { - super(Outcome.Benefit); - staticText = " Untap all creatures that attacked this turn"; - } - - public FuryOfTheHordeUntapEffect(final FuryOfTheHordeUntapEffect effect) { - super(effect); - } - - @Override - public FuryOfTheHordeUntapEffect copy() { - return new FuryOfTheHordeUntapEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatchers().get("AttackedThisTurn"); - if (watcher != null && watcher instanceof AttackedThisTurnWatcher) { - Set attackedThisTurn = ((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures(); - for (UUID uuid : attackedThisTurn) { - Permanent permanent = game.getPermanent(uuid); - if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { - permanent.untap(game); - } - } - return true; - } - return false; - } - -} - -class FuryOfTheHordeAddPhasesEffect extends OneShotEffect { - - public FuryOfTheHordeAddPhasesEffect() { - super(Outcome.Benefit); - staticText = "After this main phase, there is an additional combat phase followed by an additional main phase"; - } - - public FuryOfTheHordeAddPhasesEffect(final FuryOfTheHordeAddPhasesEffect effect) { - super(effect); - } - - @Override - public FuryOfTheHordeAddPhasesEffect copy() { - return new FuryOfTheHordeAddPhasesEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - // 15.07.2006 If it's somehow not a main phase when Fury of the Horde resolves, all it does is untap all creatures that attacked that turn. No new phases are created. - if (TurnPhase.PRECOMBAT_MAIN.equals(game.getTurn().getPhaseType()) - || TurnPhase.POSTCOMBAT_MAIN.equals(game.getTurn().getPhaseType())) { - // we can't add two turn modes at once, will add additional post combat on delayed trigger resolution - TurnMod combat = new TurnMod(source.getControllerId(), TurnPhase.COMBAT, TurnPhase.POSTCOMBAT_MAIN, false); - game.getState().getTurnMods().add(combat); - DelayedAddMainPhaseAbility delayedTriggeredAbility = new DelayedAddMainPhaseAbility(); - delayedTriggeredAbility.setConnectedTurnMod(combat.getId()); - game.addDelayedTriggeredAbility(delayedTriggeredAbility, source); - return true; - } - return false; - } - -} - -class DelayedAddMainPhaseAbility extends DelayedTriggeredAbility { - - private UUID connectedTurnMod; - private boolean enabled; - - public DelayedAddMainPhaseAbility() { - super(null, Duration.EndOfTurn); - this.usesStack = false; // don't show this to the user - } - - public DelayedAddMainPhaseAbility(DelayedAddMainPhaseAbility ability) { - super(ability); - this.connectedTurnMod = ability.connectedTurnMod; - this.enabled = ability.enabled; - } - - @Override - public DelayedAddMainPhaseAbility copy() { - return new DelayedAddMainPhaseAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.PHASE_CHANGED || event.getType() == EventType.COMBAT_PHASE_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.PHASE_CHANGED && this.connectedTurnMod.equals(event.getSourceId())) { - enabled = true; - } - if (event.getType() == GameEvent.EventType.COMBAT_PHASE_PRE && enabled) { - // add additional post combat main phase after that - after phase == null because add it after this combat - game.getState().getTurnMods().add(new TurnMod(getControllerId(), TurnPhase.POSTCOMBAT_MAIN, null, false)); - enabled = false; - } - return false; - } - - public void setConnectedTurnMod(UUID connectedTurnMod) { - this.connectedTurnMod = connectedTurnMod; - } - - @Override - public String getRule() { - return "add additional post combat main phase"; - } -} diff --git a/Mage.Sets/src/mage/sets/conspiracy/BiteOfTheBlackRose.java b/Mage.Sets/src/mage/sets/conspiracy/BiteOfTheBlackRose.java index d8f9840867..575a3bc6b5 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/BiteOfTheBlackRose.java +++ b/Mage.Sets/src/mage/sets/conspiracy/BiteOfTheBlackRose.java @@ -94,10 +94,10 @@ class BiteOfTheBlackRoseEffect extends OneShotEffect { if (player != null) { if (player.chooseUse(Outcome.ExtraTurn, "Choose sickness?", source, game)) { sicknessCount++; - game.informPlayers(player.getLogName() + " has chosen: sickness"); + game.informPlayers(player.getLogName() + " has voted for sickness"); } else { psychosisCount++; - game.informPlayers(player.getLogName() + " has chosen: psychosis"); + game.informPlayers(player.getLogName() + " has voted for psychosis"); } } } @@ -111,4 +111,4 @@ class BiteOfTheBlackRoseEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/conspiracy/CoercivePortal.java b/Mage.Sets/src/mage/sets/conspiracy/CoercivePortal.java index b08a39c58d..edebffad05 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/CoercivePortal.java +++ b/Mage.Sets/src/mage/sets/conspiracy/CoercivePortal.java @@ -68,21 +68,21 @@ public class CoercivePortal extends CardImpl { } class CoercivePortalEffect extends OneShotEffect { - + CoercivePortalEffect() { super(Outcome.Benefit); this.staticText = "Will of the council - At the beginning of your upkeep, starting with you, each player votes for carnage or homage. If carnage gets more votes, sacrifice Coercive Portal and destroy all nonland permanents. If homage gets more votes or the vote is tied, draw a card"; } - + CoercivePortalEffect(final CoercivePortalEffect effect) { super(effect); } - + @Override public CoercivePortalEffect copy() { return new CoercivePortalEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -94,17 +94,16 @@ class CoercivePortalEffect extends OneShotEffect { if (player != null) { if (player.chooseUse(Outcome.DestroyPermanent, "Choose carnage?", source, game)) { carnageCount++; - game.informPlayers(player.getLogName() + " has chosen: carnage"); - } - else { + game.informPlayers(player.getLogName() + " has voted for carnage"); + } else { homageCount++; - game.informPlayers(player.getLogName() + " has chosen: homage"); + game.informPlayers(player.getLogName() + " has voted for homage"); } } } if (carnageCount > homageCount) { new SacrificeSourceEffect().apply(game, source); - new CoercivePortalDestroyEffect().apply(game, source); + new CoercivePortalDestroyEffect().apply(game, source); } else { controller.drawCards(1, game); } @@ -115,7 +114,7 @@ class CoercivePortalEffect extends OneShotEffect { } class CoercivePortalDestroyEffect extends OneShotEffect { - + private static final FilterPermanent filter = new FilterNonlandPermanent(); public CoercivePortalDestroyEffect() { @@ -140,4 +139,4 @@ class CoercivePortalDestroyEffect extends OneShotEffect { return new CoercivePortalDestroyEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/conspiracy/CustodiSquire.java b/Mage.Sets/src/mage/sets/conspiracy/CustodiSquire.java new file mode 100644 index 0000000000..d3c3801516 --- /dev/null +++ b/Mage.Sets/src/mage/sets/conspiracy/CustodiSquire.java @@ -0,0 +1,151 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.conspiracy; + +import java.util.HashMap; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; + +/** + * + * @author LevelX2 + */ +public class CustodiSquire extends CardImpl { + + public CustodiSquire(UUID ownerId) { + super(ownerId, 18, "Custodi Squire", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{W}"); + this.expansionSetCode = "CNS"; + this.subtype.add("Spirit"); + this.subtype.add("Cleric"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Will of the council - When Custodi Squire enters the battlefield, starting with you, each player votes for an artifact, creature, or enchantment card in your graveyard. Return each card with the most votes or tied for most votes to your hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CustodiSquireVoteEffect(), false, true)); + } + + public CustodiSquire(final CustodiSquire card) { + super(card); + } + + @Override + public CustodiSquire copy() { + return new CustodiSquire(this); + } +} + +class CustodiSquireVoteEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("artifact, creature, or enchantment card from your graveyard"); + + static { + filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.ENCHANTMENT))); + } + + CustodiSquireVoteEffect() { + super(Outcome.Benefit); + this.staticText = "Will of the council - When {this} enters the battlefield, starting with you, each player votes for an artifact, creature, or enchantment card in your graveyard. Return each card with the most votes or tied for most votes to your hand"; + } + + CustodiSquireVoteEffect(final CustodiSquireVoteEffect effect) { + super(effect); + } + + @Override + public CustodiSquireVoteEffect copy() { + return new CustodiSquireVoteEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards possibleCards = new CardsImpl(); + possibleCards.addAll(controller.getGraveyard().getCards(filter, game)); + if (!possibleCards.isEmpty()) { + HashMap cardCounter = new HashMap<>(); + TargetCard target = new TargetCard(1, 1, Zone.GRAVEYARD, filter); + int maxCount = 1; + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + target.clearChosen(); + player.chooseTarget(outcome, possibleCards, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + game.informPlayers(player.getName() + " voted for " + card.getLogName()); + if (!cardCounter.containsKey(target.getFirstTarget())) { + cardCounter.put(target.getFirstTarget(), 1); + } else { + int count = cardCounter.get(target.getFirstTarget()) + 1; + if (count > maxCount) { + maxCount = count; + } + cardCounter.put(target.getFirstTarget(), count); + } + } + } + } + Cards cardsToMove = new CardsImpl(); + for (UUID uuid : possibleCards) { + if (cardCounter.containsKey(uuid)) { + if (cardCounter.get(uuid) == maxCount) { + cardsToMove.add(uuid); + } + } + } + controller.moveCards(cardsToMove, Zone.HAND, source, game); + } + return true; + } + return false; + + } +} diff --git a/Mage.Sets/src/mage/sets/conspiracy/SplitDecision.java b/Mage.Sets/src/mage/sets/conspiracy/SplitDecision.java index 09733d9772..db300384e7 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/SplitDecision.java +++ b/Mage.Sets/src/mage/sets/conspiracy/SplitDecision.java @@ -47,8 +47,9 @@ import mage.target.TargetSpell; * @author fireshoes */ public class SplitDecision extends CardImpl { - + private static final FilterSpell filter = new FilterSpell("instant or sorcery spell"); + static { filter.add(Predicates.or( new CardTypePredicate(CardType.INSTANT), @@ -101,10 +102,10 @@ class SplitDecisionEffect extends OneShotEffect { if (player != null) { if (player.chooseUse(Outcome.ExtraTurn, "Choose denial?", source, game)) { denialCount++; - game.informPlayers(player.getLogName() + " has chosen: denial"); + game.informPlayers(player.getLogName() + " has voted for denial"); } else { duplicationCount++; - game.informPlayers(player.getLogName() + " has chosen: duplication"); + game.informPlayers(player.getLogName() + " has voted for duplication"); } } } @@ -116,4 +117,4 @@ class SplitDecisionEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/conspiracy/TyrantsChoice.java b/Mage.Sets/src/mage/sets/conspiracy/TyrantsChoice.java index 8b2613ffe2..9cd9d26e3a 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/TyrantsChoice.java +++ b/Mage.Sets/src/mage/sets/conspiracy/TyrantsChoice.java @@ -64,21 +64,21 @@ public class TyrantsChoice extends CardImpl { } class TyrantsChoiceEffect extends OneShotEffect { - + TyrantsChoiceEffect() { super(Outcome.Benefit); this.staticText = "Will of the council - Starting with you, each player votes for death or torture. If death gets more votes, each opponent sacrifices a creature. If torture gets more votes or the vote is tied, each opponent loses 4 life"; } - + TyrantsChoiceEffect(final TyrantsChoiceEffect effect) { super(effect); } - + @Override public TyrantsChoiceEffect copy() { return new TyrantsChoiceEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -90,11 +90,10 @@ class TyrantsChoiceEffect extends OneShotEffect { if (player != null) { if (player.chooseUse(Outcome.Sacrifice, "Choose death?", source, game)) { deathCount++; - game.informPlayers(player.getLogName() + " has chosen: death"); - } - else { + game.informPlayers(player.getLogName() + " has voted for death"); + } else { tortureCount++; - game.informPlayers(player.getLogName() + " has chosen: torture"); + game.informPlayers(player.getLogName() + " has voted for torture"); } } } @@ -133,4 +132,4 @@ class TyrantsChoiceLoseLifeEffect extends OneShotEffect { return new TyrantsChoiceLoseLifeEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/eventide/WavesOfAggression.java b/Mage.Sets/src/mage/sets/eventide/WavesOfAggression.java index cc934abeb3..df33397641 100644 --- a/Mage.Sets/src/mage/sets/eventide/WavesOfAggression.java +++ b/Mage.Sets/src/mage/sets/eventide/WavesOfAggression.java @@ -27,24 +27,13 @@ */ package mage.sets.eventide; -import java.util.Set; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AddCombatAndMainPhaseEffect; +import mage.abilities.effects.common.UntapAllThatAttackedEffect; import mage.abilities.keyword.RetraceAbility; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.TurnPhase; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.game.turn.TurnMod; -import mage.watchers.Watcher; import mage.watchers.common.AttackedThisTurnWatcher; /** @@ -59,8 +48,8 @@ public class WavesOfAggression extends CardImpl { // Untap all creatures that attacked this turn. After this main phase, there is an additional combat phase followed by an additional main phase. this.getSpellAbility().addWatcher(new AttackedThisTurnWatcher()); - this.getSpellAbility().addEffect(new WavesOfAggressionUntapEffect()); - this.getSpellAbility().addEffect(new WavesOfAggressionAddPhasesEffect()); + this.getSpellAbility().addEffect(new UntapAllThatAttackedEffect()); + this.getSpellAbility().addEffect(new AddCombatAndMainPhaseEffect()); // Retrace this.addAbility(new RetraceAbility(this)); } @@ -74,117 +63,3 @@ public class WavesOfAggression extends CardImpl { return new WavesOfAggression(this); } } - -class WavesOfAggressionUntapEffect extends OneShotEffect { - - public WavesOfAggressionUntapEffect() { - super(Outcome.Benefit); - staticText = "Untap all creatures that attacked this turn"; - } - - public WavesOfAggressionUntapEffect(final WavesOfAggressionUntapEffect effect) { - super(effect); - } - - @Override - public WavesOfAggressionUntapEffect copy() { - return new WavesOfAggressionUntapEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatchers().get("AttackedThisTurn"); - if (watcher != null && watcher instanceof AttackedThisTurnWatcher) { - Set attackedThisTurn = ((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures(); - for (UUID uuid : attackedThisTurn) { - Permanent permanent = game.getPermanent(uuid); - if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { - permanent.untap(game); - } - } - return true; - } - return false; - } -} - -class WavesOfAggressionAddPhasesEffect extends OneShotEffect { - - public WavesOfAggressionAddPhasesEffect() { - super(Outcome.Benefit); - staticText = "After this main phase, there is an additional combat phase followed by an additional main phase"; - } - - public WavesOfAggressionAddPhasesEffect(final WavesOfAggressionAddPhasesEffect effect) { - super(effect); - } - - @Override - public WavesOfAggressionAddPhasesEffect copy() { - return new WavesOfAggressionAddPhasesEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - // 15.07.2006 If it's somehow not a main phase when Fury of the Horde resolves, all it does is untap all creatures that attacked that turn. No new phases are created. - if (TurnPhase.PRECOMBAT_MAIN.equals(game.getTurn().getPhaseType()) || TurnPhase.POSTCOMBAT_MAIN.equals(game.getTurn().getPhaseType())) { - // we can't add two turn modes at once, will add additional post combat on delayed trigger resolution - TurnMod combat = new TurnMod(source.getControllerId(), TurnPhase.COMBAT, TurnPhase.POSTCOMBAT_MAIN, false); - game.getState().getTurnMods().add(combat); - WavesOfAggressionDelayedAddMainPhaseAbility delayedTriggeredAbility = new WavesOfAggressionDelayedAddMainPhaseAbility(); - delayedTriggeredAbility.setConnectedTurnMod(combat.getId()); - game.addDelayedTriggeredAbility(delayedTriggeredAbility, source); - return true; - } - return false; - } -} - -class WavesOfAggressionDelayedAddMainPhaseAbility extends DelayedTriggeredAbility { - - private UUID connectedTurnMod; - private boolean enabled; - - public WavesOfAggressionDelayedAddMainPhaseAbility() { - super(null, Duration.EndOfTurn); - this.usesStack = false; // don't show this to the user - } - - public WavesOfAggressionDelayedAddMainPhaseAbility(WavesOfAggressionDelayedAddMainPhaseAbility ability) { - super(ability); - this.connectedTurnMod = ability.connectedTurnMod; - this.enabled = ability.enabled; - } - - @Override - public WavesOfAggressionDelayedAddMainPhaseAbility copy() { - return new WavesOfAggressionDelayedAddMainPhaseAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.PHASE_CHANGED || event.getType() == EventType.COMBAT_PHASE_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.PHASE_CHANGED && this.connectedTurnMod.equals(event.getSourceId())) { - enabled = true; - } - if (event.getType() == GameEvent.EventType.COMBAT_PHASE_PRE && enabled) { - // add additional post combat main phase after that - after phase == null because add it after this combat - game.getState().getTurnMods().add(new TurnMod(getControllerId(), TurnPhase.POSTCOMBAT_MAIN, null, false)); - enabled = false; - } - return false; - } - - public void setConnectedTurnMod(UUID connectedTurnMod) { - this.connectedTurnMod = connectedTurnMod; - } - - @Override - public String getRule() { - return "add additional post combat main phase"; - } -} diff --git a/Mage.Sets/src/mage/sets/odyssey/SeizeTheDay.java b/Mage.Sets/src/mage/sets/odyssey/SeizeTheDay.java new file mode 100644 index 0000000000..f55c8faf40 --- /dev/null +++ b/Mage.Sets/src/mage/sets/odyssey/SeizeTheDay.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.odyssey; + +import java.util.UUID; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.AddCombatAndMainPhaseEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.keyword.FlashbackAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TimingRule; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class SeizeTheDay extends CardImpl { + + public SeizeTheDay(UUID ownerId) { + super(ownerId, 220, "Seize the Day", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{R}"); + this.expansionSetCode = "ODY"; + + // Untap target creature. After this main phase, there is an additional combat phase followed by an additional main phase. + this.getSpellAbility().addEffect(new UntapTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new AddCombatAndMainPhaseEffect()); + + // Flashback {2}{R} + this.addAbility(new FlashbackAbility(new ManaCostsImpl("{2}{R}"), TimingRule.SORCERY)); + } + + public SeizeTheDay(final SeizeTheDay card) { + super(card); + } + + @Override + public SeizeTheDay copy() { + return new SeizeTheDay(this); + } +} diff --git a/Mage.Sets/src/mage/sets/seventhedition/RelentlessAssault.java b/Mage.Sets/src/mage/sets/seventhedition/RelentlessAssault.java index 177f36f837..84cff1ef34 100644 --- a/Mage.Sets/src/mage/sets/seventhedition/RelentlessAssault.java +++ b/Mage.Sets/src/mage/sets/seventhedition/RelentlessAssault.java @@ -27,23 +27,12 @@ */ package mage.sets.seventhedition; -import java.util.Set; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AddCombatAndMainPhaseEffect; +import mage.abilities.effects.common.UntapAllThatAttackedEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.TurnPhase; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.game.turn.TurnMod; -import mage.watchers.Watcher; import mage.watchers.common.AttackedThisTurnWatcher; /** @@ -58,8 +47,8 @@ public class RelentlessAssault extends CardImpl { // Untap all creatures that attacked this turn. After this main phase, there is an additional combat phase followed by an additional main phase. this.getSpellAbility().addWatcher(new AttackedThisTurnWatcher()); - this.getSpellAbility().addEffect(new RelentlessAssaultUntapEffect()); - this.getSpellAbility().addEffect(new RelentlessAssaultAddPhasesEffect()); + this.getSpellAbility().addEffect(new UntapAllThatAttackedEffect()); + this.getSpellAbility().addEffect(new AddCombatAndMainPhaseEffect()); } public RelentlessAssault(final RelentlessAssault card) { @@ -71,118 +60,3 @@ public class RelentlessAssault extends CardImpl { return new RelentlessAssault(this); } } - -class RelentlessAssaultUntapEffect extends OneShotEffect { - - public RelentlessAssaultUntapEffect() { - super(Outcome.Benefit); - staticText = "Untap all creatures that attacked this turn"; - } - - public RelentlessAssaultUntapEffect(final RelentlessAssaultUntapEffect effect) { - super(effect); - } - - @Override - public RelentlessAssaultUntapEffect copy() { - return new RelentlessAssaultUntapEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatchers().get("AttackedThisTurn"); - if (watcher != null && watcher instanceof AttackedThisTurnWatcher) { - Set attackedThisTurn = ((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures(); - for (UUID uuid : attackedThisTurn) { - Permanent permanent = game.getPermanent(uuid); - if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { - permanent.untap(game); - } - } - return true; - } - return false; - } -} - -class RelentlessAssaultAddPhasesEffect extends OneShotEffect { - - public RelentlessAssaultAddPhasesEffect() { - super(Outcome.Benefit); - staticText = "After this main phase, there is an additional combat phase followed by an additional main phase"; - } - - public RelentlessAssaultAddPhasesEffect(final RelentlessAssaultAddPhasesEffect effect) { - super(effect); - } - - @Override - public RelentlessAssaultAddPhasesEffect copy() { - return new RelentlessAssaultAddPhasesEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - // 15.07.2006 If it's somehow not a main phase when Fury of the Horde resolves, all it does is untap all creatures that attacked that turn. No new phases are created. - if (TurnPhase.PRECOMBAT_MAIN.equals(game.getTurn().getPhaseType()) || TurnPhase.POSTCOMBAT_MAIN.equals(game.getTurn().getPhaseType())) { - // we can't add two turn modes at once, will add additional post combat on delayed trigger resolution - TurnMod combat = new TurnMod(source.getControllerId(), TurnPhase.COMBAT, TurnPhase.POSTCOMBAT_MAIN, false); - game.getState().getTurnMods().add(combat); - RelentlessAssaultDelayedAddMainPhaseAbility delayedTriggeredAbility = new RelentlessAssaultDelayedAddMainPhaseAbility(); - delayedTriggeredAbility.setConnectedTurnMod(combat.getId()); - game.addDelayedTriggeredAbility(delayedTriggeredAbility, source); - return true; - } - return false; - } -} - -class RelentlessAssaultDelayedAddMainPhaseAbility extends DelayedTriggeredAbility { - - private UUID connectedTurnMod; - private boolean enabled; - - public RelentlessAssaultDelayedAddMainPhaseAbility() { - super(null, Duration.EndOfTurn); - this.usesStack = false; // don't show this to the user - } - - public RelentlessAssaultDelayedAddMainPhaseAbility(RelentlessAssaultDelayedAddMainPhaseAbility ability) { - super(ability); - this.connectedTurnMod = ability.connectedTurnMod; - this.enabled = ability.enabled; - } - - @Override - public RelentlessAssaultDelayedAddMainPhaseAbility copy() { - return new RelentlessAssaultDelayedAddMainPhaseAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.PHASE_CHANGED - || event.getType() == EventType.COMBAT_PHASE_PRE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.PHASE_CHANGED && this.connectedTurnMod.equals(event.getSourceId())) { - enabled = true; - } - if (event.getType() == GameEvent.EventType.COMBAT_PHASE_PRE && enabled) { - // add additional post combat main phase after that - after phase == null because add it after this combat - game.getState().getTurnMods().add(new TurnMod(getControllerId(), TurnPhase.POSTCOMBAT_MAIN, null, false)); - enabled = false; - } - return false; - } - - public void setConnectedTurnMod(UUID connectedTurnMod) { - this.connectedTurnMod = connectedTurnMod; - } - - @Override - public String getRule() { - return "add additional post combat main phase"; - } -} diff --git a/Mage.Sets/src/mage/sets/timespiral/NightshadeAssassin.java b/Mage.Sets/src/mage/sets/timespiral/NightshadeAssassin.java new file mode 100644 index 0000000000..0372510608 --- /dev/null +++ b/Mage.Sets/src/mage/sets/timespiral/NightshadeAssassin.java @@ -0,0 +1,131 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.timespiral; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class NightshadeAssassin extends CardImpl { + + public NightshadeAssassin(UUID ownerId) { + super(ownerId, 121, "Nightshade Assassin", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + this.expansionSetCode = "TSP"; + this.subtype.add("Human"); + this.subtype.add("Assassin"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // When Nightshade Assassin enters the battlefield, you may reveal X black cards in your hand. If you do, target creature gets -X/-X until end of turn. + Ability ability = new EntersBattlefieldTriggeredAbility(new NightshadeAssassinEffect(), true); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // Madness {1}{B} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{B}"))); + } + + public NightshadeAssassin(final NightshadeAssassin card) { + super(card); + } + + @Override + public NightshadeAssassin copy() { + return new NightshadeAssassin(this); + } +} + +class NightshadeAssassinEffect extends OneShotEffect { + + public NightshadeAssassinEffect() { + super(Outcome.UnboostCreature); + staticText = "you may reveal X black cards in your hand. If you do, target creature gets -X/-X until end of turn"; + } + + public NightshadeAssassinEffect(final NightshadeAssassinEffect effect) { + super(effect); + } + + @Override + public NightshadeAssassinEffect copy() { + return new NightshadeAssassinEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller == null || sourceObject == null) { + return false; + } + FilterCard filter = new FilterCard(); + filter.add(new ColorPredicate(ObjectColor.BLACK)); + int blackCards = controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game); + int cardsToReveal = controller.getAmount(0, blackCards, "Reveal how many black cards?", game); + game.informPlayers(controller.getLogName() + " chooses to reveal " + cardsToReveal + " black cards."); + if (cardsToReveal > 0) { + TargetCardInHand target = new TargetCardInHand(cardsToReveal, cardsToReveal, filter); + if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + controller.revealCards(sourceObject.getIdName(), new CardsImpl(target.getTargets()), game); + int unboost = target.getTargets().size() * -1; + ContinuousEffect effect = new BoostTargetEffect(unboost, unboost, Duration.EndOfTurn); + effect.setTargetPointer(getTargetPointer()); + game.addEffect(effect, source); + } + } + return true; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/AddCombatAndMainPhaseEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AddCombatAndMainPhaseEffect.java new file mode 100644 index 0000000000..c2fee30b9c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/AddCombatAndMainPhaseEffect.java @@ -0,0 +1,126 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.effects.common; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TurnPhase; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.turn.TurnMod; + +/** + * + * @author LevelX2 + */ +public class AddCombatAndMainPhaseEffect extends OneShotEffect { + + public AddCombatAndMainPhaseEffect() { + super(Outcome.Benefit); + staticText = "After this main phase, there is an additional combat phase followed by an additional main phase"; + } + + public AddCombatAndMainPhaseEffect(final AddCombatAndMainPhaseEffect effect) { + super(effect); + } + + @Override + public AddCombatAndMainPhaseEffect copy() { + return new AddCombatAndMainPhaseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + // 15.07.2006 If it's somehow not a main phase when Fury of the Horde resolves, all it does is untap all creatures that attacked that turn. No new phases are created. + if (TurnPhase.PRECOMBAT_MAIN.equals(game.getTurn().getPhaseType()) + || TurnPhase.POSTCOMBAT_MAIN.equals(game.getTurn().getPhaseType())) { + // we can't add two turn modes at once, will add additional post combat on delayed trigger resolution + TurnMod combat = new TurnMod(source.getControllerId(), TurnPhase.COMBAT, TurnPhase.POSTCOMBAT_MAIN, false); + game.getState().getTurnMods().add(combat); + DelayedAddMainPhaseAbility delayedTriggeredAbility = new DelayedAddMainPhaseAbility(); + delayedTriggeredAbility.setConnectedTurnMod(combat.getId()); + game.addDelayedTriggeredAbility(delayedTriggeredAbility, source); + return true; + } + return false; + } + +} + +class DelayedAddMainPhaseAbility extends DelayedTriggeredAbility { + + private UUID connectedTurnMod; + private boolean enabled; + + public DelayedAddMainPhaseAbility() { + super(null, Duration.EndOfTurn); + this.usesStack = false; // don't show this to the user + } + + public DelayedAddMainPhaseAbility(DelayedAddMainPhaseAbility ability) { + super(ability); + this.connectedTurnMod = ability.connectedTurnMod; + this.enabled = ability.enabled; + } + + @Override + public DelayedAddMainPhaseAbility copy() { + return new DelayedAddMainPhaseAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.PHASE_CHANGED || event.getType() == GameEvent.EventType.COMBAT_PHASE_PRE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.PHASE_CHANGED && this.connectedTurnMod.equals(event.getSourceId())) { + enabled = true; + } + if (event.getType() == GameEvent.EventType.COMBAT_PHASE_PRE && enabled) { + // add additional post combat main phase after that - after phase == null because add it after this combat + game.getState().getTurnMods().add(new TurnMod(getControllerId(), TurnPhase.POSTCOMBAT_MAIN, null, false)); + enabled = false; + } + return false; + } + + public void setConnectedTurnMod(UUID connectedTurnMod) { + this.connectedTurnMod = connectedTurnMod; + } + + @Override + public String getRule() { + return "add additional post combat main phase"; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java new file mode 100644 index 0000000000..512addc459 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.effects.common; + +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; +import mage.watchers.common.AttackedThisTurnWatcher; + +/** + * !!!! This effect needs the adding of the watcher in the using card class + * + * this.getSpellAbility().addWatcher(new AttackedThisTurnWatcher()); + * + * @author LevelX2 + */ +public class UntapAllThatAttackedEffect extends OneShotEffect { + + public UntapAllThatAttackedEffect() { + super(Outcome.Benefit); + staticText = " Untap all creatures that attacked this turn"; + } + + public UntapAllThatAttackedEffect(final UntapAllThatAttackedEffect effect) { + super(effect); + } + + @Override + public UntapAllThatAttackedEffect copy() { + return new UntapAllThatAttackedEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Watcher watcher = game.getState().getWatchers().get("AttackedThisTurn"); + if (watcher != null && watcher instanceof AttackedThisTurnWatcher) { + Set attackedThisTurn = ((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures(); + for (UUID uuid : attackedThisTurn) { + Permanent permanent = game.getPermanent(uuid); + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { + permanent.untap(game); + } + } + return true; + } + return false; + } + +} diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index a5a4fd5599..3319b6fdff 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -35,7 +35,6 @@ Clash Pack|CLASH| Commander's Arsenal|CMA| Commander|CMD| Conspiracy: Take the Crown|CN2| -Conspiracy|CNS| Conflux|CON| Champs|CP| Coldsnap|CSP| @@ -106,6 +105,7 @@ Magic 2012|M12| Magic 2013|M13| Magic 2014|M14| Magic 2015|M15| +Magic: The Gathering-Conspiracy|CNS| Media Inserts|MBP| Mirrodin Besieged|MBS| Masters Edition II|ME2|