mirror of
https://github.com/correl/mage.git
synced 2024-11-24 19:19:56 +00:00
* 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:
parent
e1f6d72ee9
commit
85bc7549fa
13 changed files with 595 additions and 419 deletions
|
@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
151
Mage.Sets/src/mage/sets/conspiracy/CustodiSquire.java
Normal file
151
Mage.Sets/src/mage/sets/conspiracy/CustodiSquire.java
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
68
Mage.Sets/src/mage/sets/odyssey/SeizeTheDay.java
Normal file
68
Mage.Sets/src/mage/sets/odyssey/SeizeTheDay.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
131
Mage.Sets/src/mage/sets/timespiral/NightshadeAssassin.java
Normal file
131
Mage.Sets/src/mage/sets/timespiral/NightshadeAssassin.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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|
|
||||||
|
|
Loading…
Reference in a new issue