mirror of
https://github.com/magefree/mage.git
synced 2025-12-24 20:41:58 -08:00
Merge branch 'master' into Network_Upgrade
This commit is contained in:
commit
1a6e0e5d09
102 changed files with 1055 additions and 1002 deletions
|
|
@ -104,15 +104,15 @@ class EtherwroughtPageEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player you = game.getPlayer(source.getControllerId());
|
||||
if (you != null && you.getLibrary().size() > 0) {
|
||||
Card card = you.getLibrary().getFromTop(game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null && controller.getLibrary().size() > 0) {
|
||||
Card card = controller.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
CardsImpl cards = new CardsImpl();
|
||||
cards.add(card);
|
||||
you.lookAtCards("Etherwrought Page", cards, game);
|
||||
if (you.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) {
|
||||
return card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
controller.lookAtCards("Etherwrought Page", cards, game);
|
||||
if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) {
|
||||
return controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,9 +104,7 @@ class MindFuneralEffect extends OneShotEffect {
|
|||
cards.add(card);
|
||||
}
|
||||
opponent.revealCards("Mind Funeral", cards, game);
|
||||
for (Card card: cards.getCards(game)) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
opponent.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ import mage.cards.CardImpl;
|
|||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.target.common.TargetCreatureOrPlayer;
|
||||
|
||||
|
|
@ -55,12 +54,11 @@ public class VengefulRebirth extends CardImpl {
|
|||
super(ownerId, 62, "Vengeful Rebirth", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{4}{R}{G}");
|
||||
this.expansionSetCode = "ARB";
|
||||
|
||||
|
||||
// Return target card from your graveyard to your hand. If you return a nonland card to your hand this way, {this} deals damage equal to that card's converted mana cost to target creature or player
|
||||
Target target = new TargetCardInYourGraveyard();
|
||||
this.getSpellAbility().addTarget(target);
|
||||
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard());
|
||||
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
|
||||
this.getSpellAbility().addEffect(new VengefulRebirthEffect());
|
||||
|
||||
// Exile Vengeful Rebirth.
|
||||
this.getSpellAbility().addEffect(ExileSpellEffect.getInstance());
|
||||
}
|
||||
|
|
@ -73,7 +71,6 @@ public class VengefulRebirth extends CardImpl {
|
|||
public VengefulRebirth copy() {
|
||||
return new VengefulRebirth(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class VengefulRebirthEffect extends OneShotEffect {
|
||||
|
|
@ -94,17 +91,17 @@ class VengefulRebirthEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Card card = (Card)game.getObject(source.getFirstTarget());
|
||||
if (player != null && card != null && player.removeFromGraveyard(card, game)) {
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
|
||||
if (controller != null && card != null && controller.removeFromGraveyard(card, game)) {
|
||||
controller.moveCards(card, Zone.GRAVEYARD, Zone.HAND, source, game);
|
||||
if (!card.getCardType().contains(CardType.LAND)) {
|
||||
int damage = card.getManaCost().convertedManaCost();
|
||||
Permanent permanent = game.getPermanent(source.getTargets().get(1).getTargets().get(0));
|
||||
int damage = card.getManaCost().convertedManaCost();
|
||||
Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
|
||||
if (permanent != null) {
|
||||
permanent.damage(damage, source.getSourceId(), game, false, true);
|
||||
}
|
||||
Player targetPlayer = game.getPlayer(source.getTargets().get(1).getTargets().get(0));
|
||||
Player targetPlayer = game.getPlayer(source.getTargets().get(1).getFirstTarget());
|
||||
if (targetPlayer != null) {
|
||||
targetPlayer.damage(damage, source.getSourceId(), game, false, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public class HelmOfObedience extends CardImpl {
|
|||
super(ownerId, 163, "Helm of Obedience", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{4}");
|
||||
this.expansionSetCode = "ALL";
|
||||
|
||||
// {X}, {tap}: Target opponent puts cards from the top of his or her library into his or her graveyard until a creature card or X cards are put into that graveyard this way, whichever comes first. If a creature card is put into that graveyard this way, sacrifice Helm of Obedience and put that card onto the battlefield under your control. X can't be 0.
|
||||
// {X}, {T}: Target opponent puts cards from the top of his or her library into his or her graveyard until a creature card or X cards are put into that graveyard this way, whichever comes first. If a creature card is put into that graveyard this way, sacrifice Helm of Obedience and put that card onto the battlefield under your control. X can't be 0.
|
||||
VariableManaCost xCosts = new VariableManaCost();
|
||||
xCosts.setMinX(1);
|
||||
SimpleActivatedAbility abilitiy = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HelmOfObedienceEffect(), xCosts);
|
||||
|
|
@ -106,28 +106,26 @@ class HelmOfObedienceEffect extends OneShotEffect {
|
|||
while(player.getLibrary().size() > 0) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null){
|
||||
if(card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false)){
|
||||
if(card.getCardType().contains(CardType.CREATURE)){
|
||||
// If a creature card is put into that graveyard this way, sacrifice Helm of Obedience
|
||||
// and put that card onto the battlefield under your control.
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
if (sourcePermanent != null) {
|
||||
sourcePermanent.sacrifice(source.getSourceId(), game);
|
||||
}
|
||||
if (game.getState().getZone(card.getId()).equals(Zone.GRAVEYARD)) {
|
||||
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
|
||||
}
|
||||
player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
if(card.getCardType().contains(CardType.CREATURE)){
|
||||
// If a creature card is put into that graveyard this way, sacrifice Helm of Obedience
|
||||
// and put that card onto the battlefield under your control.
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
if (sourcePermanent != null) {
|
||||
sourcePermanent.sacrifice(source.getSourceId(), game);
|
||||
}
|
||||
if (game.getState().getZone(card.getId()).equals(Zone.GRAVEYARD)) {
|
||||
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
else{
|
||||
numberOfCard++;
|
||||
if(numberOfCard >= max){
|
||||
break;
|
||||
}
|
||||
else{
|
||||
numberOfCard++;
|
||||
if(numberOfCard >= max){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,32 +94,26 @@ class SatyrWayfinderEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (player != null && sourceObject != null) {
|
||||
if (controller != null && sourceObject != null) {
|
||||
Cards cards = new CardsImpl(Zone.LIBRARY);
|
||||
cards.addAll(player.getLibrary().getTopCards(game, 4));
|
||||
cards.addAll(controller.getLibrary().getTopCards(game, 4));
|
||||
boolean properCardFound = cards.count(filterPutInHand, source.getControllerId(), source.getSourceId(), game) > 0;
|
||||
if (!cards.isEmpty()) {
|
||||
player.revealCards(sourceObject.getName(), cards, game);
|
||||
controller.revealCards(sourceObject.getName(), cards, game);
|
||||
TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand);
|
||||
if (properCardFound &&
|
||||
player.chooseUse(outcome, "Put a land card into your hand?", game) &&
|
||||
player.choose(Outcome.DrawCard, cards, target, game)) {
|
||||
controller.chooseUse(outcome, "Put a land card into your hand?", game) &&
|
||||
controller.choose(Outcome.DrawCard, cards, target, game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
cards.remove(card);
|
||||
player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
|
||||
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
|||
import mage.abilities.effects.SearchEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
|
|
@ -99,12 +101,7 @@ class InameDeathAspectEffect extends SearchEffect {
|
|||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null && player.searchLibrary(target, game)) {
|
||||
if (target.getTargets().size() > 0) {
|
||||
for (UUID cardId: target.getTargets()) {
|
||||
Card card = player.getLibrary().remove(cardId, game);
|
||||
if (card != null){
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
player.moveCards(new CardsImpl(target.getTargets()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -29,23 +29,13 @@ package mage.sets.championsofkamigawa;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.abilities.effects.common.continuous.GainProtectionFromColorSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Rarity;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterSpiritOrArcaneCard;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -77,62 +67,3 @@ public class KamiOfThePaintedRoad extends CardImpl {
|
|||
return new KamiOfThePaintedRoad(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GainProtectionFromColorSourceEffect extends GainAbilitySourceEffect {
|
||||
|
||||
FilterCard protectionFilter;
|
||||
|
||||
public GainProtectionFromColorSourceEffect(Duration duration) {
|
||||
super(new ProtectionAbility(new FilterCard()), duration);
|
||||
protectionFilter = (FilterCard)((ProtectionAbility)ability).getFilter();
|
||||
}
|
||||
|
||||
public GainProtectionFromColorSourceEffect(final GainProtectionFromColorSourceEffect effect) {
|
||||
super(effect);
|
||||
this.protectionFilter = effect.protectionFilter.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GainProtectionFromColorSourceEffect copy() {
|
||||
return new GainProtectionFromColorSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ChoiceColor colorChoice = new ChoiceColor(true);
|
||||
colorChoice.setMessage("Choose color for protection ability");
|
||||
while (!colorChoice.isChosen()) {
|
||||
controller.choose(outcome, colorChoice, game);
|
||||
if (!controller.isInGame()) {
|
||||
discard();
|
||||
return;
|
||||
}
|
||||
}
|
||||
protectionFilter.add(new ColorPredicate(colorChoice.getColor()));
|
||||
protectionFilter.setMessage(colorChoice.getChoice());
|
||||
((ProtectionAbility)ability).setFilter(protectionFilter);
|
||||
return;
|
||||
}
|
||||
discard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null && new MageObjectReference(permanent, game).refersTo(source.getSourceObject(game), game)) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
} else {
|
||||
// the source permanent is no longer on the battlefield, effect can be discarded
|
||||
discard();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "{this} gains protection from the color of your choice " + duration.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,13 @@
|
|||
*/
|
||||
package mage.sets.commander;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.SearchEffect;
|
||||
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;
|
||||
|
|
@ -87,19 +88,12 @@ class BuriedAliveEffect extends SearchEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
if (player.searchLibrary(target, game)) {
|
||||
if (target.getTargets().size() > 0) {
|
||||
for (UUID cardId: target.getTargets()) {
|
||||
Card card = player.getLibrary().remove(cardId, game);
|
||||
if (card != null){
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
if (controller.searchLibrary(target, game)) {
|
||||
controller.moveCards(new CardsImpl(target.getTargets()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
controller.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -84,11 +84,9 @@ public class SzadekLordOfSecrets extends CardImpl {
|
|||
|
||||
class SzadekLordOfSecretsEffect extends ReplacementEffectImpl {
|
||||
|
||||
List<Card> cards;
|
||||
|
||||
SzadekLordOfSecretsEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "If {this} would deal combat damage to a player, instead put that many +1/+1 counters on Szadek and that player puts that many cards from the top of his or her library into his or her graveyard";
|
||||
staticText = "If {this} would deal combat damage to a player, instead put that many +1/+1 counters on {this} and that player puts that many cards from the top of his or her library into his or her graveyard";
|
||||
}
|
||||
|
||||
SzadekLordOfSecretsEffect(final SzadekLordOfSecretsEffect effect) {
|
||||
|
|
@ -101,24 +99,25 @@ class SzadekLordOfSecretsEffect extends ReplacementEffectImpl {
|
|||
Player damagedPlayer = game.getPlayer(damageEvent.getTargetId());
|
||||
|
||||
if (damageEvent.isCombatDamage()) {
|
||||
Permanent p = game.getPermanent(source.getSourceId());
|
||||
if (p != null) {
|
||||
p.addCounters(CounterType.P1P1.createInstance(damageEvent.getAmount()), game);
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(damageEvent.getAmount()), game);
|
||||
if (damagedPlayer != null) {
|
||||
cards = damagedPlayer.getLibrary().getTopCards(game, damageEvent.getAmount());
|
||||
}
|
||||
for (Card card : cards) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
damagedPlayer.moveCards(damagedPlayer.getLibrary().getTopCards(game, damageEvent.getAmount()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.DAMAGE_PLAYER
|
||||
&& event.getSourceId().equals(source.getSourceId())) {
|
||||
if (event.getSourceId().equals(source.getSourceId())) {
|
||||
DamagePlayerEvent damageEvent = (DamagePlayerEvent) event;
|
||||
if (damageEvent.isCombatDamage()) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import mage.game.Game;
|
|||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -136,6 +137,9 @@ class EndrekSahrMasterBreederEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source));
|
||||
if (spell == null) {
|
||||
spell = (Spell) game.getLastKnownInformation(((FixedTarget)getTargetPointer()).getTarget(), Zone.STACK);
|
||||
}
|
||||
if (spell != null) {
|
||||
int cmc = spell.getConvertedManaCost();
|
||||
if (cmc > 0) {
|
||||
|
|
|
|||
|
|
@ -86,34 +86,22 @@ class StrategicPlanningEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
|
||||
if (player != null) {
|
||||
Cards cards = new CardsImpl(Zone.PICK);
|
||||
int cardsCount = Math.min(3, player.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
game.setZone(card.getId(), Zone.PICK);
|
||||
}
|
||||
}
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
|
||||
if (controller != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.addAll(controller.getLibrary().getTopCards(game, 3));
|
||||
if (cards.size() > 0) {
|
||||
player.lookAtCards("Strategic Planning", cards, game);
|
||||
|
||||
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put in your hand"));
|
||||
if (player.choose(Outcome.Benefit, cards, target, game)) {
|
||||
controller.lookAtCards("Strategic Planning", cards, game);
|
||||
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put in your hand"));
|
||||
if (controller.choose(Outcome.Benefit, cards, target, game)) {
|
||||
Card card = cards.get(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
|
||||
cards.remove(card);
|
||||
}
|
||||
}
|
||||
|
||||
for (Card card : cards.getCards(game)) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,12 +99,12 @@ class TeleminPerformanceEffect extends OneShotEffect {
|
|||
}
|
||||
if (!creatureFound) {
|
||||
cards.add(card);
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cards.isEmpty()) {
|
||||
if (!cards.isEmpty()) {
|
||||
opponent.revealCards("Telemin Performance", cards, game);
|
||||
opponent.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
if (creature != null) {
|
||||
return creature.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId());
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ public class ChillOfForeboding extends CardImpl {
|
|||
super(ownerId, 32, "Chill of Foreboding", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{U}");
|
||||
this.expansionSetCode = "DKA";
|
||||
|
||||
|
||||
// Each player puts the top five cards of his or her library into his or her graveyard.
|
||||
this.getSpellAbility().addEffect(new ChillOfForebodingEffect());
|
||||
// Flashback {7}{U}
|
||||
|
|
@ -92,13 +91,7 @@ class ChillOfForebodingEffect extends OneShotEffect {
|
|||
for (UUID playerId : sourcePlayer.getInRange()) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
int count = Math.min(5, player.getLibrary().size());
|
||||
for (int i = 0; i < count; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
player.moveCards(player.getLibrary().getTopCards(game, 5), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ import mage.game.permanent.Permanent;
|
|||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
|
|
@ -108,18 +107,21 @@ class CurseOfEchoesCopyTriggeredAbility extends TriggeredAbilityImpl {
|
|||
return new CurseOfEchoesCopyTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.SPELL_CAST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (spell != null && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) {
|
||||
Permanent enchantment = game.getPermanent(sourceId);
|
||||
if (enchantment != null && enchantment.getAttachedTo() != null) {
|
||||
Player player = game.getPlayer(enchantment.getAttachedTo());
|
||||
if (player != null && spell.getControllerId().equals(player.getId())) {
|
||||
this.getEffects().get(0).setTargetPointer(new FixedTarget(spell.getId()));
|
||||
return true;
|
||||
}
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (spell != null && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) {
|
||||
Permanent enchantment = game.getPermanent(sourceId);
|
||||
if (enchantment != null && enchantment.getAttachedTo() != null) {
|
||||
Player player = game.getPlayer(enchantment.getAttachedTo());
|
||||
if (player != null && spell.getControllerId().equals(player.getId())) {
|
||||
this.getEffects().get(0).setTargetPointer(new FixedTarget(spell.getId()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class IncreasingConfusionEffect extends OneShotEffect {
|
|||
|
||||
public IncreasingConfusionEffect() {
|
||||
super(Outcome.Detriment);
|
||||
staticText = "Target player puts the top X cards of his or her library into his or her graveyard. If Increasing Confusion was cast from a graveyard, that player puts twice that many cards into his or her graveyard instead";
|
||||
staticText = "Target player puts the top X cards of his or her library into his or her graveyard. If {this} was cast from a graveyard, that player puts twice that many cards into his or her graveyard instead";
|
||||
}
|
||||
|
||||
public IncreasingConfusionEffect(final IncreasingConfusionEffect effect) {
|
||||
|
|
@ -91,15 +91,7 @@ class IncreasingConfusionEffect extends OneShotEffect {
|
|||
if (spell.getFromZone() == Zone.GRAVEYARD) {
|
||||
amount *= 2;
|
||||
}
|
||||
Card card;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,14 +91,14 @@ class TrackersInstinctsEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Cards cards = new CardsImpl(Zone.PICK);
|
||||
|
||||
boolean creaturesFound = false;
|
||||
int count = Math.min(player.getLibrary().size(), 4);
|
||||
int count = Math.min(controller.getLibrary().size(), 4);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
Card card = controller.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
if (card.getCardType().contains(CardType.CREATURE)) {
|
||||
|
|
@ -108,9 +108,9 @@ class TrackersInstinctsEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (!cards.isEmpty()) {
|
||||
player.revealCards("Tracker's Instincts", cards, game);
|
||||
TargetCard target = new TargetCard(Zone.PICK, new FilterCreatureCard("creature card to put in hand"));
|
||||
if (creaturesFound && player.choose(Outcome.DrawCard, cards, target, game)) {
|
||||
controller.revealCards("Tracker's Instincts", cards, game);
|
||||
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCreatureCard("creature card to put in hand"));
|
||||
if (creaturesFound && controller.choose(Outcome.DrawCard, cards, target, game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
cards.remove(card);
|
||||
|
|
@ -118,13 +118,7 @@ class TrackersInstinctsEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import mage.constants.Outcome;
|
|||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -99,8 +100,8 @@ class MirkoVoskMindDrinkerEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (player == null || sourceCard == null) {
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (player == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
int landsToReveal = 4;
|
||||
|
|
@ -117,12 +118,8 @@ class MirkoVoskMindDrinkerEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
player.revealCards("by " + sourceCard.getName() + " from " + player.getName(), cards, game);
|
||||
for(Card card : cards.getCards(game)){
|
||||
if(card != null){
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
player.revealCards("by " + sourceObject.getName() + " from " + player.getName(), cards, game);
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,27 +29,18 @@ package mage.sets.dragonsoftarkir;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.effects.common.UntapSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.effects.common.continuous.GainProtectionFromColorSourceEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Rarity;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -88,62 +79,3 @@ public class PristineSkywise extends CardImpl {
|
|||
return new PristineSkywise(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GainProtectionFromColorSourceEffect extends GainAbilitySourceEffect {
|
||||
|
||||
FilterCard protectionFilter;
|
||||
|
||||
public GainProtectionFromColorSourceEffect(Duration duration) {
|
||||
super(new ProtectionAbility(new FilterCard()), duration);
|
||||
protectionFilter = (FilterCard)((ProtectionAbility)ability).getFilter();
|
||||
}
|
||||
|
||||
public GainProtectionFromColorSourceEffect(final GainProtectionFromColorSourceEffect effect) {
|
||||
super(effect);
|
||||
this.protectionFilter = effect.protectionFilter.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GainProtectionFromColorSourceEffect copy() {
|
||||
return new GainProtectionFromColorSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ChoiceColor colorChoice = new ChoiceColor(true);
|
||||
colorChoice.setMessage("Choose color for protection ability");
|
||||
while (!colorChoice.isChosen()) {
|
||||
controller.choose(outcome, colorChoice, game);
|
||||
if (!controller.isInGame()) {
|
||||
discard();
|
||||
return;
|
||||
}
|
||||
}
|
||||
protectionFilter.add(new ColorPredicate(colorChoice.getColor()));
|
||||
protectionFilter.setMessage(colorChoice.getChoice());
|
||||
((ProtectionAbility)ability).setFilter(protectionFilter);
|
||||
return;
|
||||
}
|
||||
discard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null && new MageObjectReference(permanent, game).refersTo(source.getSourceObject(game), game)) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
} else {
|
||||
// the source permanent is no longer on the battlefield, effect can be discarded
|
||||
discard();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "{this} gains protection from the color of your choice " + duration.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class SanityGrindingEffect extends OneShotEffect {
|
|||
|
||||
public SanityGrindingEffect() {
|
||||
super(Outcome.Neutral);
|
||||
staticText = "<i>Chroma</i> - Reveal the top ten cards of your library. For each blue mana symbol in the mana costs of the revealed cards, target opponent puts the top card of his or her library into his or her graveyard. Then put the cards you revealed this way on the bottom of your library in any order";
|
||||
staticText = "<i>Chroma</i> — Reveal the top ten cards of your library. For each blue mana symbol in the mana costs of the revealed cards, target opponent puts the top card of his or her library into his or her graveyard. Then put the cards you revealed this way on the bottom of your library in any order";
|
||||
}
|
||||
|
||||
public SanityGrindingEffect(final SanityGrindingEffect effect) {
|
||||
|
|
@ -87,24 +87,22 @@ class SanityGrindingEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player targetOpponent = game.getPlayer(source.getFirstTarget());
|
||||
Player you = game.getPlayer(source.getControllerId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Cards revealed = new CardsImpl();
|
||||
int amount;
|
||||
if (you == null) {
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
amount = (Math.min(10, you.getLibrary().size()));
|
||||
amount = (Math.min(10, controller.getLibrary().size()));
|
||||
for (int i = 0; i < amount; i++) {
|
||||
revealed.add(you.getLibrary().removeFromTop(game));
|
||||
revealed.add(controller.getLibrary().removeFromTop(game));
|
||||
}
|
||||
you.revealCards("Sanity Grinding", revealed, game);
|
||||
controller.revealCards("Sanity Grinding", revealed, game);
|
||||
if (targetOpponent != null) {
|
||||
amount = (Math.min(targetOpponent.getLibrary().size(), new ChromaSanityGrindingCount(revealed).calculate(game, source, this)));
|
||||
for (int i = 0; i < amount; i++) {
|
||||
targetOpponent.getLibrary().removeFromTop(game).moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
targetOpponent.moveCards(targetOpponent.getLibrary().getTopCards(game, new ChromaSanityGrindingCount(revealed).calculate(game, source, this)),
|
||||
Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return you.putCardsOnBottomOfLibrary(revealed, game, source, true);
|
||||
return controller.putCardsOnBottomOfLibrary(revealed, game, source, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -115,7 +113,7 @@ class SanityGrindingEffect extends OneShotEffect {
|
|||
|
||||
class ChromaSanityGrindingCount implements DynamicValue {
|
||||
|
||||
private Cards revealed;
|
||||
private final Cards revealed;
|
||||
|
||||
public ChromaSanityGrindingCount(Cards revealed) {
|
||||
this.revealed = revealed;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ public class ArcanumWings extends CardImpl {
|
|||
this.expansionSetCode = "FUT";
|
||||
this.subtype.add("Aura");
|
||||
|
||||
|
||||
// Enchant creature
|
||||
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||
this.getSpellAbility().addTarget(auraTarget);
|
||||
|
|
|
|||
|
|
@ -114,8 +114,8 @@ class BalustradeSpyEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
if (!cards.isEmpty()) {
|
||||
controller.moveCardsToGraveyardWithInfo(cards, source, game, Zone.LIBRARY);
|
||||
controller.revealCards(sourceObject.getName(), cards, game);
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -108,27 +108,23 @@ class BorborygmosEnragedEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
Cards cards = new CardsImpl(Zone.PICK);
|
||||
int count = Math.min(player.getLibrary().size(), 3);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
game.setZone(card.getId(), Zone.PICK);
|
||||
if (card.getCardType().contains(CardType.LAND)) {
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, true);
|
||||
} else {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.addAll(controller.getLibrary().getTopCards(game, 3));
|
||||
if (!cards.isEmpty()) {
|
||||
player.revealCards("Borborygmous Enraged", cards, game);
|
||||
return true;
|
||||
controller.revealCards("Borborygmous Enraged", cards, game);
|
||||
Cards landCards = new CardsImpl();
|
||||
for(Card card: cards.getCards(game) ) {
|
||||
if (card.getCardType().contains(CardType.LAND)) {
|
||||
landCards.add(card);
|
||||
cards.remove(card);
|
||||
}
|
||||
}
|
||||
controller.moveCards(landCards, Zone.LIBRARY, Zone.HAND, source, game);
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,27 +29,18 @@ package mage.sets.gatecrash;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.abilities.effects.common.continuous.GainProtectionFromColorSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.constants.Duration;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
/**
|
||||
|
|
@ -65,6 +56,7 @@ public class CartelAristocrat extends CardImpl {
|
|||
static {
|
||||
filter.add(new AnotherPredicate());
|
||||
}
|
||||
|
||||
public CartelAristocrat(UUID ownerId) {
|
||||
super(ownerId, 150, "Cartel Aristocrat", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{W}{B}");
|
||||
this.expansionSetCode = "GTC";
|
||||
|
|
@ -75,9 +67,8 @@ public class CartelAristocrat extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// Sacrifice another creature: Cartel Aristocrat gains protection from the color of your choice until end of turn.
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
Zone.BATTLEFIELD, new CartelAristocratEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)));
|
||||
this.addAbility(ability);
|
||||
this.addAbility(new SimpleActivatedAbility(
|
||||
Zone.BATTLEFIELD, new GainProtectionFromColorSourceEffect(Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filter))));
|
||||
}
|
||||
|
||||
public CartelAristocrat(final CartelAristocrat card) {
|
||||
|
|
@ -89,35 +80,3 @@ public class CartelAristocrat extends CardImpl {
|
|||
return new CartelAristocrat(this);
|
||||
}
|
||||
}
|
||||
class CartelAristocratEffect extends OneShotEffect {
|
||||
|
||||
public CartelAristocratEffect() {
|
||||
super(Outcome.Protect);
|
||||
this.staticText = "{this} gains protection from the color of your choice until end of turn";
|
||||
}
|
||||
|
||||
public CartelAristocratEffect(final CartelAristocratEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CartelAristocratEffect copy() {
|
||||
return new CartelAristocratEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
ChoiceColor choice = new ChoiceColor();
|
||||
choice.setMessage("Choose color to get protection from");
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null && controller.choose(outcome, choice, game)) {
|
||||
FilterCard protectionFilter = new FilterCard();
|
||||
protectionFilter.add(new ColorPredicate(choice.getColor()));
|
||||
protectionFilter.setMessage(choice.getChoice().toLowerCase());
|
||||
ContinuousEffect effect = new GainAbilitySourceEffect(new ProtectionAbility(protectionFilter), Duration.EndOfTurn);
|
||||
game.addEffect(effect, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
|
@ -88,16 +90,14 @@ class CoercedConfessionMillEffect extends OneShotEffect {
|
|||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if (player != null) {
|
||||
int foundCreatures = 0;
|
||||
int cardsCount = Math.min(4, player.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
if (card.getCardType().contains(CardType.CREATURE)) {
|
||||
++foundCreatures;
|
||||
}
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
Cards cards = new CardsImpl();
|
||||
for(Card card: player.getLibrary().getTopCards(game, 4)) {
|
||||
cards.add(card);
|
||||
if (card.getCardType().contains(CardType.CREATURE)) {
|
||||
++foundCreatures;
|
||||
}
|
||||
}
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
if (foundCreatures > 0) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
|
|
|
|||
|
|
@ -116,11 +116,7 @@ class ConsumingAberrationEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
player.revealCards("Consuming Aberrtion", cards, game);
|
||||
for(Card card : cards.getCards(game)){
|
||||
if(card != null){
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,20 +122,25 @@ class DiluvianPrimordialEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
for (Target target: source.getTargets()) {
|
||||
if (target instanceof TargetCardInOpponentsGraveyard) {
|
||||
Card targetCard = game.getCard(target.getFirstTarget());
|
||||
if (controller != null && targetCard != null) {
|
||||
if (controller.chooseUse(outcome, "Cast " + targetCard.getName() +"?", game)) {
|
||||
controller.cast(targetCard.getSpellAbility(), game, true);
|
||||
ContinuousEffect effect = new DiluvianPrimordialReplacementEffect();
|
||||
effect.setTargetPointer(new FixedTarget(targetCard.getId()));
|
||||
game.addEffect(effect, source);
|
||||
if (controller != null) {
|
||||
for (Target target: source.getTargets()) {
|
||||
if (target instanceof TargetCardInOpponentsGraveyard) {
|
||||
Card targetCard = game.getCard(target.getFirstTarget());
|
||||
if (targetCard != null) {
|
||||
if (controller.chooseUse(outcome, "Cast " + targetCard.getLogName() +"?", game)) {
|
||||
// TODO: Handle the case if the cast is not possible, so the replacement effect shouldn't be active
|
||||
ContinuousEffect effect = new DiluvianPrimordialReplacementEffect();
|
||||
effect.setTargetPointer(new FixedTarget(targetCard.getId()));
|
||||
game.addEffect(effect, source);
|
||||
|
||||
controller.cast(targetCard.getSpellAbility(), game, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -164,9 +169,9 @@ class DiluvianPrimordialReplacementEffect extends ReplacementEffectImpl {
|
|||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
Card card = game.getCard(((FixedTarget)getTargetPointer()).getTarget());
|
||||
if (card != null) {
|
||||
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.STACK, true);
|
||||
controller.moveCards(card, Zone.STACK, Zone.EXILED, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -181,10 +186,7 @@ class DiluvianPrimordialReplacementEffect extends ReplacementEffectImpl {
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getToZone() == Zone.GRAVEYARD
|
||||
&& ((ZoneChangeEvent) event).getTargetId().equals(getTargetPointer().getFirst(game, source))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return zEvent.getToZone() == Zone.GRAVEYARD
|
||||
&& ((ZoneChangeEvent) event).getTargetId().equals(getTargetPointer().getFirst(game, source));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,19 +123,14 @@ class DimirCharmEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
if(cards.size() > 0){
|
||||
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("Card to put back on top of library"));
|
||||
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("Card to put back on top of library"));
|
||||
if(controller.chooseTarget(Outcome.Benefit, cards, target, source, game)){
|
||||
Card card = cards.get(target.getFirstTarget(), game);
|
||||
if(card != null){
|
||||
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
|
||||
cards.remove(card);
|
||||
}
|
||||
|
||||
for(Card card2 : cards.getCards(game)){
|
||||
if(card2 != null){
|
||||
card2.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,11 +117,7 @@ class MindGrindEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
player.revealCards("by " + sourceCard.getName() + " from " + player.getName(), cards, game);
|
||||
for(Card card : cards.getCards(game)){
|
||||
if(card != null){
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,15 +113,18 @@ class SepulchralPrimordialEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
for (Target target: source.getTargets()) {
|
||||
if (target instanceof TargetCardInOpponentsGraveyard) {
|
||||
Card targetCard = game.getCard(target.getFirstTarget());
|
||||
if (player != null && targetCard != null) {
|
||||
targetCard.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
for (Target target: source.getTargets()) {
|
||||
if (target instanceof TargetCardInOpponentsGraveyard) {
|
||||
Card targetCard = game.getCard(target.getFirstTarget());
|
||||
if (targetCard != null) {
|
||||
targetCard.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,11 +117,7 @@ class UndercityInformerEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
player.revealCards("Undercity Informer", cards, game);
|
||||
for(Card card : cards.getCards(game)){
|
||||
if(card != null){
|
||||
card.moveToZone(Zone.GRAVEYARD, id, game, true);
|
||||
}
|
||||
}
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,36 +70,3 @@ public class ArmoredSkaab extends CardImpl {
|
|||
return new ArmoredSkaab(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ArmoredSkaabEffect extends OneShotEffect {
|
||||
|
||||
public ArmoredSkaabEffect() {
|
||||
super(Outcome.Discard);
|
||||
this.staticText = "put the top four cards of your library into your graveyard";
|
||||
}
|
||||
|
||||
public ArmoredSkaabEffect(final ArmoredSkaabEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmoredSkaabEffect copy() {
|
||||
return new ArmoredSkaabEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
int cardsCount = Math.min(4, player.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ class CellarDoorEffect extends OneShotEffect {
|
|||
if (player != null && player.getLibrary().size() > 0) {
|
||||
Card card = player.getLibrary().removeFromBottom(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
if (card.getCardType().contains(CardType.CREATURE)) {
|
||||
ZombieToken token = new ZombieToken("ISD");
|
||||
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class GhoulcallersBellEffect extends OneShotEffect {
|
|||
if (player.getLibrary().size() > 0) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.sets.innistrad;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -74,7 +75,7 @@ class HereticsPunishmentEffect extends OneShotEffect {
|
|||
|
||||
public HereticsPunishmentEffect() {
|
||||
super(Outcome.Damage);
|
||||
staticText = "Choose target creature or player, then put the top three cards of your library into your graveyard. Heretic's Punishment deals damage to that creature or player equal to the highest converted mana cost among those cards";
|
||||
staticText = "Choose target creature or player, then put the top three cards of your library into your graveyard. {this} deals damage to that creature or player equal to the highest converted mana cost among those cards";
|
||||
}
|
||||
|
||||
public HereticsPunishmentEffect(final HereticsPunishmentEffect effect) {
|
||||
|
|
@ -83,18 +84,17 @@ class HereticsPunishmentEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
int maxCost = 0;
|
||||
for (int i = 0; i < Math.min(3, player.getLibrary().size()); i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
int test = card.getManaCost().convertedManaCost();
|
||||
if (test > maxCost)
|
||||
maxCost = test;
|
||||
}
|
||||
List<Card> cardList = controller.getLibrary().getTopCards(game, 3);
|
||||
for (Card card: cardList) {
|
||||
int test = card.getManaCost().convertedManaCost();
|
||||
if (test > maxCost) {
|
||||
maxCost = test;
|
||||
}
|
||||
}
|
||||
controller.moveCards(cardList, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
if (permanent != null) {
|
||||
permanent.damage(maxCost, source.getSourceId(), game, false, true);
|
||||
|
|
|
|||
|
|
@ -92,16 +92,19 @@ class MindshriekerEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getFirstTarget());
|
||||
if (player != null && player.getLibrary().size() > 0) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
int amount = card.getManaCost().convertedManaCost();
|
||||
if (amount > 0)
|
||||
game.addEffect(new BoostSourceEffect(amount, amount, Duration.EndOfTurn), source);
|
||||
return true;
|
||||
Player targetPlayer = game.getPlayer(source.getFirstTarget());
|
||||
if (targetPlayer != null) {
|
||||
if (targetPlayer.getLibrary().size() > 0) {
|
||||
Card card = targetPlayer.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
targetPlayer.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
int amount = card.getManaCost().convertedManaCost();
|
||||
if (amount > 0) {
|
||||
game.addEffect(new BoostSourceEffect(amount, amount, Duration.EndOfTurn), source);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,8 +98,9 @@ class MirrorMadPhantasmEffect extends OneShotEffect {
|
|||
Cards cards = new CardsImpl();
|
||||
while (true) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card == null)
|
||||
if (card == null) {
|
||||
break;
|
||||
}
|
||||
if (card.getName().equals("Mirror-Mad Phantasm")) {
|
||||
card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId());
|
||||
break;
|
||||
|
|
@ -107,9 +108,7 @@ class MirrorMadPhantasmEffect extends OneShotEffect {
|
|||
cards.add(card);
|
||||
}
|
||||
player.revealCards("Mirror-Mad Phantasm", cards, game);
|
||||
for (Card card: cards.getCards(game)) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ class VoidEffect extends OneShotEffect {
|
|||
targetPlayer.revealCards("Void", targetPlayer.getHand(), game);
|
||||
for (Card card : targetPlayer.getHand().getCards(game)) {
|
||||
if (filterCard.match(card, game)) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
targetPlayer.discard(card, source, game);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public class DroolingGroodion extends CardImpl {
|
|||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DroolingGroodionEffect(), new ManaCostsImpl("{2}{B}{G}"));
|
||||
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(), true)));
|
||||
ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (first target)")));
|
||||
ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (second target)")));
|
||||
ability.addTarget(new TargetOtherCreaturePermanent(new FilterCreaturePermanent("creature (second target)")));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -112,3 +112,28 @@ class DroolingGroodionEffect extends ContinuousEffectImpl {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TargetOtherCreaturePermanent extends TargetCreaturePermanent {
|
||||
|
||||
public TargetOtherCreaturePermanent(FilterCreaturePermanent filter) {
|
||||
super(filter);
|
||||
}
|
||||
|
||||
public TargetOtherCreaturePermanent(final TargetOtherCreaturePermanent target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
|
||||
if (source.getTargets().get(0).getTargets().contains(id)) {
|
||||
return false;
|
||||
}
|
||||
return super.canTarget(controllerId, id, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetOtherCreaturePermanent copy() {
|
||||
return new TargetOtherCreaturePermanent(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,17 +105,9 @@ class SearchLibraryPutInGraveEffect extends SearchEffect {
|
|||
}
|
||||
if (player.searchLibrary(target, game)) {
|
||||
if (target.getTargets().size() > 0) {
|
||||
Cards cards = new CardsImpl();
|
||||
for (UUID cardId: (List<UUID>)target.getTargets()) {
|
||||
Card card = player.getLibrary().remove(cardId, game);
|
||||
if (card != null){
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
cards.add(card);
|
||||
}
|
||||
}
|
||||
if (cards.size() > 0) {
|
||||
player.revealCards("Quiet Speculation", cards, game);
|
||||
}
|
||||
Cards cards = new CardsImpl(target.getTargets());
|
||||
player.revealCards("Quiet Speculation", cards, game);
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ package mage.sets.khansoftarkir;
|
|||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.ZoneChangeTriggeredAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -41,9 +40,8 @@ import mage.constants.Zone;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.events.ZoneChangeGroupEvent;
|
||||
import mage.game.permanent.token.ZombieToken;
|
||||
import mage.game.stack.StackObject;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -102,58 +100,38 @@ class SidisiBroodTyrantAbility extends TriggeredAbilityImpl {
|
|||
if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId())) {
|
||||
return true;
|
||||
}
|
||||
if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever {this} enters the battlefield or attacks, put the top three cards of your library into your graveyard.";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SidisiBroodTyrantTriggeredAbility extends ZoneChangeTriggeredAbility {
|
||||
|
||||
UUID lastStackObjectId = null;
|
||||
class SidisiBroodTyrantTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public SidisiBroodTyrantTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, Zone.LIBRARY, Zone.GRAVEYARD, new CreateTokenEffect(new ZombieToken("KTK")), "", false);
|
||||
super(Zone.BATTLEFIELD, new CreateTokenEffect(new ZombieToken("KTK")), false);
|
||||
}
|
||||
|
||||
public SidisiBroodTyrantTriggeredAbility(final SidisiBroodTyrantTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.lastStackObjectId = ability.lastStackObjectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE_GROUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
|
||||
if ((fromZone == null || zEvent.getFromZone() == fromZone) && (toZone == null || zEvent.getToZone() == toZone)) {
|
||||
Card card = game.getCard(event.getTargetId());
|
||||
if (card != null && card.getOwnerId().equals(getControllerId()) && card.getCardType().contains(CardType.CREATURE)) {
|
||||
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
|
||||
if (stackObject == null) {
|
||||
stackObject = (StackObject) game.getLastKnownInformation(event.getSourceId(), Zone.STACK);
|
||||
}
|
||||
// If multiple cards go to graveyard from replacement effect (e.g. Dredge) each card is wrongly handled as a new event
|
||||
if (stackObject != null) {
|
||||
if (stackObject.getId().equals(lastStackObjectId)) {
|
||||
return false; // was already handled
|
||||
}
|
||||
lastStackObjectId = stackObject.getId();
|
||||
ZoneChangeGroupEvent zEvent = (ZoneChangeGroupEvent)event;
|
||||
if (Zone.LIBRARY == zEvent.getFromZone() && Zone.GRAVEYARD == zEvent.getToZone()) {
|
||||
for (Card card: zEvent.getCards()) {
|
||||
if (card.getOwnerId().equals(getControllerId()) && card.getCardType().contains(CardType.CREATURE)) {
|
||||
return true;
|
||||
} else {
|
||||
// special action or replacement effect, so we can't check yet if multiple cards are moved with one effect
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class SultaiSoothsayerEffect extends OneShotEffect {
|
|||
if (controller.choose(Outcome.Benefit, cards, target, game)) {
|
||||
Card card = cards.get(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
|
||||
cards.remove(card);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,17 +180,12 @@ class WarpWorldEffect extends OneShotEffect {
|
|||
player = playerList.getNext(game);
|
||||
} while (!player.getId().equals(game.getActivePlayerId()));
|
||||
|
||||
// put the rest of the cards into the graveyard
|
||||
// put the rest of the cards on buttom of the library
|
||||
playerList.setCurrent(game.getActivePlayerId());
|
||||
player = game.getPlayer(game.getActivePlayerId());
|
||||
do {
|
||||
CardsImpl cards = cardsRevealed.get(player.getId());
|
||||
for (Card card : cards.getCards(game)) {
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
|
||||
CardsImpl cards = cardsRevealed.get(player.getId());
|
||||
player.putCardsOnBottomOfLibrary(cards, game, source, false);
|
||||
player = playerList.getNext(game);
|
||||
} while (!player.getId().equals(game.getActivePlayerId()));
|
||||
|
||||
|
|
|
|||
|
|
@ -86,13 +86,13 @@ class GlimpseTheFutureEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
|
||||
if (player != null) {
|
||||
if (controller != null) {
|
||||
Cards cards = new CardsImpl(Zone.PICK);
|
||||
int cardsCount = Math.min(3, player.getLibrary().size());
|
||||
int cardsCount = Math.min(3, controller.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
Card card = controller.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
game.setZone(card.getId(), Zone.PICK);
|
||||
|
|
@ -100,20 +100,17 @@ class GlimpseTheFutureEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (cards.size() > 0) {
|
||||
player.lookAtCards("Glimpse the Future", cards, game);
|
||||
controller.lookAtCards("Glimpse the Future", cards, game);
|
||||
|
||||
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put in your hand"));
|
||||
if (player.choose(Outcome.Benefit, cards, target, game)) {
|
||||
if (controller.choose(Outcome.Benefit, cards, target, game)) {
|
||||
Card card = cards.get(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
|
||||
cards.remove(card);
|
||||
}
|
||||
}
|
||||
|
||||
for (Card card : cards.getCards(game)) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.sets.magic2014;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -102,35 +103,32 @@ class JaceMindseekerEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Cards cards = new CardsImpl();
|
||||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if (player != null) {
|
||||
// putting cards to grave shouldn't end the game, so getting minimun available
|
||||
int cardsCount = Math.min(5, player.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
if (filter.match(card, game)) {
|
||||
cards.add(card);
|
||||
Cards cardsToCast = new CardsImpl();
|
||||
Player targetOpponent = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if (targetOpponent != null) {
|
||||
List<Card> allCards = targetOpponent.getLibrary().getTopCards(game, 5);
|
||||
targetOpponent.moveCards(allCards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
for(Card card : allCards) {
|
||||
if (filter.match(card, game)) {
|
||||
Zone zone = game.getState().getZone(card.getId());
|
||||
// If the five cards are put into a public zone such as exile instead of a graveyard (perhaps due to the ability of Rest in Peace),
|
||||
// you can cast one of those instant or sorcery cards from that zone.
|
||||
if (zone.equals(Zone.GRAVEYARD) || zone.equals(Zone.EXILED)) {
|
||||
cardsToCast.add(card);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("couldn't get card from library");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cast an instant or sorcery for free
|
||||
// TODO: Check if card can also be cast if it doesn't end in the graveyard due to other active effects (LevelX2 08.07.2013).
|
||||
if (cards.size() > 0) {
|
||||
if (cardsToCast.size() > 0) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
TargetCard target = new TargetCard(Zone.PICK, filter);
|
||||
TargetCard target = new TargetCard(Zone.GRAVEYARD, filter); // zone should be ignored here
|
||||
target.setNotTarget(true);
|
||||
if (controller.chooseUse(outcome, "Cast an instant or sorcery card from among them for free?", game)
|
||||
&& controller.choose(outcome, cards, target, game)) {
|
||||
Card card = cards.get(target.getFirstTarget(), game);
|
||||
&& controller.choose(outcome, cardsToCast, target, game)) {
|
||||
Card card = cardsToCast.get(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
controller.cast(card.getSpellAbility(), game, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import mage.abilities.effects.common.AttachEffect;
|
|||
import mage.abilities.effects.common.combat.CantBlockAttackActivateAttachedEffect;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
|
|
|||
|
|
@ -31,11 +31,9 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.EntersBattlefieldEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
|
|
@ -112,6 +110,7 @@ public class WorldheartPhoenix extends CardImpl {
|
|||
if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
|
||||
Player player = game.getPlayer(affectedControllerId);
|
||||
if (player != null) {
|
||||
// can sometimes be cast with base mana cost from grave????
|
||||
player.setCastSourceIdWithAlternateMana(sourceId, new ManaCostsImpl<>("{W}{U}{B}{R}{G}"));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,23 +103,20 @@ class CountrysideCrusherEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent == null) {
|
||||
permanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
|
||||
}
|
||||
if (player != null && permanent != null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (controller != null && sourcePermanent != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
while (player.getLibrary().size() > 0) {
|
||||
Card card = player.getLibrary().getFromTop(game);
|
||||
while (controller.getLibrary().size() > 0) {
|
||||
Card card = controller.getLibrary().getFromTop(game);
|
||||
cards.add(card);
|
||||
if (card.getCardType().contains(CardType.LAND)) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.revealCards(permanent.getName(), cards, game);
|
||||
controller.revealCards(sourcePermanent.getName(), cards, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -127,8 +127,7 @@ class NogginWhackEffect extends OneShotEffect {
|
|||
for (UUID cardId : (List<UUID>) targetInHand.getTargets()) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": Discarded card ").append(card.getName()).toString());
|
||||
controller.discard(card, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
|||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.PlayTargetWithoutPayingManaEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
|
|
@ -104,13 +103,10 @@ class ChancellorOfTheSpiresDelayedTriggeredAbility extends DelayedTriggeredAbili
|
|||
ChancellorOfTheSpiresDelayedTriggeredAbility(ChancellorOfTheSpiresDelayedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE;
|
||||
}
|
||||
@Override
|
||||
public ChancellorOfTheSpiresDelayedTriggeredAbility copy() {
|
||||
|
|
@ -132,16 +128,9 @@ class ChancellorOfTheSpiresEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
|
||||
Player player = game.getPlayer(opponentId);
|
||||
if (player != null) {
|
||||
int cardsCount = Math.min(7, player.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null)
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
else
|
||||
break;
|
||||
}
|
||||
Player opponent = game.getPlayer(opponentId);
|
||||
if (opponent != null) {
|
||||
opponent.moveCards(opponent.getLibrary().getTopCards(game, 7), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -82,13 +82,17 @@ class MindcrankTriggeredAbility extends TriggeredAbilityImpl {
|
|||
return new MindcrankTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == EventType.LOST_LIFE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Set<UUID> opponents = game.getOpponents(this.getControllerId());
|
||||
if (event.getType() == EventType.LOST_LIFE && opponents.contains(event.getPlayerId())) {
|
||||
if (opponents.contains(event.getPlayerId())) {
|
||||
Effect effect = this.getEffects().get(0);
|
||||
effect.setValue("targetPlayer", event.getPlayerId());
|
||||
effect.setValue("amount", event.getAmount());
|
||||
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -117,21 +121,13 @@ class MindcrankEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
UUID targetId = (UUID) getValue("targetPlayer");
|
||||
Player player = game.getPlayer(targetId);
|
||||
if (player != null) {
|
||||
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (targetPlayer != null) {
|
||||
Integer amount = (Integer) getValue("amount");
|
||||
if (amount == null) {
|
||||
amount = 0;
|
||||
}
|
||||
// putting cards to grave shouldn't end the game, so getting minimum available
|
||||
amount = Math.min(amount, player.getLibrary().size());
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
targetPlayer.moveCards(targetPlayer.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,23 +30,15 @@ package mage.sets.odyssey;
|
|||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.DiscardCardCost;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.common.continuous.GainProtectionFromColorSourceEffect;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -66,7 +58,7 @@ public class ResilientWanderer extends CardImpl {
|
|||
// First strike
|
||||
this.addAbility(FirstStrikeAbility.getInstance());
|
||||
// Discard a card: Resilient Wanderer gains protection from the color of your choice until end of turn.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainProtectionFromColorSourceEffect(), new DiscardCardCost());
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainProtectionFromColorSourceEffect(Duration.EndOfTurn), new DiscardCardCost());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -80,40 +72,3 @@ public class ResilientWanderer extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class GainProtectionFromColorSourceEffect extends ContinuousEffectImpl {
|
||||
|
||||
protected FilterCard protectionFilter;
|
||||
|
||||
public GainProtectionFromColorSourceEffect() {
|
||||
super(Duration.EndOfTurn, Outcome.AddAbility);
|
||||
}
|
||||
|
||||
public GainProtectionFromColorSourceEffect(final GainProtectionFromColorSourceEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GainProtectionFromColorSourceEffect copy() {
|
||||
return new GainProtectionFromColorSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent creature = game.getPermanent(source.getSourceId());
|
||||
if (creature != null) {
|
||||
ChoiceColor choice = (ChoiceColor) source.getChoices().get(0);
|
||||
protectionFilter.add(new ColorPredicate(choice.getColor()));
|
||||
protectionFilter.setMessage(choice.getChoice());
|
||||
ProtectionAbility ability = new ProtectionAbility(protectionFilter);
|
||||
creature.addAbility(ability, source.getSourceId(), game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "{this} gains protection from the color of your choice " + duration.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,16 +89,16 @@ class ThinkTankLookLibraryEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player you = game.getPlayer(source.getControllerId());
|
||||
if (you != null) {
|
||||
if (you.getLibrary().size() > 0) {
|
||||
Card card = you.getLibrary().getFromTop(game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
if (controller.getLibrary().size() > 0) {
|
||||
Card card = controller.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
CardsImpl cards = new CardsImpl();
|
||||
cards.add(card);
|
||||
you.lookAtCards("Think Tank", cards, game);
|
||||
if (you.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) {
|
||||
return card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
controller.lookAtCards("Think Tank", cards, game);
|
||||
if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) {
|
||||
return controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,25 +30,16 @@ package mage.sets.onslaught;
|
|||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.BlocksTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.abilities.effects.common.continuous.GainProtectionFromColorSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -69,7 +60,7 @@ public class JarethLeonineTitan extends CardImpl {
|
|||
// Whenever Jareth, Leonine Titan blocks, it gets +7/+7 until end of turn.
|
||||
this.addAbility(new BlocksTriggeredAbility(new BoostSourceEffect(7,7,Duration.EndOfTurn), false));
|
||||
// {W}: Jareth gains protection from the color of your choice until end of turn.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new JarethsGainProtectionFromColorSourceEffect(), new ManaCostsImpl("{W}"));
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainProtectionFromColorSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{W}"));
|
||||
this.addAbility(ability);
|
||||
|
||||
}
|
||||
|
|
@ -83,48 +74,3 @@ public class JarethLeonineTitan extends CardImpl {
|
|||
return new JarethLeonineTitan(this);
|
||||
}
|
||||
}
|
||||
|
||||
class JarethsGainProtectionFromColorSourceEffect extends ContinuousEffectImpl {
|
||||
|
||||
protected FilterCard protectionFilter;
|
||||
|
||||
public JarethsGainProtectionFromColorSourceEffect() {
|
||||
super(Duration.EndOfTurn, Outcome.AddAbility);
|
||||
}
|
||||
|
||||
public JarethsGainProtectionFromColorSourceEffect(final JarethsGainProtectionFromColorSourceEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JarethsGainProtectionFromColorSourceEffect copy() {
|
||||
return new JarethsGainProtectionFromColorSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent creature = game.getPermanent(source.getSourceId());
|
||||
if (controller != null && creature != null) {
|
||||
ChoiceColor choice = new ChoiceColor();
|
||||
while (!choice.isChosen()) {
|
||||
controller.choose(Outcome.Protect, choice, game);
|
||||
if (!controller.isInGame()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
protectionFilter.add(new ColorPredicate(choice.getColor()));
|
||||
protectionFilter.setMessage(choice.getChoice());
|
||||
ProtectionAbility ability = new ProtectionAbility(protectionFilter);
|
||||
creature.addAbility(ability, source.getSourceId(), game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "{this} gains protection from the color of your choice " + duration.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class InfernalGenesis extends CardImpl {
|
|||
class InfernalGenesisEffect extends OneShotEffect {
|
||||
|
||||
InfernalGenesisEffect() {
|
||||
super(Outcome.BoostCreature);
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "that player puts the top card of his or her library into his or her graveyard. Then he or she puts X 1/1 black Minion creature tokens onto the battlefield, where X is that card's converted mana cost";
|
||||
}
|
||||
|
||||
|
|
@ -79,14 +79,14 @@ class InfernalGenesisEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (player != null) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
if (card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false)) {
|
||||
if (player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game)) {
|
||||
int cmc = card.getManaCost().convertedManaCost();
|
||||
MinionToken token = new MinionToken();
|
||||
token.putOntoBattlefield(cmc, game, id, player.getId());
|
||||
token.putOntoBattlefield(cmc, game, source.getSourceId(), player.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class DestroyTheEvidenceEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
player.revealCards(sourceObject.getName(), cards, game, true);
|
||||
player.moveCardsToGraveyardWithInfo(cards, source, game, Zone.LIBRARY);
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class EpicExperimentEffect extends OneShotEffect {
|
|||
// move cards not cast to graveyard
|
||||
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
|
||||
if (exile != null) {
|
||||
controller.moveCardsToGraveyardWithInfo(exile, source, game, Zone.EXILED);
|
||||
controller.moveCards(exile, Zone.EXILED, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ public class GuildFeud extends CardImpl {
|
|||
super(ownerId, 97, "Guild Feud", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}");
|
||||
this.expansionSetCode = "RTR";
|
||||
|
||||
|
||||
// At the beginning of your upkeep, target opponent reveals the top three cards
|
||||
// of his or her library, may put a creature card from among them onto the battlefield,
|
||||
// then puts the rest into his or her graveyard. You do the same with the top three
|
||||
|
|
@ -101,27 +100,20 @@ class GuildFeudEffect extends OneShotEffect {
|
|||
if (opponent != null && controller != null) {
|
||||
for (int activePlayer = 0; activePlayer < 2; activePlayer++) {
|
||||
Player player = (activePlayer == 0? opponent : controller);
|
||||
Cards topThreeCards = new CardsImpl(Zone.PICK);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (player.getLibrary().size() > 0) {
|
||||
Card topCard = player.getLibrary().removeFromTop(game);
|
||||
if (topCard != null) {
|
||||
topThreeCards.add(topCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
player.revealCards(player.getLogName() + " top three library cards", topThreeCards, game);
|
||||
Cards topThreeCards = new CardsImpl();
|
||||
topThreeCards.addAll(player.getLibrary().getTopCards(game, 3));
|
||||
player.revealCards(player.getName() + " top three library cards", topThreeCards, game);
|
||||
Card creatureToBattlefield;
|
||||
if (!topThreeCards.isEmpty()) {
|
||||
if (player.chooseUse(Outcome.PutCreatureInPlay, "Put a creature card among them to the battlefield?", game)) {
|
||||
TargetCard target = new TargetCard(Zone.PICK,
|
||||
TargetCard target = new TargetCard(Zone.LIBRARY,
|
||||
new FilterCreatureCard(
|
||||
"creature card to put on the battlefield"));
|
||||
if (player.choose(Outcome.PutCreatureInPlay, topThreeCards, target, game)) {
|
||||
creatureToBattlefield = topThreeCards.get(target.getFirstTarget(), game);
|
||||
if (creatureToBattlefield != null) {
|
||||
topThreeCards.remove(creatureToBattlefield);
|
||||
if (creatureToBattlefield.putOntoBattlefield(game, Zone.PICK,
|
||||
if (creatureToBattlefield.putOntoBattlefield(game, Zone.LIBRARY,
|
||||
source.getSourceId(), player.getId())) {
|
||||
game.informPlayers("Guild Feud: " + player.getLogName() + " put " + creatureToBattlefield.getName() + " to the battlefield");
|
||||
if (activePlayer == 0) {
|
||||
|
|
@ -133,23 +125,14 @@ class GuildFeudEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (topThreeCards.size() > 0) {
|
||||
|
||||
while (topThreeCards.size() > 0) {
|
||||
Card card = topThreeCards.get(topThreeCards.iterator().next(), game);
|
||||
topThreeCards.remove(card);
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
player.moveCards(topThreeCards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
// If two creatures are put onto the battlefield this way, those creatures fight each other
|
||||
if (opponentCreature != null && controllerCreature != null) {
|
||||
int power = opponentCreature.getPower().getValue();
|
||||
opponentCreature.damage(controllerCreature.getPower().getValue(), source.getSourceId(), game, false, true);
|
||||
controllerCreature.damage(power, source.getSourceId(), game, false, true);
|
||||
opponentCreature.fight(controllerCreature, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -158,4 +141,4 @@ class GuildFeudEffect extends OneShotEffect {
|
|||
public GuildFeudEffect copy() {
|
||||
return new GuildFeudEffect(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ public class JaradsOrders extends CardImpl {
|
|||
super(ownerId, 175, "Jarad's Orders", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{B}{G}");
|
||||
this.expansionSetCode = "RTR";
|
||||
|
||||
|
||||
// Search your library for up to two creature cards and reveal them. Put one into your hand and the other into your graveyard. Then shuffle your library.
|
||||
this.getSpellAbility().addEffect(new JaradsOrdersEffect());
|
||||
}
|
||||
|
|
@ -91,36 +90,35 @@ class JaradsOrdersEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterCreatureCard("creature cards"));
|
||||
if (player.searchLibrary(target, game)) {
|
||||
if (controller.searchLibrary(target, game)) {
|
||||
if (target.getTargets().size() > 0) {
|
||||
Cards revealed = new CardsImpl();
|
||||
for (UUID cardId: (List<UUID>)target.getTargets()) {
|
||||
Card card = player.getLibrary().getCard(cardId, game);
|
||||
Card card = controller.getLibrary().getCard(cardId, game);
|
||||
revealed.add(card);
|
||||
}
|
||||
player.revealCards("Jarad's Orders", revealed, game);
|
||||
controller.revealCards("Jarad's Orders", revealed, game);
|
||||
if (target.getTargets().size() == 2) {
|
||||
TargetCard target2 = new TargetCard(Zone.PICK, filter);
|
||||
player.choose(Outcome.Benefit, revealed, target2, game);
|
||||
controller.choose(Outcome.Benefit, revealed, target2, game);
|
||||
Card card = revealed.get(target2.getFirstTarget(), game);
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
|
||||
revealed.remove(card);
|
||||
card = revealed.getCards(game).iterator().next();
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
else if (target.getTargets().size() == 1) {
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
} else if (target.getTargets().size() == 1) {
|
||||
Card card = revealed.getCards(game).iterator().next();
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
|
||||
}
|
||||
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
controller.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
controller.shuffleLibrary(game);
|
||||
}
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -90,14 +90,7 @@ class PsychicSpiralEffect extends OneShotEffect {
|
|||
if (cardsInGraveyard > 0) {
|
||||
Player targetPlayer = game.getPlayer(source.getFirstTarget());
|
||||
if (targetPlayer != null) {
|
||||
for (int i = 0; i<cardsInGraveyard ; i++) {
|
||||
if (targetPlayer.getLibrary().size() > 0) {
|
||||
Card card = targetPlayer.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
targetPlayer.moveCards(targetPlayer.getLibrary().getTopCards(game, cardsInGraveyard), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import mage.constants.Rarity;
|
|||
import mage.constants.Zone;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||
|
|
@ -60,15 +61,22 @@ public class EldraziConscription extends CardImpl {
|
|||
this.subtype.add("Eldrazi");
|
||||
this.subtype.add("Aura");
|
||||
|
||||
// Enchant creature
|
||||
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||
this.getSpellAbility().addTarget(auraTarget);
|
||||
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||
this.addAbility(ability);
|
||||
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(10, 10, Duration.WhileOnBattlefield)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(new AnnihilatorAbility(2), AttachmentType.AURA)));
|
||||
|
||||
// Enchanted creature gets +10/+10 and has trample and annihilator 2
|
||||
ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(10, 10, Duration.WhileOnBattlefield));
|
||||
Effect effect = new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA);
|
||||
effect.setText("and has trample");
|
||||
ability.addEffect(effect);
|
||||
effect = new GainAbilityAttachedEffect(new AnnihilatorAbility(2), AttachmentType.AURA);
|
||||
effect.setText("and annihilator 2. <i>(Whenever it attacks, defending player sacrifices two permanents.)</i>");
|
||||
ability.addEffect(effect);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public EldraziConscription (final EldraziConscription card) {
|
||||
|
|
|
|||
|
|
@ -91,19 +91,8 @@ class KeeningStoneEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getFirstTarget());
|
||||
if (player != null) {
|
||||
Library library = player.getLibrary();
|
||||
|
||||
int amount = Math.min(player.getGraveyard().size(), library.size());
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Card card = library.removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (amount > 0) {
|
||||
return true;
|
||||
}
|
||||
player.moveCards(player.getLibrary().getTopCards(game, player.getGraveyard().size()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,19 +93,18 @@ class ChoiceOfDamnationsEffect extends OneShotEffect {
|
|||
int amount = targetPlayer.getAmount(0, Integer.MAX_VALUE, "Chooses a number", game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
String sb = String.valueOf("Shall " + targetPlayer.getLogName() + " lose ") + Integer.toString(amount) + " life?";
|
||||
if (controller.chooseUse(outcome, sb, game)) {
|
||||
if (controller.chooseUse(outcome, "Shall " + targetPlayer.getLogName() + " lose " + amount + " life?", game)) {
|
||||
targetPlayer.loseLife(amount, game);
|
||||
} else {
|
||||
int numberPermanents = game.getState().getBattlefield().countAll(new FilterPermanent(), targetPlayer.getId(), game);
|
||||
if (numberPermanents > amount) {
|
||||
int numberToSacrifice = numberPermanents - amount;
|
||||
Target target = new TargetControlledPermanent(numberToSacrifice, numberToSacrifice, new FilterControlledPermanent(), false);
|
||||
Target target = new TargetControlledPermanent(numberToSacrifice, numberToSacrifice, new FilterControlledPermanent("permanent you control to sacrifice"), false);
|
||||
targetPlayer.chooseTarget(Outcome.Sacrifice, target, source, game);
|
||||
for (UUID uuid : target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(uuid);
|
||||
if (permanent != null) {
|
||||
permanent.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
permanent.sacrifice(source.getSourceId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -107,19 +106,8 @@ class CloudhoofKirinEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
if (targetPlayer != null) {
|
||||
int cardsCount = Math.min(spell.getConvertedManaCost(), targetPlayer.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = targetPlayer.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return targetPlayer.moveCards(targetPlayer.getLibrary().getTopCards(game, spell.getConvertedManaCost()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ import mage.filter.predicate.Predicates;
|
|||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetCardInOpponentsGraveyard;
|
||||
|
|
@ -114,34 +113,15 @@ class GethLordOfTheVaultEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card card = game.getCard(source.getFirstTarget());
|
||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
if (card != null) {
|
||||
// if still in graveyard
|
||||
if (game.getState().getZone(card.getId()).equals(Zone.GRAVEYARD)) {
|
||||
Player player = game.getPlayer(card.getOwnerId());
|
||||
if (card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId())) {
|
||||
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
permanent.setTapped(true);
|
||||
}
|
||||
|
||||
int xvalue = card.getManaCost().convertedManaCost();
|
||||
int cardsCount = Math.min(xvalue, player.getLibrary().size());
|
||||
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card removedCard = player.getLibrary().getFromTop(game);
|
||||
if (removedCard != null) {
|
||||
removedCard.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId(), true);
|
||||
Player player = game.getPlayer(card.getOwnerId());
|
||||
if (player != null) {
|
||||
player.moveCards(player.getLibrary().getTopCards(game, card.getManaCost().convertedManaCost()), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.counters.CounterType;
|
||||
|
|
@ -85,17 +84,12 @@ class GrindclockEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
int amount = game.getPermanent(source.getSourceId()).getCounters().getCount(CounterType.CHARGE);
|
||||
Player player = game.getPlayer(source.getFirstTarget());
|
||||
Card card;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
Player targetPlayer = game.getPlayer(source.getFirstTarget());
|
||||
if (targetPlayer != null) {
|
||||
targetPlayer.moveCards(targetPlayer.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
|
|
@ -128,7 +129,7 @@ class MimicVatTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with Mimic Vat to its owner's graveyard";
|
||||
return "Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with {this} to its owner's graveyard";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -146,14 +147,14 @@ class MimicVatEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent == null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null || permanent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return older cards to graveyard
|
||||
for (UUID imprinted : permanent.getImprinted()) {
|
||||
Card card = game.getCard(imprinted);
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
controller.moveCards(card, Zone.EXILED, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
permanent.clearImprinted(game);
|
||||
|
||||
|
|
|
|||
|
|
@ -113,10 +113,7 @@ class AncestralMemoriesEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Card card : cards.getCards(game)) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ class GhastlordOfFugueEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player targetPlayer = game.getPlayer(source.getFirstTarget());
|
||||
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (targetPlayer != null
|
||||
|
|
@ -111,7 +111,7 @@ class GhastlordOfFugueEffect extends OneShotEffect {
|
|||
chosenCard = game.getCard(target.getFirstTarget());
|
||||
}
|
||||
if (chosenCard != null) {
|
||||
controller.moveCardToExileWithInfo(chosenCard, null, "", source.getSourceId(), game, Zone.HAND, true);
|
||||
controller.moveCards(chosenCard, Zone.HAND, Zone.EXILED, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,24 +98,19 @@ class SearchLibraryPutInGraveyard extends SearchEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.searchLibrary(target, game)) {
|
||||
if (target.getTargets().size() > 0) {
|
||||
Cards cards = new CardsImpl();
|
||||
for (UUID cardId: (List<UUID>)target.getTargets()) {
|
||||
Card card = player.getLibrary().remove(cardId, game);
|
||||
if (card != null){
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
if (controller.searchLibrary(target, game)) {
|
||||
if (target.getTargets().size() > 0) {
|
||||
Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
controller.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,17 +84,19 @@ class HinderingLightPredicate implements ObjectPlayerPredicate<ObjectPlayer<Stac
|
|||
if (controllerId == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Target target : input.getObject().getStackAbility().getTargets()) {
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
if (controllerId.equals(targetId)) {
|
||||
return true;
|
||||
for (UUID modeId :input.getObject().getStackAbility().getModes().getSelectedModes()) {
|
||||
input.getObject().getStackAbility().getModes().setActiveMode(modeId);
|
||||
for (Target target : input.getObject().getStackAbility().getTargets()) {
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
if (controllerId.equals(targetId)) {
|
||||
return true;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null && controllerId.equals(permanent.getControllerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null && controllerId.equals(permanent.getControllerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,26 +93,19 @@ class AltarOfDementiaEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
int amount = 0;
|
||||
for (Cost cost: source.getCosts()) {
|
||||
if (cost instanceof SacrificeTargetCost && ((SacrificeTargetCost)cost).getPermanents().size() > 0) {
|
||||
amount = ((SacrificeTargetCost)cost).getPermanents().get(0).getPower().getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (amount > 0) {
|
||||
Player player = game.getPlayer(source.getFirstTarget());
|
||||
if (player != null) {
|
||||
for (int i = 0; i<amount ; i++) {
|
||||
if (player.getLibrary().size() > 0) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
Player player = game.getPlayer(source.getFirstTarget());
|
||||
if (player != null) {
|
||||
int amount = 0;
|
||||
for (Cost cost: source.getCosts()) {
|
||||
if (cost instanceof SacrificeTargetCost && ((SacrificeTargetCost)cost).getPermanents().size() > 0) {
|
||||
amount = ((SacrificeTargetCost)cost).getPermanents().get(0).getPower().getValue();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (amount > 0) {
|
||||
player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,43 +94,42 @@ class IntuitionEffect extends SearchEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Player opponent = game.getPlayer(source.getFirstTarget());
|
||||
if (player == null || opponent == null)
|
||||
if (controller == null || opponent == null)
|
||||
return false;
|
||||
|
||||
if (player.getLibrary().size() >= 3 && player.searchLibrary(target, game)) {
|
||||
if (controller.getLibrary().size() >= 3 && controller.searchLibrary(target, game)) {
|
||||
|
||||
if (target.getTargets().size() == 3) {
|
||||
Cards cards = new CardsImpl();
|
||||
for (UUID cardId: (List<UUID>)target.getTargets()) {
|
||||
Card card = player.getLibrary().getCard(cardId, game);
|
||||
Card card = controller.getLibrary().getCard(cardId, game);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
}
|
||||
}
|
||||
player.revealCards("Reveal", cards, game);
|
||||
controller.revealCards("Reveal", cards, game);
|
||||
|
||||
TargetCard targetCard = new TargetCard(Zone.PICK, new FilterCard());
|
||||
|
||||
while(!opponent.choose(Outcome.Neutral, cards, targetCard, game));
|
||||
while(!opponent.choose(Outcome.Neutral, cards, targetCard, game)) {
|
||||
if (!opponent.isInGame()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Card card = cards.get(targetCard.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
cards.remove(card);
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
|
||||
controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
|
||||
}
|
||||
|
||||
for(UUID uuid : cards){
|
||||
card = cards.get(uuid, game);
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
}
|
||||
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
controller.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
|
||||
player.shuffleLibrary(game);
|
||||
controller.shuffleLibrary(game);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -114,16 +114,17 @@ class WoodSageEffect extends OneShotEffect {
|
|||
|
||||
Cards cards = new CardsImpl();
|
||||
cards.addAll(controller.getLibrary().getTopCards(game, 4));
|
||||
|
||||
if (!cards.isEmpty()) {
|
||||
Cards cardsToHand = new CardsImpl();
|
||||
controller.revealCards(sourceObject.getName(), cards, game);
|
||||
for (Card card: cards.getCards(game)) {
|
||||
if (card.getName().equals(cardName)) {
|
||||
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true);
|
||||
cardsToHand.add(card);
|
||||
cards.remove(card);
|
||||
}
|
||||
}
|
||||
controller.moveCardsToGraveyardWithInfo(cards, source, game, Zone.LIBRARY);
|
||||
controller.moveCards(cardsToHand, Zone.LIBRARY, Zone.HAND, source, game);
|
||||
controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,8 +80,7 @@ class TraumatizeEffect extends OneShotEffect {
|
|||
Player player = game.getPlayer(source.getFirstTarget());
|
||||
if (player != null) {
|
||||
int amount = player.getLibrary().size() / 2;
|
||||
player.moveCardsToGraveyardWithInfo(player.getLibrary().getTopCards(game, amount), source, game, Zone.LIBRARY);
|
||||
return true;
|
||||
return player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,16 +83,7 @@ class WhetstoneEffect extends OneShotEffect {
|
|||
for (UUID playerId : game.getPlayerList()) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
// putting cards to grave shouldn't end the game, so getting minimun available
|
||||
int cardsCount = Math.min(2, player.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, false);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.moveCards(player.getLibrary().getTopCards(game, 2), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,11 @@ public class CursesTest extends CardTestPlayerBase {
|
|||
public void testCurseOfEchoes() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 5);
|
||||
// Enchant player
|
||||
// Whenever enchanted player casts an instant or sorcery spell, each other player may copy that
|
||||
// spell and may choose new targets for the copy he or she controls.
|
||||
addCard(Zone.HAND, playerA, "Curse of Echoes");
|
||||
// Draw three cards.
|
||||
addCard(Zone.HAND, playerB, "Jace's Ingenuity");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Echoes", playerB);
|
||||
|
|
@ -49,6 +53,8 @@ public class CursesTest extends CardTestPlayerBase {
|
|||
@Test
|
||||
public void testCurseOfExhaustion1() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||
// Enchant player
|
||||
// Enchanted player can't cast more than one spell each turn.
|
||||
addCard(Zone.HAND, playerA, "Curse of Exhaustion");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
|
||||
addCard(Zone.HAND, playerB, "Lightning Bolt", 2);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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 org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* 702.64. Aura swap
|
||||
* 702.64a Aura swap is an activated ability of some Aura cards.
|
||||
* "Aura swap [cost]" means "[Cost]: You may exchange this permanent with an Aura card in your hand."
|
||||
* 702.64b If either half of the exchange can't be completed, the ability has no effect.
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class AuraSwapTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Test normal swap
|
||||
*/
|
||||
@Test
|
||||
public void testAuraSwap1() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
// Enchanted creature has flying.
|
||||
// Aura swap {2}{U}
|
||||
addCard(Zone.HAND, playerA, "Arcanum Wings"); // {1}{U}
|
||||
|
||||
// Enchant creature
|
||||
// Enchanted creature gets +10/+10 and has trample and annihilator 2. (Whenever it attacks, defending player sacrifices two permanents.)
|
||||
addCard(Zone.HAND, playerA, "Eldrazi Conscription"); // {8}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Arcanum Wings", "Silvercoat Lion");
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Aura swap");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, "Arcanum Wings", 1);
|
||||
assertPermanentCount(playerA, "Eldrazi Conscription", 1);
|
||||
assertPowerToughness(playerA, "Silvercoat Lion", 12, 12);
|
||||
}
|
||||
/**
|
||||
* Test swap canceled because enchantment disenchanted
|
||||
*/
|
||||
@Test
|
||||
public void testAuraSwap2() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
// Enchanted creature has flying.
|
||||
// Aura swap {2}{U}
|
||||
addCard(Zone.HAND, playerA, "Arcanum Wings"); // {1}{U}
|
||||
|
||||
// Enchant creature
|
||||
// Enchanted creature gets +10/+10 and has trample and annihilator 2. (Whenever it attacks, defending player sacrifices two permanents.)
|
||||
addCard(Zone.HAND, playerA, "Eldrazi Conscription"); // {8}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
|
||||
addCard(Zone.HAND, playerB, "Disenchant");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Arcanum Wings", "Silvercoat Lion");
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Aura swap");
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Disenchant", "Arcanum Wings", "Aura swap");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Disenchant", 1);
|
||||
|
||||
assertGraveyardCount(playerA, "Arcanum Wings", 1);
|
||||
assertPermanentCount(playerA, "Eldrazi Conscription", 0);
|
||||
assertHandCount(playerA, "Eldrazi Conscription", 1);
|
||||
assertPowerToughness(playerA, "Silvercoat Lion", 2, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -45,7 +45,38 @@ public class DredgeTest extends CardTestPlayerBase {
|
|||
*/
|
||||
|
||||
|
||||
/**
|
||||
@Test
|
||||
public void testSultaiSoothsayerWithSidisiBroodTyrant() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
// Whenever Sidisi, Brood Tyrant enters the battlefield or attacks, put the top three cards of your library into your graveyard.
|
||||
// Whenever one or more creature cards are put into your graveyard from your library, put a 2/2 black Zombie creature token onto the battlefield.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sidisi, Brood Tyrant");
|
||||
// When Sultai Soothsayer enters the battlefield, look at the top four cards of your library.
|
||||
// Put one of them into your hand and the rest into your graveyard.
|
||||
addCard(Zone.HAND, playerA, "Sultai Soothsayer");
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 5);
|
||||
skipInitShuffling();
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sultai Soothsayer");
|
||||
addTarget(playerA, "Silvercoat Lion");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertHandCount(playerA, "Silvercoat Lion", 1);
|
||||
assertGraveyardCount(playerA, "Silvercoat Lion", 3);
|
||||
|
||||
assertPermanentCount(playerA, "Zombie", 1); // May only be one creature
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Had a Sidisi, Brood Tyrant in play and dredge a Stinkweed Imp hitting 3 creatures.
|
||||
* and Sidisi triggered 3 times instead of just one.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -10,7 +10,15 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* 702.87. Rebound
|
||||
* 702.87a Rebound appears on some instants and sorceries. It represents a static ability that functions while
|
||||
* the spell is on the stack and may create a delayed triggered ability. "Rebound" means "If this spell was cast
|
||||
* from your hand, instead of putting it into your graveyard as it resolves, exile it and, at the beginning of
|
||||
* your next upkeep, you may cast this card from exile without paying its mana cost."
|
||||
* 702.87b Casting a card without paying its mana cost as the result of a rebound ability follows the rules for
|
||||
* paying alternative costs in rules 601.2b and 601.2e–g.
|
||||
* 702.87c Multiple instances of rebound on the same spell are redundant.
|
||||
*
|
||||
* @author jeff
|
||||
*/
|
||||
public class ReboundTest extends CardTestPlayerBase{
|
||||
|
|
@ -104,6 +112,8 @@ public class ReboundTest extends CardTestPlayerBase{
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
|
||||
// Target creature gets +1/+0 until end of turn and is unblockable this turn.
|
||||
// Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep,
|
||||
// you may cast this card from exile without paying its mana cost.)
|
||||
addCard(Zone.HAND, playerA, "Distortion Strike");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Memnite", 1);
|
||||
|
||||
|
|
@ -113,12 +123,12 @@ public class ReboundTest extends CardTestPlayerBase{
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Distortion Strike", "Memnite");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Memnite","Distortion Strike");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
//check exile and graveyard
|
||||
assertGraveyardCount(playerB, "Lightning Bolt", 1);
|
||||
assertGraveyardCount(playerA, "Distortion Strike", 1);
|
||||
assertGraveyardCount(playerA, "Memnite", 1);
|
||||
assertGraveyardCount(playerA, "Distortion Strike", 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 org.mage.test.cards.abilities.oneshot.counterspell;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class EndrekSahrMasterBreederTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Test that tokens are created also if the spell that triggers Endreks ability is countered
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testTokenAlsoIfCountered() {
|
||||
// Whenever you cast a creature spell, put X 1/1 black Thrull creature tokens onto the battlefield, where X is that spell's converted mana cost.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Endrek Sahr, Master Breeder", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||
addCard(Zone.HAND, playerB, "Counterspell", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Counterspell", "Silvercoat Lion", "Silvercoat Lion");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
|
||||
assertGraveyardCount(playerB, "Counterspell", 1);
|
||||
|
||||
assertPermanentCount(playerA, "Thrull", 2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -62,5 +62,35 @@ public class WinLoseEffectsTest extends CardTestPlayerBase {
|
|||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
/**
|
||||
* If I have resolved an Angel's Grace this turn, have an empty library, a Laboratory Maniac on
|
||||
* the battlefield, and would draw a card, nothing happens. I should win the game if the card drawing effect resolves.
|
||||
*/
|
||||
@Test
|
||||
public void testAngelsGrace() {
|
||||
addCard(Zone.HAND, playerA, "Angel's Grace");
|
||||
// Prevent the next 1 damage that would be dealt to target creature or player this turn.
|
||||
// Draw a card.
|
||||
addCard(Zone.HAND, playerA, "Bandage");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Laboratory Maniac", 1);
|
||||
|
||||
skipInitShuffling();
|
||||
|
||||
playerA.getLibrary().clear();
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel's Grace");
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Bandage");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
Assert.assertEquals("Player A library is empty", 0 , playerA.getLibrary().size());
|
||||
Assert.assertTrue("Player A has not won but should have", playerA.hasWon());
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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 org.mage.test.cards.restriction;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class ArrestTest extends CardTestPlayerBase {
|
||||
|
||||
|
||||
@Test
|
||||
public void testArrest1() {
|
||||
addCard(Zone.HAND, playerA, "Arrest");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Forest", 4);
|
||||
// {3}{G}: Put a 1/1 green Saproling creature token onto the battlefield.
|
||||
// {3}{W}: Creatures you control get +1/+1 until end of turn.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Selesnya Guildmage");
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Arrest", "Selesnya Guildmage");
|
||||
attack(2, playerB, "Selesnya Guildmage");
|
||||
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Arrest", 1);
|
||||
assertPermanentCount(playerB, "Saproling", 0); // can't use ability so no Saproling
|
||||
|
||||
assertLife(playerA, 20); // can't attack so no damage to player
|
||||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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 org.mage.test.multiplayer;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestMultiPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PrimordialTest extends CardTestMultiPlayerBase {
|
||||
|
||||
/**
|
||||
* Tests Primordial cards with multiplayer effects
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void SepulchralPrimordialTest() {
|
||||
// When Sepulchral Primordial enters the battlefield, for each opponent, you may put up to one
|
||||
// target creature card from that player's graveyard onto the battlefield under your control.
|
||||
addCard(Zone.HAND, playerA, "Sepulchral Primordial");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp",7);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion");
|
||||
addCard(Zone.GRAVEYARD, playerC, "Walking Corpse");
|
||||
addCard(Zone.GRAVEYARD, playerD, "Pillarfield Ox");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sepulchral Primordial");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Sepulchral Primordial", 1);
|
||||
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
||||
assertPermanentCount(playerA, "Walking Corpse", 0);
|
||||
assertPermanentCount(playerA, "Pillarfield Ox", 1);
|
||||
assertGraveyardCount(playerC, "Walking Corpse", 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -68,9 +68,7 @@ public class PutTopCardOfYourLibraryToGraveyardCost extends CostImpl {
|
|||
Player player = game.getPlayer(controllerId);
|
||||
if (player != null && player.getLibrary().size() >= numberOfCards) {
|
||||
paid = true;
|
||||
Cards cards = new CardsImpl();
|
||||
cards.addAll(player.getLibrary().getTopCards(game, numberOfCards));
|
||||
player.moveCardsToGraveyardWithInfo(cards, ability, game, Zone.LIBRARY);
|
||||
player.moveCards(player.getLibrary().getTopCards(game, numberOfCards), Zone.LIBRARY, Zone.GRAVEYARD, ability, game);
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class AddManaOfAnyColorEffect extends BasicManaEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ChoiceColor choice = new ChoiceColor(false);
|
||||
ChoiceColor choice = new ChoiceColor(true);
|
||||
|
||||
if (controller.choose(outcome, choice, game)) {
|
||||
if (choice.getColor() == null) {
|
||||
|
|
|
|||
|
|
@ -94,9 +94,6 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
|
|||
if (mageObject instanceof Card) {
|
||||
Card card = (Card) mageObject;
|
||||
switch (targetZone) {
|
||||
case HAND:
|
||||
controller.moveCardToHandWithInfo(card, sourceId, game, Zone.STACK);
|
||||
break;
|
||||
case LIBRARY:
|
||||
controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.STACK, flag, true);
|
||||
break;
|
||||
|
|
@ -104,7 +101,7 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
|
|||
controller.moveCardToExileWithInfo(card, null, "", sourceId, game, Zone.STACK, true);
|
||||
break;
|
||||
default:
|
||||
card.moveToZone(targetZone, sourceId, game, flag);
|
||||
controller.moveCards(card, Zone.STACK, targetZone, source, game);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -74,9 +74,7 @@ public class PutLibraryIntoGraveTargetEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if (player != null) {
|
||||
// putting cards to grave shouldn't end the game, so getting minimun available
|
||||
int cardsCount = Math.min(amount.calculate(game, source, this), player.getLibrary().size());
|
||||
player.moveCardsToGraveyardWithInfo(player.getLibrary().getTopCards(game, cardsCount), source, game, Zone.LIBRARY);
|
||||
player.moveCards(player.getLibrary().getTopCards(game, amount.calculate(game, source, this)), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -65,8 +65,7 @@ public class PutTopCardOfLibraryIntoGraveControllerEffect extends OneShotEffect
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
controller.moveCardsToGraveyardWithInfo(controller.getLibrary().getTopCards(game, numberCards), source, game, Zone.LIBRARY);
|
||||
return true;
|
||||
return controller.moveCards(controller.getLibrary().getTopCards(game, numberCards), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
|
|
@ -106,13 +105,7 @@ public class PutTopCardOfLibraryIntoGraveEachPlayerEffect extends OneShotEffect
|
|||
private void putCardsToGravecard(UUID playerId, Ability source, Game game) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
int cardsCount = Math.min(numberCards.calculate(game, source, this), player.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
player.moveCards(player.getLibrary().getTopCards(game, numberCards.calculate(game, source, this)), Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,11 +100,14 @@ public class ReturnFromExileEffect extends OneShotEffect {
|
|||
}
|
||||
break;
|
||||
case HAND:
|
||||
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED);
|
||||
controller.moveCards(card, Zone.EXILED, Zone.HAND, source, game);
|
||||
break;
|
||||
case LIBRARY:
|
||||
controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.EXILED, true, true);
|
||||
break;
|
||||
case GRAVEYARD:
|
||||
controller.moveCards(card, Zone.EXILED, Zone.GRAVEYARD, source, game);
|
||||
break;
|
||||
default:
|
||||
card.moveToZone(zone, source.getSourceId(), game, tapped);
|
||||
if (!game.isSimulation()) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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.continuous;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.Duration;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class GainProtectionFromColorSourceEffect extends GainAbilitySourceEffect {
|
||||
|
||||
FilterCard protectionFilter;
|
||||
|
||||
public GainProtectionFromColorSourceEffect(Duration duration) {
|
||||
super(new ProtectionAbility(new FilterCard()), duration);
|
||||
protectionFilter = (FilterCard)((ProtectionAbility)ability).getFilter();
|
||||
}
|
||||
|
||||
public GainProtectionFromColorSourceEffect(final GainProtectionFromColorSourceEffect effect) {
|
||||
super(effect);
|
||||
this.protectionFilter = effect.protectionFilter.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GainProtectionFromColorSourceEffect copy() {
|
||||
return new GainProtectionFromColorSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ChoiceColor colorChoice = new ChoiceColor(true);
|
||||
colorChoice.setMessage("Choose color for protection ability");
|
||||
while (!colorChoice.isChosen()) {
|
||||
controller.choose(outcome, colorChoice, game);
|
||||
if (!controller.isInGame()) {
|
||||
discard();
|
||||
return;
|
||||
}
|
||||
}
|
||||
game.informPlayers("Choosen color: " + colorChoice.getColor());
|
||||
protectionFilter.add(new ColorPredicate(colorChoice.getColor()));
|
||||
protectionFilter.setMessage(colorChoice.getChoice());
|
||||
((ProtectionAbility)ability).setFilter(protectionFilter);
|
||||
return;
|
||||
}
|
||||
discard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null && new MageObjectReference(permanent, game).refersTo(source.getSourceObject(game), game)) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
} else {
|
||||
// the source permanent is no longer on the battlefield, effect can be discarded
|
||||
discard();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "{this} gains protection from the color of your choice " + duration.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -104,8 +104,8 @@ class DredgeEffect extends ReplacementEffectImpl {
|
|||
}
|
||||
Cards cardsToGrave = new CardsImpl();
|
||||
cardsToGrave.addAll(player.getLibrary().getTopCards(game, amount));
|
||||
player.moveCardsToGraveyardWithInfo(cardsToGrave, source, game, Zone.LIBRARY);
|
||||
player.moveCardToHandWithInfo(sourceCard, source.getSourceId(), game, Zone.GRAVEYARD);
|
||||
player.moveCards(cardsToGrave, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
|
||||
player.moveCards(sourceCard, Zone.GRAVEYARD, Zone.HAND, source, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public class WitherAbility extends StaticAbility implements MageSingleton {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Wither";
|
||||
return "Wither <i>(This deals damage to creatures in the form of -1/-1 counters.)</i>";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1204,7 +1204,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
top.resolve(this);
|
||||
} finally {
|
||||
if (top != null) {
|
||||
state.getStack().remove(top);
|
||||
state.getStack().remove(top); // seems partly redundant because move card from stack to grave is already done and the stack removed
|
||||
rememberLKI(top.getSourceId(), Zone.STACK, top);
|
||||
if (!getTurn().isEndTurnRequested()) {
|
||||
while (state.hasSimultaneousEvents()) {
|
||||
|
|
@ -1739,8 +1739,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
boolean result = false;
|
||||
if (permanent.moveToZone(Zone.GRAVEYARD, null, this, false)) {
|
||||
if (!this.isSimulation()) {
|
||||
this.informPlayers(new StringBuilder(permanent.getLogName())
|
||||
.append(" is put into graveyard from battlefield").toString());
|
||||
this.informPlayers(permanent.getLogName() + " is put into graveyard from battlefield");
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,13 +81,14 @@ public class GameEvent implements Serializable {
|
|||
|
||||
//player events
|
||||
/* ZONE_CHANGE
|
||||
targetId id of the zone chaning object
|
||||
targetId id of the zone changing object
|
||||
sourceId sourceId of the ability with the object moving effect
|
||||
playerId controller of the moved object
|
||||
amount not used for this event
|
||||
flag not used for this event
|
||||
*/
|
||||
ZONE_CHANGE,
|
||||
ZONE_CHANGE_GROUP,
|
||||
EMPTY_DRAW,
|
||||
DRAW_CARD, DREW_CARD,
|
||||
MIRACLE_CARD_REVEALED,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public class ZoneChangeEvent extends GameEvent {
|
|||
public ZoneChangeEvent(UUID targetId, UUID playerId, Zone fromZone, Zone toZone) {
|
||||
this(targetId, null, playerId, fromZone, toZone);
|
||||
}
|
||||
|
||||
|
||||
public Zone getFromZone() {
|
||||
return fromZone;
|
||||
}
|
||||
|
|
|
|||
64
Mage/src/mage/game/events/ZoneChangeGroupEvent.java
Normal file
64
Mage/src/mage/game/events/ZoneChangeGroupEvent.java
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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.game.events;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ZoneChangeGroupEvent extends GameEvent {
|
||||
|
||||
private final Zone fromZone;
|
||||
private final Zone toZone;
|
||||
private final List<Card> cards;
|
||||
|
||||
public ZoneChangeGroupEvent(List<Card> cards, UUID sourceId, UUID playerId, Zone fromZone, Zone toZone) {
|
||||
super(EventType.ZONE_CHANGE_GROUP, null, sourceId, playerId);
|
||||
this.fromZone = fromZone;
|
||||
this.toZone = toZone;
|
||||
this.cards = cards;
|
||||
}
|
||||
|
||||
public Zone getFromZone() {
|
||||
return fromZone;
|
||||
}
|
||||
|
||||
public Zone getToZone() {
|
||||
return toZone;
|
||||
}
|
||||
|
||||
public List<Card> getCards() {
|
||||
return cards;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -201,13 +201,14 @@ public class Spell implements StackObject, Card {
|
|||
result |= spellAbility.resolve(game);
|
||||
}
|
||||
}
|
||||
// game.getState().handleSimultaneousEvent(game);
|
||||
// game.resetShortLivingLKI();
|
||||
index++;
|
||||
}
|
||||
}
|
||||
if (game.getState().getZone(card.getMainCard().getId()) == Zone.STACK) {
|
||||
card.moveToZone(Zone.GRAVEYARD, ability.getSourceId(), game, false);
|
||||
Player player = game.getPlayer(getControllerId());
|
||||
if (player != null) {
|
||||
player.moveCards(card, Zone.STACK, Zone.GRAVEYARD, ability, game);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -524,7 +525,15 @@ public class Spell implements StackObject, Card {
|
|||
public void counter(UUID sourceId, Game game) {
|
||||
this.countered = true;
|
||||
if (!isCopiedSpell()) {
|
||||
card.moveToZone(Zone.GRAVEYARD, sourceId, game, false);
|
||||
Player player = game.getPlayer(getControllerId());
|
||||
if (player != null) {
|
||||
Ability counteringAbility = null;
|
||||
MageObject counteringObject = game.getObject(sourceId);
|
||||
if (counteringObject instanceof StackObject) {
|
||||
counteringAbility = ((StackObject)counteringObject).getStackAbility();
|
||||
}
|
||||
player.moveCards(card, Zone.STACK, Zone.GRAVEYARD, counteringAbility, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -502,10 +502,8 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
|
||||
|
||||
/**
|
||||
* Moves 1 to n cards to the graveyard. The owner of the cards may determine the order,
|
||||
* if more than one card is moved to graveyard.
|
||||
* Uses card.moveToZone and posts a inform message about moving the card to graveyard
|
||||
* into the game log
|
||||
* Internal used to move cards
|
||||
* Use commonly player.moveCards()
|
||||
*
|
||||
* @param cards
|
||||
* @param source
|
||||
|
|
@ -513,7 +511,6 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
* @param fromZone if null, this info isn't postet
|
||||
* @return
|
||||
*/
|
||||
boolean moveCardsToGraveyardWithInfo(Cards cards, Ability source, Game game, Zone fromZone);
|
||||
boolean moveCardsToGraveyardWithInfo(List<Card> cards, Ability source, Game game, Zone fromZone);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ import mage.game.events.DamagePlayerEvent;
|
|||
import mage.game.events.DamagedPlayerEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.events.ZoneChangeGroupEvent;
|
||||
import mage.game.match.MatchPlayer;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
|
|
@ -2441,11 +2442,10 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
// eliminate duplicate activated abilities
|
||||
Map<String, Ability> playableActivated = new HashMap<>();
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
|
||||
for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
|
||||
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = getUseableActivatedAbilities(permanent, Zone.BATTLEFIELD, game);
|
||||
for (ActivatedAbility ability : useableAbilities.values()) {
|
||||
if (!playableActivated.containsKey(ability.toString())) {
|
||||
if (canPlay(ability, availableMana, permanent, game)) {
|
||||
playableActivated.put(ability.toString(), ability);
|
||||
}
|
||||
playableActivated.put(ability.toString(), ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2844,14 +2844,25 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCards(List<Card> cards, Zone fromZone, Zone toZone, Ability source, Game game) {
|
||||
if (cards.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
game.fireEvent(new ZoneChangeGroupEvent(cards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone));
|
||||
switch(toZone) {
|
||||
case EXILED:
|
||||
boolean result = false;
|
||||
for(Card card: cards) {
|
||||
result |= moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, true);
|
||||
}
|
||||
return result;
|
||||
case GRAVEYARD:
|
||||
return moveCardsToGraveyardWithInfo(cards, source, game, fromZone);
|
||||
case HAND:
|
||||
result = false;
|
||||
for(Card card: cards) {
|
||||
moveCardToHandWithInfo(card, playerId, game, fromZone);
|
||||
result |= moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone);
|
||||
}
|
||||
return true;
|
||||
return result;
|
||||
default:
|
||||
throw new UnsupportedOperationException("to Zone not supported yet");
|
||||
}
|
||||
|
|
@ -2886,33 +2897,25 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCardsToGraveyardWithInfo(Cards allCards, Ability source, Game game, Zone fromZone) {
|
||||
ArrayList<Card> cards = new ArrayList<>();
|
||||
cards.addAll(allCards.getCards(game));
|
||||
return moveCardsToGraveyardWithInfo(cards, source, game, fromZone);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean moveCardsToGraveyardWithInfo(List<Card> allCards, Ability source, Game game, Zone fromZone) {
|
||||
while (!allCards.isEmpty()) {
|
||||
// identify cards from one owner
|
||||
Cards cards = new CardsImpl();
|
||||
UUID ownerId = null;
|
||||
for (Card card: allCards) {
|
||||
for (Iterator<Card> it = allCards.iterator(); it.hasNext();) {
|
||||
Card card = it.next();
|
||||
if (cards.isEmpty()) {
|
||||
ownerId = card.getOwnerId();
|
||||
}
|
||||
if (card.getOwnerId().equals(ownerId)) {
|
||||
it.remove();
|
||||
cards.add(card);
|
||||
}
|
||||
}
|
||||
allCards.removeAll(cards.getCards(game));
|
||||
// move cards ot graveyard in order the owner decides
|
||||
if (cards.size() != 0) {
|
||||
TargetCard target = new TargetCard(fromZone, new FilterCard("card to put on the top of your graveyard (last one chosen will be topmost)"));
|
||||
target.setRequired(true);
|
||||
if (!cards.isEmpty()) {
|
||||
Player choosingPlayer = this;
|
||||
if (ownerId != this.getId()) {
|
||||
choosingPlayer = game.getPlayer(ownerId);
|
||||
|
|
@ -2925,6 +2928,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
chooseOrder = choosingPlayer.chooseUse(Outcome.Neutral, "Would you like to choose the order the cards go to graveyard?", game);
|
||||
}
|
||||
if (chooseOrder) {
|
||||
TargetCard target = new TargetCard(fromZone, new FilterCard("card to put on the top of your graveyard (last one chosen will be topmost)"));
|
||||
target.setRequired(true);
|
||||
while (choosingPlayer.isInGame() && cards.size() > 1) {
|
||||
choosingPlayer.chooseTarget(Outcome.Neutral, cards, target, source, game);
|
||||
UUID targetObjectId = target.getFirstTarget();
|
||||
|
|
@ -2936,7 +2941,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
target.clearChosen();
|
||||
}
|
||||
if (cards.size() == 1) {
|
||||
choosingPlayer.moveCardToGraveyardWithInfo(cards.getCards(game).iterator().next(), source.getSourceId(), game, fromZone);
|
||||
choosingPlayer.moveCardToGraveyardWithInfo(cards.getCards(game).iterator().next(), source == null ? null : source.getSourceId(), game, fromZone);
|
||||
}
|
||||
} else {
|
||||
for (Card card : cards.getCards(game)) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue