* Added Custodi Squire (2 votes), Nightshade Assassin (2 votes), Seize the Day (2 votes) from the Card Requests - JUNE list.

This commit is contained in:
LevelX2 2016-06-04 12:21:47 +02:00
parent e1f6d72ee9
commit 85bc7549fa
13 changed files with 595 additions and 419 deletions

View file

@ -27,29 +27,18 @@
*/ */
package mage.sets.coldsnap; package mage.sets.coldsnap;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.costs.AlternativeCostSourceAbility; import mage.abilities.costs.AlternativeCostSourceAbility;
import mage.abilities.costs.common.ExileFromHandCost; 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.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.TurnPhase;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate; 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.target.common.TargetCardInHand;
import mage.watchers.Watcher;
import mage.watchers.common.AttackedThisTurnWatcher; import mage.watchers.common.AttackedThisTurnWatcher;
/** /**
@ -72,8 +61,8 @@ public class FuryOfTheHorde extends CardImpl {
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(2, filter)))); 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. // 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 UntapAllThatAttackedEffect());
this.getSpellAbility().addEffect(new FuryOfTheHordeAddPhasesEffect()); this.getSpellAbility().addEffect(new AddCombatAndMainPhaseEffect());
this.getSpellAbility().addWatcher(new AttackedThisTurnWatcher()); this.getSpellAbility().addWatcher(new AttackedThisTurnWatcher());
} }
@ -87,120 +76,3 @@ public class FuryOfTheHorde extends CardImpl {
return new FuryOfTheHorde(this); 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<UUID> 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";
}
}

View file

@ -94,10 +94,10 @@ class BiteOfTheBlackRoseEffect extends OneShotEffect {
if (player != null) { if (player != null) {
if (player.chooseUse(Outcome.ExtraTurn, "Choose sickness?", source, game)) { if (player.chooseUse(Outcome.ExtraTurn, "Choose sickness?", source, game)) {
sicknessCount++; sicknessCount++;
game.informPlayers(player.getLogName() + " has chosen: sickness"); game.informPlayers(player.getLogName() + " has voted for sickness");
} else { } else {
psychosisCount++; psychosisCount++;
game.informPlayers(player.getLogName() + " has chosen: psychosis"); game.informPlayers(player.getLogName() + " has voted for psychosis");
} }
} }
} }

View file

@ -94,11 +94,10 @@ class CoercivePortalEffect extends OneShotEffect {
if (player != null) { if (player != null) {
if (player.chooseUse(Outcome.DestroyPermanent, "Choose carnage?", source, game)) { if (player.chooseUse(Outcome.DestroyPermanent, "Choose carnage?", source, game)) {
carnageCount++; carnageCount++;
game.informPlayers(player.getLogName() + " has chosen: carnage"); game.informPlayers(player.getLogName() + " has voted for carnage");
} } else {
else {
homageCount++; homageCount++;
game.informPlayers(player.getLogName() + " has chosen: homage"); game.informPlayers(player.getLogName() + " has voted for homage");
} }
} }
} }

View file

@ -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 = "<i>Will of the council</i> - 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<UUID, Integer> 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;
}
}

View file

@ -49,6 +49,7 @@ import mage.target.TargetSpell;
public class SplitDecision extends CardImpl { public class SplitDecision extends CardImpl {
private static final FilterSpell filter = new FilterSpell("instant or sorcery spell"); private static final FilterSpell filter = new FilterSpell("instant or sorcery spell");
static { static {
filter.add(Predicates.or( filter.add(Predicates.or(
new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.INSTANT),
@ -101,10 +102,10 @@ class SplitDecisionEffect extends OneShotEffect {
if (player != null) { if (player != null) {
if (player.chooseUse(Outcome.ExtraTurn, "Choose denial?", source, game)) { if (player.chooseUse(Outcome.ExtraTurn, "Choose denial?", source, game)) {
denialCount++; denialCount++;
game.informPlayers(player.getLogName() + " has chosen: denial"); game.informPlayers(player.getLogName() + " has voted for denial");
} else { } else {
duplicationCount++; duplicationCount++;
game.informPlayers(player.getLogName() + " has chosen: duplication"); game.informPlayers(player.getLogName() + " has voted for duplication");
} }
} }
} }

View file

@ -90,11 +90,10 @@ class TyrantsChoiceEffect extends OneShotEffect {
if (player != null) { if (player != null) {
if (player.chooseUse(Outcome.Sacrifice, "Choose death?", source, game)) { if (player.chooseUse(Outcome.Sacrifice, "Choose death?", source, game)) {
deathCount++; deathCount++;
game.informPlayers(player.getLogName() + " has chosen: death"); game.informPlayers(player.getLogName() + " has voted for death");
} } else {
else {
tortureCount++; tortureCount++;
game.informPlayers(player.getLogName() + " has chosen: torture"); game.informPlayers(player.getLogName() + " has voted for torture");
} }
} }
} }

View file

@ -27,24 +27,13 @@
*/ */
package mage.sets.eventide; package mage.sets.eventide;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.effects.common.AddCombatAndMainPhaseEffect;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.effects.common.UntapAllThatAttackedEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.RetraceAbility; import mage.abilities.keyword.RetraceAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity; 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; 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. // 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().addWatcher(new AttackedThisTurnWatcher());
this.getSpellAbility().addEffect(new WavesOfAggressionUntapEffect()); this.getSpellAbility().addEffect(new UntapAllThatAttackedEffect());
this.getSpellAbility().addEffect(new WavesOfAggressionAddPhasesEffect()); this.getSpellAbility().addEffect(new AddCombatAndMainPhaseEffect());
// Retrace // Retrace
this.addAbility(new RetraceAbility(this)); this.addAbility(new RetraceAbility(this));
} }
@ -74,117 +63,3 @@ public class WavesOfAggression extends CardImpl {
return new WavesOfAggression(this); 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<UUID> 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";
}
}

View file

@ -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);
}
}

View file

@ -27,23 +27,12 @@
*/ */
package mage.sets.seventhedition; package mage.sets.seventhedition;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.effects.common.AddCombatAndMainPhaseEffect;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.effects.common.UntapAllThatAttackedEffect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity; 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; 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. // 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().addWatcher(new AttackedThisTurnWatcher());
this.getSpellAbility().addEffect(new RelentlessAssaultUntapEffect()); this.getSpellAbility().addEffect(new UntapAllThatAttackedEffect());
this.getSpellAbility().addEffect(new RelentlessAssaultAddPhasesEffect()); this.getSpellAbility().addEffect(new AddCombatAndMainPhaseEffect());
} }
public RelentlessAssault(final RelentlessAssault card) { public RelentlessAssault(final RelentlessAssault card) {
@ -71,118 +60,3 @@ public class RelentlessAssault extends CardImpl {
return new RelentlessAssault(this); 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<UUID> 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";
}
}

View file

@ -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;
}
}

View file

@ -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";
}
}

View file

@ -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<UUID> 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;
}
}

View file

@ -35,7 +35,6 @@ Clash Pack|CLASH|
Commander's Arsenal|CMA| Commander's Arsenal|CMA|
Commander|CMD| Commander|CMD|
Conspiracy: Take the Crown|CN2| Conspiracy: Take the Crown|CN2|
Conspiracy|CNS|
Conflux|CON| Conflux|CON|
Champs|CP| Champs|CP|
Coldsnap|CSP| Coldsnap|CSP|
@ -106,6 +105,7 @@ Magic 2012|M12|
Magic 2013|M13| Magic 2013|M13|
Magic 2014|M14| Magic 2014|M14|
Magic 2015|M15| Magic 2015|M15|
Magic: The Gathering-Conspiracy|CNS|
Media Inserts|MBP| Media Inserts|MBP|
Mirrodin Besieged|MBS| Mirrodin Besieged|MBS|
Masters Edition II|ME2| Masters Edition II|ME2|