Merge branch 'master' into Network_Upgrade

This commit is contained in:
betasteward 2015-05-23 14:43:29 -04:00
commit 1a6e0e5d09
102 changed files with 1055 additions and 1002 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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> &mdash; 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;

View file

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

View file

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

View file

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

View file

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

View file

@ -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) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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.
*/

View file

@ -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.2eg.
* 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);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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) {

View file

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

View file

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

View file

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

View file

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

View file

@ -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()) {

View file

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

View file

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

View file

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

View file

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

View file

@ -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,

View file

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

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

View file

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

View file

@ -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);
/**

View file

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