Merge origin/master

This commit is contained in:
jeffwadsworth 2019-01-08 03:35:55 -06:00
commit e15a53bdf2
41 changed files with 941 additions and 382 deletions

View file

@ -1,4 +1,3 @@
package mage.player.ai; package mage.player.ai;
import mage.MageObject; import mage.MageObject;
@ -25,7 +24,6 @@ import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class SimulatedPlayer2 extends ComputerPlayer { public class SimulatedPlayer2 extends ComputerPlayer {
@ -173,6 +171,7 @@ public class SimulatedPlayer2 extends ComputerPlayer {
// allActions.add(new SimulatedAction(sim, actions)); // allActions.add(new SimulatedAction(sim, actions));
// } // }
// } // }
/** /**
* if suggested abilities exist, return only those from playables * if suggested abilities exist, return only those from playables
* *
@ -191,11 +190,13 @@ public class SimulatedPlayer2 extends ComputerPlayer {
List<Ability> filtered = new ArrayList<>(); List<Ability> filtered = new ArrayList<>();
for (Ability ability : playables) { for (Ability ability : playables) {
Card card = game.getCard(ability.getSourceId()); Card card = game.getCard(ability.getSourceId());
for (String s : suggested) { if (card != null) {
if (s.equals(card.getName())) { for (String s : suggested) {
logger.debug("matched: " + s); if (s.equals(card.getName())) {
forced = true; logger.debug("matched: " + s);
filtered.add(ability); forced = true;
filtered.add(ability);
}
} }
} }
} }
@ -216,26 +217,28 @@ public class SimulatedPlayer2 extends ComputerPlayer {
for (Ability option : options) { for (Ability option : options) {
if (!option.getTargets().isEmpty() && option.getTargets().get(0).getMaxNumberOfTargets() == 1) { if (!option.getTargets().isEmpty() && option.getTargets().get(0).getMaxNumberOfTargets() == 1) {
Card card = game.getCard(ability.getSourceId()); Card card = game.getCard(ability.getSourceId());
for (String s : suggested) { if (card != null) {
String[] groups = s.split(";"); for (String s : suggested) {
logger.trace("s=" + s + ";groups=" + groups.length); String[] groups = s.split(";");
if (groups.length == 2) { logger.trace("s=" + s + ";groups=" + groups.length);
if (groups[0].equals(card.getName()) && groups[1].startsWith("name=")) { if (groups.length == 2) {
// extract target and compare to suggested if (groups[0].equals(card.getName()) && groups[1].startsWith("name=")) {
String targetName = groups[1].split("=")[1]; // extract target and compare to suggested
Player player = game.getPlayer(option.getFirstTarget()); String targetName = groups[1].split("=")[1];
if (player != null && targetName.equals(player.getName())) { Player player = game.getPlayer(option.getFirstTarget());
System.out.println("matched(option): " + s); if (player != null && targetName.equals(player.getName())) {
filtered.add(option);
return filtered;
} else {
Card target = game.getCard(option.getFirstTarget());
if (target != null && target.getName().equals(targetName)) {
System.out.println("matched(option): " + s); System.out.println("matched(option): " + s);
filtered.add(option); filtered.add(option);
return filtered; return filtered;
} else {
Card target = game.getCard(option.getFirstTarget());
if (target != null && target.getName().equals(targetName)) {
System.out.println("matched(option): " + s);
filtered.add(option);
return filtered;
}
System.out.println("not equal UUID for target, player=" + player);
} }
System.out.println("not equal UUID for target, player=" + player);
} }
} }
} }

View file

@ -1,19 +1,7 @@
package mage.server.util; package mage.server.util;
import java.io.File;
import java.lang.reflect.Constructor;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.repository.CardCriteria; import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
@ -25,6 +13,16 @@ import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import java.io.File;
import java.lang.reflect.Constructor;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* @author JayDi85 * @author JayDi85
*/ */
@ -111,6 +109,9 @@ public final class SystemUtil {
for (UUID cardID : cardsList) { for (UUID cardID : cardsList) {
Card card = game.getCard(cardID); Card card = game.getCard(cardID);
if (card == null) {
continue;
}
// basic info (card + set) // basic info (card + set)
String cardInfo = card.getName() + " - " + card.getExpansionSetCode(); String cardInfo = card.getName() + " - " + card.getExpansionSetCode();
@ -537,8 +538,8 @@ public final class SystemUtil {
/** /**
* Get a diff between two dates * Get a diff between two dates
* *
* @param date1 the oldest date * @param date1 the oldest date
* @param date2 the newest date * @param date2 the newest date
* @param timeUnit the unit in which you want the diff * @param timeUnit the unit in which you want the diff
* @return the diff value, in the provided unit * @return the diff value, in the provided unit
*/ */

View file

@ -1,8 +1,5 @@
package mage.cards.c; package mage.cards.c;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.Mana; import mage.Mana;
import mage.ObjectColor; import mage.ObjectColor;
@ -30,8 +27,11 @@ import mage.target.TargetCard;
import mage.util.CardUtil; import mage.util.CardUtil;
import mage.util.GameLog; import mage.util.GameLog;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public final class ChromeMox extends CardImpl { public final class ChromeMox extends CardImpl {
@ -141,7 +141,7 @@ class ChromeMoxManaEffect extends ManaEffect {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) { if (permanent != null) {
List<UUID> imprinted = permanent.getImprinted(); List<UUID> imprinted = permanent.getImprinted();
if (!imprinted.isEmpty()) { if (imprinted != null && !imprinted.isEmpty()) {
Card imprintedCard = game.getCard(imprinted.get(0)); Card imprintedCard = game.getCard(imprinted.get(0));
if (imprintedCard != null) { if (imprintedCard != null) {
ObjectColor color = imprintedCard.getColor(game); ObjectColor color = imprintedCard.getColor(game);
@ -172,7 +172,7 @@ class ChromeMoxManaEffect extends ManaEffect {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (permanent != null && player != null) { if (permanent != null && player != null) {
List<UUID> imprinted = permanent.getImprinted(); List<UUID> imprinted = permanent.getImprinted();
if (!imprinted.isEmpty()) { if (imprinted != null && !imprinted.isEmpty()) {
Card imprintedCard = game.getCard(imprinted.get(0)); Card imprintedCard = game.getCard(imprinted.get(0));
if (imprintedCard != null) { if (imprintedCard != null) {
Choice choice = new ChoiceColor(true); Choice choice = new ChoiceColor(true);

View file

@ -115,7 +115,7 @@ class CloneShellDiesEffect extends OneShotEffect {
Permanent permanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); Permanent permanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
if (permanent != null) { if (permanent != null) {
List<UUID> imprinted = permanent.getImprinted(); List<UUID> imprinted = permanent.getImprinted();
if (!imprinted.isEmpty()) { if (imprinted != null && !imprinted.isEmpty()) {
Card imprintedCard = game.getCard(imprinted.get(0)); Card imprintedCard = game.getCard(imprinted.get(0));
if (imprintedCard != null) { if (imprintedCard != null) {
imprintedCard.setFaceDown(false, game); imprintedCard.setFaceDown(false, game);

View file

@ -0,0 +1,144 @@
package mage.cards.d;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.keyword.RiotAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.command.emblems.DomriChaosBringerEmblem;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.stack.Spell;
import mage.target.targetpointer.FixedTarget;
import mage.watchers.Watcher;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DomriChaosBringer extends CardImpl {
public DomriChaosBringer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{R}{G}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.DOMRI);
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// +1: Add {R} or {G}. If that mana is spent on a creature spell, it gains riot.
// TODO: make this into a single ability, also make this, Generator Servant and Hall of the Bandit Lord work without card scope watchers
Mana mana = Mana.RedMana(1);
mana.setFlag(true);
Ability ability = new LoyaltyAbility(new BasicManaEffect(mana).setText("Add {R}. If that mana is spent on a creature spell, it gains riot"), 1);
this.addAbility(ability, new HallOfTheBanditLordWatcher(ability));
mana = Mana.GreenMana(1);
mana.setFlag(true);
ability = new LoyaltyAbility(new BasicManaEffect(mana).setText("Add {G}. If that mana is spent on a creature spell, it gains riot"), 1);
this.addAbility(ability, new HallOfTheBanditLordWatcher(ability));
// 3: Look at the top four cards of your library. You may reveal up to two creature cards from among them and put them into your hand. Put the rest on the bottom of your library in a random order.
this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(
new StaticValue(4), false, new StaticValue(2),
StaticFilters.FILTER_CARD_CREATURE, Zone.LIBRARY, false,
true, false, Zone.HAND, false, false, false
).setText(
"Look at the top four cards of your library. " +
"You may reveal up to two creature cards from among them " +
"and put them into your hand. Put the rest on the bottom of your library " +
"in a random order."
), -3));
// 8: You get an emblem with "At the beginning of each end step, create a 4/4 red and green Beast creature token with trample."
this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new DomriChaosBringerEmblem()), -8));
}
private DomriChaosBringer(final DomriChaosBringer card) {
super(card);
}
@Override
public DomriChaosBringer copy() {
return new DomriChaosBringer(this);
}
}
class HallOfTheBanditLordWatcher extends Watcher {
private final Ability source;
private final List<UUID> creatures = new ArrayList<>();
HallOfTheBanditLordWatcher(Ability source) {
super(HallOfTheBanditLordWatcher.class.getSimpleName(), WatcherScope.CARD);
this.source = source;
}
private HallOfTheBanditLordWatcher(final HallOfTheBanditLordWatcher watcher) {
super(watcher);
this.creatures.addAll(watcher.creatures);
this.source = watcher.source;
}
@Override
public HallOfTheBanditLordWatcher copy() {
return new HallOfTheBanditLordWatcher(this);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.MANA_PAID) {
MageObject target = game.getObject(event.getTargetId());
if (event.getSourceId() != null
&& event.getSourceId().equals(this.getSourceId())
&& target != null && target.isCreature()
&& event.getFlag()) {
if (target instanceof Spell) {
this.creatures.add(((Spell) target).getCard().getId());
}
}
}
if (event.getType() == GameEvent.EventType.COUNTERED) {
if (creatures.contains(event.getTargetId())) {
creatures.remove(event.getSourceId());
}
}
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
if (creatures.contains(event.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
// spell was e.g. exiled and goes again to stack, so previous cast has not resolved.
if (zEvent.getToZone() == Zone.STACK) {
creatures.remove(event.getSourceId());
}
}
}
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
if (creatures.contains(event.getSourceId())) {
ContinuousEffect effect = new GainAbilityTargetEffect(new RiotAbility(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
game.addEffect(effect, source);
creatures.remove(event.getSourceId());
}
}
}
@Override
public void reset() {
super.reset();
creatures.clear();
}
}

View file

@ -1,8 +1,5 @@
package mage.cards.d; package mage.cards.d;
import java.util.List;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -22,8 +19,10 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.List;
import java.util.UUID;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public final class Duplicant extends CardImpl { public final class Duplicant extends CardImpl {
@ -117,6 +116,9 @@ class DuplicantContinuousEffect extends ContinuousEffectImpl {
if (permanent != null) { if (permanent != null) {
if (!permanent.getImprinted().isEmpty()) { if (!permanent.getImprinted().isEmpty()) {
List<UUID> imprinted = permanent.getImprinted(); List<UUID> imprinted = permanent.getImprinted();
if (imprinted == null || imprinted.isEmpty()) {
return false;
}
Card card = game.getCard(imprinted.get(imprinted.size() - 1)); Card card = game.getCard(imprinted.get(imprinted.size() - 1));
if (card != null && card.isCreature()) { if (card != null && card.isCreature()) {
switch (layer) { switch (layer) {
@ -134,7 +136,6 @@ class DuplicantContinuousEffect extends ContinuousEffectImpl {
} }
} }
return true; return true;
} }
} }

View file

@ -0,0 +1,152 @@
package mage.cards.g;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardIdPredicate;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.other.OwnerIdPredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GuardianProject extends CardImpl {
public GuardianProject(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}");
// Whenever a nontoken creature enters the battlefield under your control, if that creature does not have the same name as another creature you control or a creature card in your graveyard, draw a card.
this.addAbility(new GuardianProjectTriggeredAbility());
}
private GuardianProject(final GuardianProject card) {
super(card);
}
@Override
public GuardianProject copy() {
return new GuardianProject(this);
}
}
class GuardianProjectTriggeredAbility extends EntersBattlefieldAllTriggeredAbility {
public static final FilterPermanent filter = new FilterControlledCreaturePermanent();
static {
filter.add(Predicates.not(new TokenPredicate()));
}
GuardianProjectTriggeredAbility() {
super(new GuardianProjectEffect(null), filter);
}
private GuardianProjectTriggeredAbility(final GuardianProjectTriggeredAbility ability) {
super(ability);
}
@Override
public GuardianProjectTriggeredAbility copy() {
return new GuardianProjectTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = ((ZoneChangeEvent) event).getTarget();
if (!filter.match(permanent, sourceId, controllerId, game)) {
return false;
}
if (checkCondition(permanent, controllerId, game)) {
this.getEffects().clear();
this.addEffect(new GuardianProjectEffect(new MageObjectReference(permanent, game)));
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever a nontoken creature enters the battlefield under your control, " +
"if that creature does not have the same name as another creature you control " +
"or a creature card in your graveyard, draw a card.";
}
// This is needed as checkInterveningIfClause can't access trigger event information
static boolean checkCondition(Permanent permanent, UUID controllerId, Game game) {
Player player = game.getPlayer(controllerId);
if (player == null) {
return false;
}
if (!permanent.getName().equals("")) {
FilterCard filterCard = new FilterCard();
filterCard.add(new NamePredicate(permanent.getName()));
filterCard.add(new OwnerIdPredicate(controllerId));
if (player.getGraveyard().count(filterCard, game) > 0) {
return false;
}
}
FilterPermanent filterPermanent = new FilterCreaturePermanent();
filterPermanent.add(new NamePredicate(permanent.getName()));
filterPermanent.add(Predicates.not(new CardIdPredicate(permanent.getId())));
filterPermanent.add(new ControllerIdPredicate(controllerId));
if (game.getBattlefield().getActivePermanents(filterPermanent, controllerId, game).size() > 0) {
return false;
}
return true;
}
}
class GuardianProjectEffect extends OneShotEffect {
private final MageObjectReference mor;
GuardianProjectEffect(MageObjectReference mor) {
super(Outcome.Benefit);
this.mor = mor;
}
private GuardianProjectEffect(final GuardianProjectEffect effect) {
super(effect);
this.mor = effect.mor;
}
@Override
public GuardianProjectEffect copy() {
return new GuardianProjectEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
if (GuardianProjectTriggeredAbility.checkCondition(
mor.getPermanentOrLKIBattlefield(game), source.getControllerId(), game)
) {
player.drawCards(1, game);
return true;
}
return false;
}
}

View file

@ -58,6 +58,7 @@ class HintOfInsanityEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
FilterCard filter = new FilterCard("card from your hand"); FilterCard filter = new FilterCard("card from your hand");
Player targetPlayer = game.getPlayer(source.getFirstTarget()); Player targetPlayer = game.getPlayer(source.getFirstTarget());
Card chosenCard;
if (targetPlayer != null) { if (targetPlayer != null) {
TargetCardInHand targetCard = new TargetCardInHand(filter); TargetCardInHand targetCard = new TargetCardInHand(filter);
targetCard.setNotTarget(true); targetCard.setNotTarget(true);
@ -66,12 +67,10 @@ class HintOfInsanityEffect extends OneShotEffect {
targetPlayer.revealCards("Hint of Insanity Reveal", cardsInHand, game); targetPlayer.revealCards("Hint of Insanity Reveal", cardsInHand, game);
if (!cardsInHand.isEmpty() if (!cardsInHand.isEmpty()
&& targetPlayer.choose(Outcome.Discard, targetCard, source.getSourceId(), game)) { && targetPlayer.choose(Outcome.Discard, targetCard, source.getSourceId(), game)) {
Card chosenCard = game.getCard(targetCard.getFirstTarget()); chosenCard = game.getCard(targetCard.getFirstTarget());
if (chosenCard != null) { for (Card card : cardsInHand.getCards(game)) {
for (Card card : cardsInHand.getCards(game)) { if (CardUtil.haveSameNames(card, chosenCard) && !card.isLand()) {
if (CardUtil.haveSameNames(card, chosenCard) && !card.isLand()) { targetPlayer.discard(card, source, game);
targetPlayer.discard(card, source, game);
}
} }
} }
return true; return true;

View file

@ -0,0 +1,69 @@
package mage.cards.k;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class KayasWrath extends CardImpl {
public KayasWrath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}{W}{B}{B}");
// Destroy all creatures. You gain life equal to the number of creatures you controlled that were destroyed this way.
this.getSpellAbility().addEffect(new KayasWrathEffect());
}
private KayasWrath(final KayasWrath card) {
super(card);
}
@Override
public KayasWrath copy() {
return new KayasWrath(this);
}
}
class KayasWrathEffect extends OneShotEffect {
KayasWrathEffect() {
super(Outcome.Benefit);
staticText = "Destroy all creatures. You gain life equal to the number of " +
"creatures you controlled that were destroyed this way.";
}
private KayasWrathEffect(final KayasWrathEffect effect) {
super(effect);
}
@Override
public KayasWrathEffect copy() {
return new KayasWrathEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
int counter = 0;
for (Permanent permanent : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_PERMANENT_CREATURE,
source.getControllerId(), source.getSourceId(), game
)) {
boolean isMine = permanent != null && permanent.getControllerId().equals(source.getControllerId());
if (permanent.destroy(source.getSourceId(), game, false) && isMine) {
counter++;
}
}
return new GainLifeEffect(counter).apply(game, source);
}
}

View file

@ -1,7 +1,5 @@
package mage.cards.n; package mage.cards.n;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -16,12 +14,7 @@ import mage.abilities.keyword.TrampleAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
@ -32,8 +25,9 @@ import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import java.util.UUID;
/** /**
*
* @author L_J * @author L_J
*/ */
public final class NamelessRace extends CardImpl { public final class NamelessRace extends CardImpl {
@ -94,13 +88,13 @@ class NamelessRaceEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
Card sourceCard = game.getCard(source.getSourceId());
int permanentsInPlay = new PermanentsOnBattlefieldCount(filter).calculate(game, source, null); int permanentsInPlay = new PermanentsOnBattlefieldCount(filter).calculate(game, source, null);
int cardsInGraveyards = new CardsInAllGraveyardsCount(filter2).calculate(game, source, null); int cardsInGraveyards = new CardsInAllGraveyardsCount(filter2).calculate(game, source, null);
int maxAmount = Math.min(permanentsInPlay + cardsInGraveyards, controller.getLife()); int maxAmount = Math.min(permanentsInPlay + cardsInGraveyards, controller.getLife());
int payAmount = controller.getAmount(0, maxAmount, "Pay up to " + maxAmount + " life", game); int payAmount = controller.getAmount(0, maxAmount, "Pay up to " + maxAmount + " life", game);
controller.loseLife(payAmount, game, false); controller.loseLife(payAmount, game, false);
game.informPlayers(sourceCard.getLogName() + ": " + controller.getLogName() + Card sourceCard = game.getCard(source.getSourceId());
game.informPlayers((sourceCard != null ? sourceCard.getLogName() : "") + ": " + controller.getLogName() +
" pays " + payAmount + " life"); " pays " + payAmount + " life");
game.addEffect(new SetPowerToughnessSourceEffect(payAmount, payAmount, Duration.Custom, SubLayer.SetPT_7b), source); game.addEffect(new SetPowerToughnessSourceEffect(payAmount, payAmount, Duration.Custom, SubLayer.SetPT_7b), source);
return true; return true;

View file

@ -1,14 +1,8 @@
package mage.cards.n; package mage.cards.n;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
@ -18,14 +12,15 @@ import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class Nightsnare extends CardImpl { public final class Nightsnare extends CardImpl {
public Nightsnare(UUID ownerId, CardSetInfo setInfo) { public Nightsnare(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// Target opponent reveals their hand. You may choose a nonland card from it. If you do, that player discards that card. If you don't, that player discards two cards. // Target opponent reveals their hand. You may choose a nonland card from it. If you do, that player discards that card. If you don't, that player discards two cards.
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
@ -57,11 +52,11 @@ class NightsnareDiscardEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player player = game.getPlayer(targetPointer.getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId());
if (player != null && controller != null) { if (player != null && controller != null) {
if (!player.getHand().isEmpty()) { if (!player.getHand().isEmpty()) {
Cards revealedCards = new CardsImpl(); Cards revealedCards = new CardsImpl();
revealedCards.addAll(player.getHand()); revealedCards.addAll(player.getHand());
Card sourceCard = game.getCard(source.getSourceId());
player.revealCards(sourceCard != null ? sourceCard.getIdName() : "Discard", revealedCards, game); player.revealCards(sourceCard != null ? sourceCard.getIdName() : "Discard", revealedCards, game);
// You may choose a nonland card from it. // You may choose a nonland card from it.
if (controller.chooseUse(outcome, "Choose a a card to discard? (Otherwise " + player.getLogName() + " has to discard 2 cards).", source, game)) { if (controller.chooseUse(outcome, "Choose a a card to discard? (Otherwise " + player.getLogName() + " has to discard 2 cards).", source, game)) {

View file

@ -0,0 +1,88 @@
package mage.cards.n;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.TapForManaAllTriggeredManaAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.mana.AddManaOfAnyTypeProducedEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class NikyaOfTheOldWays extends CardImpl {
public NikyaOfTheOldWays(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CENTAUR);
this.subtype.add(SubType.DRUID);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// You can't cast noncreature spells.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD, new NikyaOfTheOldWaysCantCastEffect()
));
// Whenever you tap a land for mana, add one mana of any type that land produced.
AddManaOfAnyTypeProducedEffect effect = new AddManaOfAnyTypeProducedEffect();
effect.setText("add one mana of any type that land produced");
this.addAbility(new TapForManaAllTriggeredManaAbility(
effect,
new FilterControlledLandPermanent("you tap a land"),
SetTargetPointer.PERMANENT)
);
}
private NikyaOfTheOldWays(final NikyaOfTheOldWays card) {
super(card);
}
@Override
public NikyaOfTheOldWays copy() {
return new NikyaOfTheOldWays(this);
}
}
class NikyaOfTheOldWaysCantCastEffect extends ContinuousRuleModifyingEffectImpl {
NikyaOfTheOldWaysCantCastEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = "You can't cast noncreature spells";
}
private NikyaOfTheOldWaysCantCastEffect(final NikyaOfTheOldWaysCantCastEffect effect) {
super(effect);
}
@Override
public NikyaOfTheOldWaysCantCastEffect copy() {
return new NikyaOfTheOldWaysCantCastEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CAST_SPELL;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getPlayerId().equals(source.getControllerId())) {
Card card = game.getCard(event.getSourceId());
return card != null && !card.isCreature();
}
return false;
}
}

View file

@ -1,8 +1,5 @@
package mage.cards.n; package mage.cards.n;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.common.FightTargetsEffect; import mage.abilities.effects.common.FightTargetsEffect;
import mage.cards.Card; import mage.cards.Card;
@ -19,6 +16,9 @@ import mage.game.stack.Spell;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import java.util.Set;
import java.util.UUID;
/** /**
* @author Styxo * @author Styxo
*/ */
@ -56,8 +56,11 @@ class TargetCreatureWithLessPowerPermanent extends TargetPermanent {
@Override @Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
int maxPower = Integer.MIN_VALUE; // get the most poerful controlled creature that can be targeted int maxPower = Integer.MIN_VALUE; // get the most powerful controlled creature that can be targeted
Card sourceCard = game.getCard(sourceId); Card sourceCard = game.getCard(sourceId);
if (sourceCard == null) {
return false;
}
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURES, sourceControllerId, game)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURES, sourceControllerId, game)) {
if (permanent.getPower().getValue() > maxPower && permanent.canBeTargetedBy(sourceCard, sourceControllerId, game)) { if (permanent.getPower().getValue() > maxPower && permanent.canBeTargetedBy(sourceCard, sourceControllerId, game)) {
maxPower = permanent.getPower().getValue(); maxPower = permanent.getPower().getValue();

View file

@ -1,7 +1,5 @@
package mage.cards.p; package mage.cards.p;
import java.util.UUID;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
@ -10,23 +8,19 @@ import mage.abilities.keyword.FlashbackAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.TimingRule;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import java.util.UUID;
/** /**
*
* @author BetaSteward * @author BetaSteward
*/ */
public final class PastInFlames extends CardImpl { public final class PastInFlames extends CardImpl {
public PastInFlames(UUID ownerId, CardSetInfo setInfo) { public PastInFlames(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
// Each instant and sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost. // Each instant and sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost.
@ -72,7 +66,7 @@ class PastInFlamesEffect extends ContinuousEffectImpl {
player.getGraveyard().stream().map((cardId) -> game.getCard(cardId)).filter((card) -> (card.isInstant() || card.isSorcery())).forEachOrdered((card) -> { player.getGraveyard().stream().map((cardId) -> game.getCard(cardId)).filter((card) -> (card.isInstant() || card.isSorcery())).forEachOrdered((card) -> {
affectedObjectList.add(new MageObjectReference(card, game)); affectedObjectList.add(new MageObjectReference(card, game));
}); });
} }
} }
} }
@ -82,17 +76,18 @@ class PastInFlamesEffect extends ContinuousEffectImpl {
if (player != null) { if (player != null) {
player.getGraveyard().stream().filter((cardId) -> (affectedObjectList.contains(new MageObjectReference(cardId, game)))).forEachOrdered((cardId) -> { player.getGraveyard().stream().filter((cardId) -> (affectedObjectList.contains(new MageObjectReference(cardId, game)))).forEachOrdered((cardId) -> {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
FlashbackAbility ability = null; if (card != null) {
if (card.isInstant()) { FlashbackAbility ability = null;
ability = new FlashbackAbility(card.getManaCost(), TimingRule.INSTANT); if (card.isInstant()) {
} ability = new FlashbackAbility(card.getManaCost(), TimingRule.INSTANT);
else if (card.isSorcery()) { } else if (card.isSorcery()) {
ability = new FlashbackAbility(card.getManaCost(), TimingRule.SORCERY); ability = new FlashbackAbility(card.getManaCost(), TimingRule.SORCERY);
} }
if (ability != null) { if (ability != null) {
ability.setSourceId(cardId); ability.setSourceId(cardId);
ability.setControllerId(card.getOwnerId()); ability.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability); game.getState().addOtherAbility(card, ability);
}
} }
}); });
return true; return true;

View file

@ -1,7 +1,5 @@
package mage.cards.p; package mage.cards.p;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -19,14 +17,15 @@ import mage.game.permanent.token.MinionToken;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author FenrisulfrX * @author FenrisulfrX
*/ */
public final class PhyrexianProcessor extends CardImpl { public final class PhyrexianProcessor extends CardImpl {
public PhyrexianProcessor(UUID ownerId, CardSetInfo setInfo) { public PhyrexianProcessor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// As {this} enters the battlefield, pay any amount of life. // As {this} enters the battlefield, pay any amount of life.
this.addAbility(new EntersBattlefieldTriggeredAbility(new PhyrexianProcessorEffect())); this.addAbility(new EntersBattlefieldTriggeredAbility(new PhyrexianProcessorEffect()));
@ -65,11 +64,11 @@ class PhyrexianProcessorEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if(controller != null) { if (controller != null) {
Card sourceCard = game.getCard(source.getSourceId());
int payAmount = controller.getAmount(0, controller.getLife(), staticText, game); int payAmount = controller.getAmount(0, controller.getLife(), staticText, game);
controller.loseLife(payAmount, game, false); controller.loseLife(payAmount, game, false);
game.informPlayers(sourceCard.getName() + ": " + controller.getLogName() + Card sourceCard = game.getCard(source.getSourceId());
game.informPlayers((sourceCard != null ? sourceCard.getName() : "") + ": " + controller.getLogName() +
" pays " + payAmount + " life."); " pays " + payAmount + " life.");
String key = CardUtil.getCardZoneString("lifePaid", source.getSourceId(), game); String key = CardUtil.getCardZoneString("lifePaid", source.getSourceId(), game);
game.getState().setValue(key, payAmount); game.getState().setValue(key, payAmount);
@ -99,7 +98,7 @@ class PhyrexianProcessorCreateTokenEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
String key = CardUtil.getCardZoneString("lifePaid", source.getSourceId(), game); String key = CardUtil.getCardZoneString("lifePaid", source.getSourceId(), game);
Object object = game.getState().getValue(key); Object object = game.getState().getValue(key);
if(object instanceof Integer) { if (object instanceof Integer) {
int lifePaid = (int) object; int lifePaid = (int) object;
MinionToken token = new MinionToken(); MinionToken token = new MinionToken();
token.getPower().modifyBaseValue(lifePaid); token.getPower().modifyBaseValue(lifePaid);

View file

@ -1,9 +1,5 @@
package mage.cards.p; package mage.cards.p;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
@ -16,14 +12,17 @@ import mage.game.permanent.token.RatToken;
import mage.players.Player; import mage.players.Player;
import mage.players.PlayerList; import mage.players.PlayerList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class PlagueOfVermin extends CardImpl { public final class PlagueOfVermin extends CardImpl {
public PlagueOfVermin(UUID ownerId, CardSetInfo setInfo) { public PlagueOfVermin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{6}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{B}");
// Starting with you, each player may pay any amount of life. Repeat this process until no one pays life. Each player creates a 1/1 black Rat creature token for each 1 life he or she paid this way. // Starting with you, each player may pay any amount of life. Repeat this process until no one pays life. Each player creates a 1/1 black Rat creature token for each 1 life he or she paid this way.
@ -60,7 +59,6 @@ class PlagueOfVerminEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId());
Map<UUID, Integer> payLife = new HashMap<>(); Map<UUID, Integer> payLife = new HashMap<>();
int currentLifePaid; int currentLifePaid;
int totalPaidLife; int totalPaidLife;
@ -90,7 +88,8 @@ class PlagueOfVerminEffect extends OneShotEffect {
payLife.put(currentPlayer.getId(), currentLifePaid + totalPaidLife); payLife.put(currentPlayer.getId(), currentLifePaid + totalPaidLife);
} }
} }
game.informPlayers(sourceCard.getName() + ": " + currentPlayer.getLogName() + " pays " + payLife.get(currentPlayer.getId()) + " life"); Card sourceCard = game.getCard(source.getSourceId());
game.informPlayers((sourceCard != null ? sourceCard.getName() : "") + ": " + currentPlayer.getLogName() + " pays " + payLife.get(currentPlayer.getId()) + " life");
firstInactivePlayer = null; firstInactivePlayer = null;
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.p; package mage.cards.p;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
@ -23,6 +21,8 @@ import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/** /**
* @author North * @author North
*/ */
@ -76,13 +76,11 @@ class PostmortemLungeEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Card card = game.getCard(source.getFirstTarget()); Card card = game.getCard(source.getFirstTarget());
if (card != null) { if (card != null) {
Player cardOwner = game.getPlayer(card.getOwnerId()); Player cardOwner = game.getPlayer(card.getOwnerId());
if (cardOwner == null) { if (cardOwner == null) {
return false; return false;
} }
if (cardOwner.moveCards(card, Zone.BATTLEFIELD, source, game)) { if (cardOwner.moveCards(card, Zone.BATTLEFIELD, source, game)) {
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) { if (permanent != null) {
@ -96,7 +94,6 @@ class PostmortemLungeEffect extends OneShotEffect {
} }
return true; return true;
} }
return false; return false;
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.p; package mage.cards.p;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
@ -17,15 +15,15 @@ import mage.players.Player;
import mage.target.TargetSpell; import mage.target.TargetSpell;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*
*/ */
public final class PutAway extends CardImpl { public final class PutAway extends CardImpl {
public PutAway(UUID ownerId, CardSetInfo setInfo) { public PutAway(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}{U}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}");
// Counter target spell. You may shuffle up to one target card from your graveyard into your library. // Counter target spell. You may shuffle up to one target card from your graveyard into your library.
@ -66,15 +64,14 @@ class PutAwayEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Spell spell = game.getStack().getSpell(source.getFirstTarget()); Spell spell = game.getStack().getSpell(source.getFirstTarget());
Card card = game.getCard(source.getTargets().get(1).getFirstTarget()); if (spell != null && game.getStack().counter(spell.getId(), source.getSourceId(), game)) {
Player you = game.getPlayer(source.getControllerId());
if (spell != null
&& game.getStack().counter(spell.getId(), source.getSourceId(), game)) {
countered = true; countered = true;
} }
if (you != null) {
if (card != null Card card = game.getCard(source.getTargets().get(1).getFirstTarget());
&& you.chooseUse(Outcome.Benefit, "Do you wish to shuffle up to one target card from your graveyard into your library?", source, game) Player you = game.getPlayer(source.getControllerId());
if (you != null && card != null) {
if (you.chooseUse(Outcome.Benefit, "Do you wish to shuffle up to one target card from your graveyard into your library?", source, game)
&& game.getState().getZone(card.getId()).match(Zone.GRAVEYARD)) { && game.getState().getZone(card.getId()).match(Zone.GRAVEYARD)) {
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
you.shuffleLibrary(source, game); you.shuffleLibrary(source, game);

View file

@ -5,8 +5,6 @@ import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.RevealHandSourceControllerEffect;
import mage.abilities.effects.common.RevealHandTargetEffect;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.*; import mage.cards.*;
@ -23,7 +21,6 @@ import mage.target.common.TargetOpponent;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author noahg * @author noahg
*/ */
public final class RakdosAugermage extends CardImpl { public final class RakdosAugermage extends CardImpl {
@ -71,16 +68,16 @@ class RakdosAugermageEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player player = game.getPlayer(targetPointer.getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId());
if (player != null && controller != null) { if (player != null && controller != null) {
Cards revealedCards = new CardsImpl(); Cards revealedCards = new CardsImpl();
revealedCards.addAll(controller.getHand()); revealedCards.addAll(controller.getHand());
player.revealCards((sourceCard != null ? sourceCard.getIdName() + " (" + sourceCard.getZoneChangeCounter(game) + ") (" : "Discard (")+controller.getName()+")", revealedCards, game); Card sourceCard = game.getCard(source.getSourceId());
player.revealCards((sourceCard != null ? sourceCard.getIdName() + " (" + sourceCard.getZoneChangeCounter(game) + ") (" : "Discard (") + controller.getName() + ")", revealedCards, game);
TargetCard target = new TargetCard(Zone.HAND, new FilterCard()); TargetCard target = new TargetCard(Zone.HAND, new FilterCard());
if (player.choose(Outcome.Benefit, revealedCards, target, game)) { if (player.choose(Outcome.Benefit, revealedCards, target, game)) {
Card card = revealedCards.get(target.getFirstTarget(), game); Card card = revealedCards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
return player.discard(card, source, game); return player.discard(card, source, game);
} }
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.r; package mage.cards.r;
import java.util.UUID;
import mage.ConditionalMana; import mage.ConditionalMana;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
@ -14,14 +12,10 @@ import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.mana.ConditionalColorlessManaAbility; import mage.abilities.mana.ConditionalColorlessManaAbility;
import mage.abilities.mana.builder.ConditionalManaBuilder; import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.cards.Card; import mage.cards.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
@ -30,14 +24,15 @@ import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class RenownedWeaponsmith extends CardImpl { public final class RenownedWeaponsmith extends CardImpl {
public RenownedWeaponsmith(UUID ownerId, CardSetInfo setInfo) { public RenownedWeaponsmith(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ARTIFICER); this.subtype.add(SubType.ARTIFICER);
this.power = new MageInt(1); this.power = new MageInt(1);
@ -120,11 +115,14 @@ class RenownedWeaponsmithEffect extends OneShotEffect {
TargetCardInLibrary target = new TargetCardInLibrary(filter); TargetCardInLibrary target = new TargetCardInLibrary(filter);
if (controller.searchLibrary(target, game)) { if (controller.searchLibrary(target, game)) {
if (!target.getTargets().isEmpty()) { if (!target.getTargets().isEmpty()) {
Card card = game.getCard(target.getFirstTarget());
Cards revealed = new CardsImpl(); Cards revealed = new CardsImpl();
revealed.add(card); Card card = game.getCard(target.getFirstTarget());
controller.revealCards(sourceObject.getIdName(), revealed, game); if (card != null) {
controller.moveCards(revealed, Zone.HAND, source, game); revealed.add(card);
controller.revealCards(sourceObject.getIdName(), revealed, game);
controller.moveCards(revealed, Zone.HAND, source, game);
}
} }
} }
controller.shuffleLibrary(source, game); controller.shuffleLibrary(source, game);

View file

@ -1,8 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -21,6 +18,9 @@ import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.List;
import java.util.UUID;
/** /**
* @author nantuko * @author nantuko
*/ */
@ -113,11 +113,9 @@ class SemblanceAnvilCostReductionEffect extends CostModificationEffectImpl {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) { if (permanent != null) {
List<UUID> imprinted = permanent.getImprinted(); List<UUID> imprinted = permanent.getImprinted();
if (!imprinted.isEmpty()) { if (imprinted != null && !imprinted.isEmpty()) {
Card imprintedCard = game.getCard(imprinted.get(0)); Card imprintedCard = game.getCard(imprinted.get(0));
if (imprintedCard != null && imprintedCard.shareTypes(sourceCard)) { return imprintedCard != null && imprintedCard.shareTypes(sourceCard);
return true;
}
} }
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
@ -15,19 +13,20 @@ import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInASingleGraveyard; import mage.target.common.TargetCardInASingleGraveyard;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class SereneRemembrance extends CardImpl { public final class SereneRemembrance extends CardImpl {
public SereneRemembrance (UUID ownerId, CardSetInfo setInfo) { public SereneRemembrance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{G}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}");
// Shuffle Serene Remembrance and up to three target cards from a single graveyard into their owners' libraries. // Shuffle Serene Remembrance and up to three target cards from a single graveyard into their owners' libraries.
this.getSpellAbility().addEffect(new SereneRemembranceEffect()); this.getSpellAbility().addEffect(new SereneRemembranceEffect());
this.getSpellAbility().addTarget(new TargetCardInASingleGraveyard(0,3,new FilterCard("up to three target cards from a single graveyard"))); this.getSpellAbility().addTarget(new TargetCardInASingleGraveyard(0, 3, new FilterCard("up to three target cards from a single graveyard")));
} }
@ -36,7 +35,7 @@ public final class SereneRemembrance extends CardImpl {
} }
@Override @Override
public SereneRemembrance copy() { public SereneRemembrance copy() {
return new SereneRemembrance(this); return new SereneRemembrance(this);
} }
} }
@ -60,6 +59,8 @@ class SereneRemembranceEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
boolean result = false; boolean result = false;
// 3 cards to graveyard
Player graveyardPlayer = null; Player graveyardPlayer = null;
for (UUID cardInGraveyard : targetPointer.getTargets(game, source)) { for (UUID cardInGraveyard : targetPointer.getTargets(game, source)) {
Card card = game.getCard(cardInGraveyard); Card card = game.getCard(cardInGraveyard);
@ -73,15 +74,20 @@ class SereneRemembranceEffect extends OneShotEffect {
} }
} }
} }
// source card to graveyard
Card card = game.getCard(source.getSourceId()); Card card = game.getCard(source.getSourceId());
result |= card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); if (card != null) {
Player player = game.getPlayer(card.getOwnerId()); result |= card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
if (player != null){ Player player = game.getPlayer(card.getOwnerId());
player.shuffleLibrary(source, game); if (player != null) {
} player.shuffleLibrary(source, game);
if (graveyardPlayer != null && !graveyardPlayer.equals(player)) { }
graveyardPlayer.shuffleLibrary(source, game); if (graveyardPlayer != null && !graveyardPlayer.equals(player)) {
graveyardPlayer.shuffleLibrary(source, game);
}
} }
return result; return result;
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
@ -13,11 +11,7 @@ import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEf
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
@ -25,8 +19,9 @@ import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/** /**
*
* @author emerald000 * @author emerald000
*/ */
public final class ShireiShizosCaretaker extends CardImpl { public final class ShireiShizosCaretaker extends CardImpl {
@ -78,8 +73,8 @@ class ShireiShizosCaretakerTriggeredAbility extends TriggeredAbilityImpl {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event; ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
Permanent LKIpermanent = game.getPermanentOrLKIBattlefield(zEvent.getTargetId()); Permanent LKIpermanent = game.getPermanentOrLKIBattlefield(zEvent.getTargetId());
Card card = game.getCard(zEvent.getTargetId()); Card card = game.getCard(zEvent.getTargetId());
if (card != null
if (card != null && LKIpermanent != null && LKIpermanent != null
&& card.isOwnedBy(this.controllerId) && card.isOwnedBy(this.controllerId)
&& zEvent.getToZone() == Zone.GRAVEYARD && zEvent.getToZone() == Zone.GRAVEYARD
&& zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getFromZone() == Zone.BATTLEFIELD

View file

@ -1,16 +1,10 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
@ -23,14 +17,15 @@ import mage.players.Player;
import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import java.util.UUID;
/** /**
*
* @author LoneFox * @author LoneFox
*/ */
public final class ShroudedLore extends CardImpl { public final class ShroudedLore extends CardImpl {
public ShroudedLore(UUID ownerId, CardSetInfo setInfo) { public ShroudedLore(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
// Target opponent chooses a card in your graveyard. You may pay {B}. If you do, repeat this process except that opponent can't choose a card already chosen for Shrouded Lore. Then put the last chosen card into your hand. // Target opponent chooses a card in your graveyard. You may pay {B}. If you do, repeat this process except that opponent can't choose a card already chosen for Shrouded Lore. Then put the last chosen card into your hand.
this.getSpellAbility().addEffect(new ShroudedLoreEffect()); this.getSpellAbility().addEffect(new ShroudedLoreEffect());
@ -67,8 +62,7 @@ class ShroudedLoreEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId()); Player you = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); Player opponent = game.getPlayer(targetPointer.getFirst(game, source));
if(you != null && opponent != null) if (you != null && opponent != null) {
{
FilterCard filter = new FilterCard(); FilterCard filter = new FilterCard();
filter.add(new OwnerIdPredicate(you.getId())); filter.add(new OwnerIdPredicate(you.getId()));
Cost cost = new ManaCostsImpl("{B}"); Cost cost = new ManaCostsImpl("{B}");
@ -78,31 +72,31 @@ class ShroudedLoreEffect extends OneShotEffect {
do { do {
chosenCard = new TargetCardInGraveyard(filter); chosenCard = new TargetCardInGraveyard(filter);
chosenCard.setNotTarget(true); chosenCard.setNotTarget(true);
if(chosenCard.canChoose(opponent.getId(), game)) { if (chosenCard.canChoose(opponent.getId(), game)) {
opponent.chooseTarget(Outcome.ReturnToHand, chosenCard, source, game); opponent.chooseTarget(Outcome.ReturnToHand, chosenCard, source, game);
card = game.getCard(chosenCard.getFirstTarget()); card = game.getCard(chosenCard.getFirstTarget());
filter.add(Predicates.not(new CardIdPredicate(card.getId()))); if (card != null) {
game.informPlayers("Shrouded Lore: " + opponent.getLogName() + " has chosen " + card.getLogName()); filter.add(Predicates.not(new CardIdPredicate(card.getId())));
} game.informPlayers("Shrouded Lore: " + opponent.getLogName() + " has chosen " + card.getLogName());
else { }
} else {
done = true; done = true;
} }
if(!done) { if (!done) {
if(cost.canPay(source, source.getSourceId(), you.getId(), game) && you.chooseUse(Outcome.Benefit, "Pay {B} to choose a different card ?", source, game)) { if (cost.canPay(source, source.getSourceId(), you.getId(), game) && you.chooseUse(Outcome.Benefit, "Pay {B} to choose a different card ?", source, game)) {
cost.clearPaid(); cost.clearPaid();
if(!cost.pay(source, game, source.getSourceId(), you.getId(), false, null)) { if (!cost.pay(source, game, source.getSourceId(), you.getId(), false, null)) {
done = true; done = true;
} }
} } else {
else {
done = true; done = true;
} }
} }
} while(!done); } while (!done);
if(card != null) { if (card != null) {
Cards cardsToHand = new CardsImpl(); Cards cardsToHand = new CardsImpl();
cardsToHand.add(card); cardsToHand.add(card);
you.moveCards(cardsToHand, Zone.HAND, source, game); you.moveCards(cardsToHand, Zone.HAND, source, game);

View file

@ -1,8 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.LinkedList;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -14,11 +11,7 @@ import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
@ -30,8 +23,10 @@ import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.LinkedList;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class SistersOfStoneDeath extends CardImpl { public final class SistersOfStoneDeath extends CardImpl {
@ -39,7 +34,7 @@ public final class SistersOfStoneDeath extends CardImpl {
private UUID exileId = UUID.randomUUID(); private UUID exileId = UUID.randomUUID();
public SistersOfStoneDeath(UUID ownerId, CardSetInfo setInfo) { public SistersOfStoneDeath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}{G}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}{G}{G}");
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GORGON); this.subtype.add(SubType.GORGON);
@ -100,7 +95,9 @@ class SistersOfStoneDeathEffect extends OneShotEffect {
LinkedList<UUID> cards = new LinkedList<>(exile); LinkedList<UUID> cards = new LinkedList<>(exile);
for (UUID cardId : cards) { for (UUID cardId : cards) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
cardsInExile.add(card); if (card != null) {
cardsInExile.add(card);
}
} }
if (controller.choose(Outcome.PutCreatureInPlay, cardsInExile, target, game)) { if (controller.choose(Outcome.PutCreatureInPlay, cardsInExile, target, game)) {
Card chosenCard = game.getCard(target.getFirstTarget()); Card chosenCard = game.getCard(target.getFirstTarget());

View file

@ -0,0 +1,97 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SphinxOfNewPrahv extends CardImpl {
public SphinxOfNewPrahv(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}{U}{U}");
this.subtype.add(SubType.SPHINX);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Spells your opponents cast that target Sphinx of New Prahv cost {2} more to cast.
this.addAbility(new SimpleStaticAbility(new SphinxOfNewPrahvCostIncreaseEffect()));
}
private SphinxOfNewPrahv(final SphinxOfNewPrahv card) {
super(card);
}
@Override
public SphinxOfNewPrahv copy() {
return new SphinxOfNewPrahv(this);
}
}
class SphinxOfNewPrahvCostIncreaseEffect extends CostModificationEffectImpl {
SphinxOfNewPrahvCostIncreaseEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST);
staticText = "Spells your opponents cast that target {this} cost {2} more to cast";
}
private SphinxOfNewPrahvCostIncreaseEffect(SphinxOfNewPrahvCostIncreaseEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
SpellAbility spellAbility = (SpellAbility) abilityToModify;
CardUtil.adjustCost(spellAbility, -2);
return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null
|| !(abilityToModify instanceof SpellAbility)
|| !controller.hasOpponent(abilityToModify.getControllerId(), game)) {
return false;
}
for (UUID modeId : abilityToModify.getModes().getSelectedModes()) {
Mode mode = abilityToModify.getModes().get(modeId);
for (Target target : mode.getTargets()) {
for (UUID targetUUID : target.getTargets()) {
if (targetUUID.equals(source.getSourceId())) {
return true;
}
}
}
}
return false;
}
@Override
public SphinxOfNewPrahvCostIncreaseEffect copy() {
return new SphinxOfNewPrahvCostIncreaseEffect(this);
}
}

View file

@ -1,22 +1,12 @@
package mage.cards.s; package mage.cards.s;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost; import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card; import mage.cards.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.SplitCard;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
@ -27,8 +17,12 @@ import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class SphinxOfTheChimes extends CardImpl { public final class SphinxOfTheChimes extends CardImpl {
@ -91,7 +85,7 @@ class TargetTwoNonLandCardsWithSameNameInHand extends TargetCardInHand {
Set<UUID> newPossibleTargets = new HashSet<>(); Set<UUID> newPossibleTargets = new HashSet<>();
Set<UUID> possibleTargets = new HashSet<>(); Set<UUID> possibleTargets = new HashSet<>();
Player player = game.getPlayer(sourceControllerId); Player player = game.getPlayer(sourceControllerId);
if(player == null){ if (player == null) {
return newPossibleTargets; return newPossibleTargets;
} }
for (Card card : player.getHand().getCards(filter, game)) { for (Card card : player.getHand().getCards(filter, game)) {
@ -116,9 +110,11 @@ class TargetTwoNonLandCardsWithSameNameInHand extends TargetCardInHand {
for (UUID cardToCheck : cardsToCheck) { for (UUID cardToCheck : cardsToCheck) {
FilterCard nameFilter = new FilterCard(); FilterCard nameFilter = new FilterCard();
Card card = game.getCard(cardToCheck); Card card = game.getCard(cardToCheck);
nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName())); if (card != null) {
if (cardsToCheck.count(nameFilter, game) > 1) { nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName()));
newPossibleTargets.add(cardToCheck); if (cardsToCheck.count(nameFilter, game) > 1) {
newPossibleTargets.add(cardToCheck);
}
} }
} }
} }
@ -129,7 +125,7 @@ class TargetTwoNonLandCardsWithSameNameInHand extends TargetCardInHand {
public boolean canChoose(UUID sourceControllerId, Game game) { public boolean canChoose(UUID sourceControllerId, Game game) {
Cards cardsToCheck = new CardsImpl(); Cards cardsToCheck = new CardsImpl();
Player player = game.getPlayer(sourceControllerId); Player player = game.getPlayer(sourceControllerId);
if(player == null){ if (player == null) {
return false; return false;
} }
for (Card card : player.getHand().getCards(filter, game)) { for (Card card : player.getHand().getCards(filter, game)) {
@ -153,16 +149,12 @@ class TargetTwoNonLandCardsWithSameNameInHand extends TargetCardInHand {
if (card != null) { if (card != null) {
if (targets.size() == 1) { if (targets.size() == 1) {
Card card2 = game.getCard(targets.entrySet().iterator().next().getKey()); Card card2 = game.getCard(targets.entrySet().iterator().next().getKey());
if (card2 != null && card2.getName().equals(card.getName())) { return card2 != null && card2.getName().equals(card.getName());
return true;
}
} else { } else {
FilterCard nameFilter = new FilterCard(); FilterCard nameFilter = new FilterCard();
nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName())); nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName()));
Player player = game.getPlayer(card.getOwnerId()); Player player = game.getPlayer(card.getOwnerId());
if (player != null && player.getHand().getCards(nameFilter, game).size() > 1) { return player != null && player.getHand().getCards(nameFilter, game).size() > 1;
return true;
}
} }
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BecomesTappedAttachedTriggeredAbility; import mage.abilities.common.BecomesTappedAttachedTriggeredAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
@ -24,8 +22,9 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent; import mage.target.common.TargetLandPermanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth & L_J * @author jeffwadsworth & L_J
*/ */
public final class SteamVines extends CardImpl { public final class SteamVines extends CardImpl {
@ -76,7 +75,6 @@ class SteamVinesEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent steamVines = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent steamVines = game.getPermanentOrLKIBattlefield(source.getSourceId());
Card steamVinesCard = game.getCard(source.getSourceId());
if (steamVines != null) { if (steamVines != null) {
Permanent enchantedLand = game.getPermanentOrLKIBattlefield(steamVines.getAttachedTo()); Permanent enchantedLand = game.getPermanentOrLKIBattlefield(steamVines.getAttachedTo());
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
@ -85,15 +83,15 @@ class SteamVinesEffect extends OneShotEffect {
Player landsController = game.getPlayer(enchantedLand.getControllerId()); Player landsController = game.getPlayer(enchantedLand.getControllerId());
if (game.getState().getZone(enchantedLand.getId()) == Zone.BATTLEFIELD) { // if 2 or more Steam Vines were on a land if (game.getState().getZone(enchantedLand.getId()) == Zone.BATTLEFIELD) { // if 2 or more Steam Vines were on a land
enchantedLand.destroy(source.getId(), game, false); enchantedLand.destroy(source.getId(), game, false);
if(landsController != null) { if (landsController != null) {
landsController.damage(1, source.getSourceId(), game, false, true); landsController.damage(1, source.getSourceId(), game, false, true);
} }
} }
if (!game.getBattlefield().getAllActivePermanents(CardType.LAND).isEmpty()) { //lands are available on the battlefield if (!game.getBattlefield().getAllActivePermanents(CardType.LAND).isEmpty()) { //lands are available on the battlefield
Target target = new TargetLandPermanent(); Target target = new TargetLandPermanent();
target.setNotTarget(true); //not a target, it is chosen target.setNotTarget(true); //not a target, it is chosen
if (steamVinesCard != null Card steamVinesCard = game.getCard(source.getSourceId());
&& landsController != null) { if (steamVinesCard != null && landsController != null) {
if (landsController.choose(Outcome.DestroyPermanent, target, source.getId(), game)) { if (landsController.choose(Outcome.DestroyPermanent, target, source.getId(), game)) {
if (target.getFirstTarget() != null) { if (target.getFirstTarget() != null) {
Permanent landChosen = game.getPermanent(target.getFirstTarget()); Permanent landChosen = game.getPermanent(target.getFirstTarget());

View file

@ -1,11 +1,11 @@
package mage.cards.s; package mage.cards.s;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.*; import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.SplitCard;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SuperType; import mage.constants.SuperType;
@ -21,8 +21,10 @@ import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import java.util.List;
import java.util.UUID;
/** /**
*
* @author North * @author North
*/ */
public final class SurgicalExtraction extends CardImpl { public final class SurgicalExtraction extends CardImpl {
@ -71,12 +73,12 @@ class SurgicalExtractionEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Card chosenCard = game.getCard(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
// 6/1/2011 "Any number of cards" means just that. If you wish, you can choose to // 6/1/2011 "Any number of cards" means just that. If you wish, you can choose to
// leave some or all of the cards with the same name as the targeted card, // leave some or all of the cards with the same name as the targeted card,
// including that card, in the zone they're in. // including that card, in the zone they're in.
Card chosenCard = game.getCard(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
if (chosenCard != null && controller != null) { if (chosenCard != null && controller != null) {
Player owner = game.getPlayer(chosenCard.getOwnerId()); Player owner = game.getPlayer(chosenCard.getOwnerId());
if (owner != null) { if (owner != null) {

View file

@ -1,7 +1,5 @@
package mage.cards.t; package mage.cards.t;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -17,14 +15,15 @@ import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.players.Player; import mage.players.Player;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class TeferiMageOfZhalfir extends CardImpl { public final class TeferiMageOfZhalfir extends CardImpl {
public TeferiMageOfZhalfir(UUID ownerId, CardSetInfo setInfo) { public TeferiMageOfZhalfir(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}{U}");
addSuperType(SuperType.LEGENDARY); addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD); this.subtype.add(SubType.WIZARD);
@ -76,14 +75,14 @@ class TeferiMageOfZhalfirAddFlashEffect extends ContinuousEffectImpl {
// in graveyard // in graveyard
for (UUID cardId : controller.getGraveyard()) { for (UUID cardId : controller.getGraveyard()) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
if (card.isCreature()) { if (card != null && card.isCreature()) {
game.getState().addOtherAbility(card, FlashAbility.getInstance()); game.getState().addOtherAbility(card, FlashAbility.getInstance());
} }
} }
// on Hand // on Hand
for (UUID cardId : controller.getHand()) { for (UUID cardId : controller.getHand()) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
if (card.isCreature()) { if (card != null && card.isCreature()) {
game.getState().addOtherAbility(card, FlashAbility.getInstance()); game.getState().addOtherAbility(card, FlashAbility.getInstance());
} }
} }
@ -103,7 +102,7 @@ class TeferiMageOfZhalfirAddFlashEffect extends ContinuousEffectImpl {
for (UUID commanderId : controller.getCommandersIds()) { for (UUID commanderId : controller.getCommandersIds()) {
if (game.getState().getZone(commanderId) == Zone.COMMAND) { if (game.getState().getZone(commanderId) == Zone.COMMAND) {
Card card = game.getCard(commanderId); Card card = game.getCard(commanderId);
if (card.isCreature()) { if (card != null && card.isCreature()) {
game.getState().addOtherAbility(card, FlashAbility.getInstance()); game.getState().addOtherAbility(card, FlashAbility.getInstance());
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.t; package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@ -18,12 +16,7 @@ import mage.abilities.keyword.EnchantAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game; import mage.game.Game;
@ -34,8 +27,9 @@ import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class TravelingPlague extends CardImpl { public final class TravelingPlague extends CardImpl {
@ -130,10 +124,10 @@ class TravelingPlagueEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Card travelingPlague = game.getCard(source.getSourceId());
Permanent enchantedCreature = (Permanent) game.getState().getValue("travelingPlague" + source.getSourceId()); Permanent enchantedCreature = (Permanent) game.getState().getValue("travelingPlague" + source.getSourceId());
if (enchantedCreature != null) { if (enchantedCreature != null) {
Player controllerOfEnchantedCreature = game.getPlayer(enchantedCreature.getControllerId()); Player controllerOfEnchantedCreature = game.getPlayer(enchantedCreature.getControllerId());
Card travelingPlague = game.getCard(source.getSourceId());
if (travelingPlague != null if (travelingPlague != null
&& game.getState().getZone(travelingPlague.getId()) == Zone.GRAVEYARD // aura must come from the graveyard && game.getState().getZone(travelingPlague.getId()) == Zone.GRAVEYARD // aura must come from the graveyard
&& controllerOfEnchantedCreature != null) { && controllerOfEnchantedCreature != null) {

View file

@ -1,7 +1,5 @@
package mage.cards.t; package mage.cards.t;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -11,25 +9,21 @@ import mage.abilities.keyword.TrampleAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.filter.common.FilterLandCard; import mage.filter.common.FilterLandCard;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class TrenchGorger extends CardImpl { public final class TrenchGorger extends CardImpl {
public TrenchGorger(UUID ownerId, CardSetInfo setInfo) { public TrenchGorger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{U}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{U}{U}");
this.subtype.add(SubType.LEVIATHAN); this.subtype.add(SubType.LEVIATHAN);
this.power = new MageInt(6); this.power = new MageInt(6);
@ -77,8 +71,10 @@ class TrenchGorgerEffect extends OneShotEffect {
int count = 0; int count = 0;
for (UUID cardId : target.getTargets()) { for (UUID cardId : target.getTargets()) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); if (card != null) {
count++; controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true);
count++;
}
} }
controller.shuffleLibrary(source, game); controller.shuffleLibrary(source, game);
game.addEffect(new SetPowerToughnessSourceEffect(count, count, Duration.EndOfGame, SubLayer.SetPT_7b), source); game.addEffect(new SetPowerToughnessSourceEffect(count, count, Duration.EndOfGame, SubLayer.SetPT_7b), source);

View file

@ -1,6 +1,5 @@
package mage.cards.v; package mage.cards.v;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.ActivatedAbility; import mage.abilities.ActivatedAbility;
import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.ActivateAsSorceryActivatedAbility;
@ -25,8 +24,9 @@ import mage.players.Player;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class VolrathsDungeon extends CardImpl { public final class VolrathsDungeon extends CardImpl {
@ -65,7 +65,7 @@ class PayLifeActivePlayerCost extends CostImpl {
public PayLifeActivePlayerCost(int amount) { public PayLifeActivePlayerCost(int amount) {
this.amount = new StaticValue(amount); this.amount = new StaticValue(amount);
this.text = "Pay " + Integer.toString(amount) + " life"; this.text = "Pay " + amount + " life";
} }
public PayLifeActivePlayerCost(DynamicValue amount, String text) { public PayLifeActivePlayerCost(DynamicValue amount, String text) {
@ -89,9 +89,9 @@ class PayLifeActivePlayerCost extends CostImpl {
int lifeToPayAmount = amount.calculate(game, ability, null); int lifeToPayAmount = amount.calculate(game, ability, null);
Player activatingPlayer = game.getPlayer(game.getActivePlayerId()); Player activatingPlayer = game.getPlayer(game.getActivePlayerId());
if (activatingPlayer != null if (activatingPlayer != null
&& activatingPlayer.chooseUse(Outcome.LoseLife, "Do you wish to pay "+ lifeToPayAmount +" life?", ability, game)) { && activatingPlayer.chooseUse(Outcome.LoseLife, "Do you wish to pay " + lifeToPayAmount + " life?", ability, game)) {
Player player = game.getPlayer(game.getActivePlayerId()); Player player = game.getPlayer(game.getActivePlayerId());
if(player != null) { if (player != null) {
this.paid = player.loseLife(lifeToPayAmount, game, false) == lifeToPayAmount; this.paid = player.loseLife(lifeToPayAmount, game, false) == lifeToPayAmount;
} }
} }
@ -127,7 +127,7 @@ class VolrathsDungeonEffect extends OneShotEffect {
TargetCardInHand target = new TargetCardInHand(); TargetCardInHand target = new TargetCardInHand();
if (targetedPlayer.choose(Outcome.Detriment, targetedPlayer.getHand(), target, game)) { if (targetedPlayer.choose(Outcome.Detriment, targetedPlayer.getHand(), target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
return targetedPlayer.putCardOnTopXOfLibrary(card, game, source, 0); return card != null && targetedPlayer.putCardOnTopXOfLibrary(card, game, source, 0);
} }
} }
return false; return false;

View file

@ -1,7 +1,5 @@
package mage.cards.y; package mage.cards.y;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.LegendarySpellAbility; import mage.abilities.common.LegendarySpellAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -9,7 +7,10 @@ import mage.abilities.effects.common.ExileSpellEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
import mage.filter.common.FilterPermanentCard; import mage.filter.common.FilterPermanentCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
@ -20,6 +21,8 @@ import mage.players.Player;
import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetCreatureOrPlaneswalker; import mage.target.common.TargetCreatureOrPlaneswalker;
import java.util.UUID;
/** /**
* @author JRHerlehy Created on 4/8/18. * @author JRHerlehy Created on 4/8/18.
*/ */
@ -78,7 +81,6 @@ class YawgmothsVileOfferingEffect extends OneShotEffect {
} }
Card returnCard = game.getCard(source.getTargets().getFirstTarget()); Card returnCard = game.getCard(source.getTargets().getFirstTarget());
if (returnCard != null) { if (returnCard != null) {
controller.moveCards(returnCard, Zone.BATTLEFIELD, source, game); controller.moveCards(returnCard, Zone.BATTLEFIELD, source, game);
} }

View file

@ -56,6 +56,7 @@ public final class RavnicaAllegiance extends ExpansionSet {
cards.add(new SetCardInfo("Cry of the Carnarium", 70, Rarity.UNCOMMON, mage.cards.c.CryOfTheCarnarium.class)); cards.add(new SetCardInfo("Cry of the Carnarium", 70, Rarity.UNCOMMON, mage.cards.c.CryOfTheCarnarium.class));
cards.add(new SetCardInfo("Depose // Deploy", 225, Rarity.UNCOMMON, mage.cards.d.DeposeDeploy.class)); cards.add(new SetCardInfo("Depose // Deploy", 225, Rarity.UNCOMMON, mage.cards.d.DeposeDeploy.class));
cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class)); cards.add(new SetCardInfo("Deputy of Detention", 165, Rarity.RARE, mage.cards.d.DeputyOfDetention.class));
cards.add(new SetCardInfo("Domri, Chaos Bringer", 166, Rarity.MYTHIC, mage.cards.d.DomriChaosBringer.class));
cards.add(new SetCardInfo("Dovin, Grand Arbiter", 167, Rarity.MYTHIC, mage.cards.d.DovinGrandArbiter.class)); cards.add(new SetCardInfo("Dovin, Grand Arbiter", 167, Rarity.MYTHIC, mage.cards.d.DovinGrandArbiter.class));
cards.add(new SetCardInfo("Drill Bit", 73, Rarity.UNCOMMON, mage.cards.d.DrillBit.class)); cards.add(new SetCardInfo("Drill Bit", 73, Rarity.UNCOMMON, mage.cards.d.DrillBit.class));
cards.add(new SetCardInfo("Electrodominance", 99, Rarity.RARE, mage.cards.e.Electrodominance.class)); cards.add(new SetCardInfo("Electrodominance", 99, Rarity.RARE, mage.cards.e.Electrodominance.class));
@ -73,6 +74,7 @@ public final class RavnicaAllegiance extends ExpansionSet {
cards.add(new SetCardInfo("Gruul Guildgate", 250, Rarity.COMMON, mage.cards.g.GruulGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gruul Guildgate", 250, Rarity.COMMON, mage.cards.g.GruulGuildgate.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Gruul Locket", 234, Rarity.COMMON, mage.cards.g.GruulLocket.class)); cards.add(new SetCardInfo("Gruul Locket", 234, Rarity.COMMON, mage.cards.g.GruulLocket.class));
cards.add(new SetCardInfo("Gruul Spellbreaker", 179, Rarity.RARE, mage.cards.g.GruulSpellbreaker.class)); cards.add(new SetCardInfo("Gruul Spellbreaker", 179, Rarity.RARE, mage.cards.g.GruulSpellbreaker.class));
cards.add(new SetCardInfo("Guardian Project", 130, Rarity.RARE, mage.cards.g.GuardianProject.class));
cards.add(new SetCardInfo("Gutterbones", 76, Rarity.RARE, mage.cards.g.Gutterbones.class)); cards.add(new SetCardInfo("Gutterbones", 76, Rarity.RARE, mage.cards.g.Gutterbones.class));
cards.add(new SetCardInfo("Hackrobat", 181, Rarity.UNCOMMON, mage.cards.h.Hackrobat.class)); cards.add(new SetCardInfo("Hackrobat", 181, Rarity.UNCOMMON, mage.cards.h.Hackrobat.class));
cards.add(new SetCardInfo("Hallowed Fountain", 251, Rarity.RARE, mage.cards.h.HallowedFountain.class)); cards.add(new SetCardInfo("Hallowed Fountain", 251, Rarity.RARE, mage.cards.h.HallowedFountain.class));
@ -82,6 +84,7 @@ public final class RavnicaAllegiance extends ExpansionSet {
cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class)); cards.add(new SetCardInfo("Imperious Oligarch", 184, Rarity.COMMON, mage.cards.i.ImperiousOligarch.class));
cards.add(new SetCardInfo("Incubation // Incongruity", 226, Rarity.UNCOMMON, mage.cards.i.IncubationIncongruity.class)); cards.add(new SetCardInfo("Incubation // Incongruity", 226, Rarity.UNCOMMON, mage.cards.i.IncubationIncongruity.class));
cards.add(new SetCardInfo("Judith, the Scourge Diva", 185, Rarity.RARE, mage.cards.j.JudithTheScourgeDiva.class)); cards.add(new SetCardInfo("Judith, the Scourge Diva", 185, Rarity.RARE, mage.cards.j.JudithTheScourgeDiva.class));
cards.add(new SetCardInfo("Kaya's Wrath", 187, Rarity.RARE, mage.cards.k.KayasWrath.class));
cards.add(new SetCardInfo("Kaya, Orzhov Usurper", 186, Rarity.MYTHIC, mage.cards.k.KayaOrzhovUsurper.class)); cards.add(new SetCardInfo("Kaya, Orzhov Usurper", 186, Rarity.MYTHIC, mage.cards.k.KayaOrzhovUsurper.class));
cards.add(new SetCardInfo("Lavinia, Azorius Renegade", 189, Rarity.RARE, mage.cards.l.LaviniaAzoriusRenegade.class)); cards.add(new SetCardInfo("Lavinia, Azorius Renegade", 189, Rarity.RARE, mage.cards.l.LaviniaAzoriusRenegade.class));
cards.add(new SetCardInfo("Light Up the Stage", 107, Rarity.UNCOMMON, mage.cards.l.LightUpTheStage.class)); cards.add(new SetCardInfo("Light Up the Stage", 107, Rarity.UNCOMMON, mage.cards.l.LightUpTheStage.class));
@ -89,6 +92,7 @@ public final class RavnicaAllegiance extends ExpansionSet {
cards.add(new SetCardInfo("Mesmerizing Benthid", 43, Rarity.MYTHIC, mage.cards.m.MesmerizingBenthid.class)); cards.add(new SetCardInfo("Mesmerizing Benthid", 43, Rarity.MYTHIC, mage.cards.m.MesmerizingBenthid.class));
cards.add(new SetCardInfo("Ministrant of Obligation", 16, Rarity.UNCOMMON, mage.cards.m.MinistrantOfObligation.class)); cards.add(new SetCardInfo("Ministrant of Obligation", 16, Rarity.UNCOMMON, mage.cards.m.MinistrantOfObligation.class));
cards.add(new SetCardInfo("Mortify", 192, Rarity.UNCOMMON, mage.cards.m.Mortify.class)); cards.add(new SetCardInfo("Mortify", 192, Rarity.UNCOMMON, mage.cards.m.Mortify.class));
cards.add(new SetCardInfo("Nikya of the Old Ways", 193, Rarity.RARE, mage.cards.n.NikyaOfTheOldWays.class));
cards.add(new SetCardInfo("Orzhov Guildgate", 252, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orzhov Guildgate", 252, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Orzhov Guildgate", 253, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orzhov Guildgate", 253, Rarity.COMMON, mage.cards.o.OrzhovGuildgate.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Orzhov Locket", 236, Rarity.COMMON, mage.cards.o.OrzhovLocket.class)); cards.add(new SetCardInfo("Orzhov Locket", 236, Rarity.COMMON, mage.cards.o.OrzhovLocket.class));
@ -123,6 +127,7 @@ public final class RavnicaAllegiance extends ExpansionSet {
cards.add(new SetCardInfo("Smothering Tithe", 22, Rarity.RARE, mage.cards.s.SmotheringTithe.class)); cards.add(new SetCardInfo("Smothering Tithe", 22, Rarity.RARE, mage.cards.s.SmotheringTithe.class));
cards.add(new SetCardInfo("Spawn of Mayhem", 85, Rarity.MYTHIC, mage.cards.s.SpawnOfMayhem.class)); cards.add(new SetCardInfo("Spawn of Mayhem", 85, Rarity.MYTHIC, mage.cards.s.SpawnOfMayhem.class));
cards.add(new SetCardInfo("Sphinx of Foresight", 55, Rarity.RARE, mage.cards.s.SphinxOfForesight.class)); cards.add(new SetCardInfo("Sphinx of Foresight", 55, Rarity.RARE, mage.cards.s.SphinxOfForesight.class));
cards.add(new SetCardInfo("Sphinx of New Prahv", 208, Rarity.UNCOMMON, mage.cards.s.SphinxOfNewPrahv.class));
cards.add(new SetCardInfo("Sphinx's Insight", 209, Rarity.COMMON, mage.cards.s.SphinxsInsight.class)); cards.add(new SetCardInfo("Sphinx's Insight", 209, Rarity.COMMON, mage.cards.s.SphinxsInsight.class));
cards.add(new SetCardInfo("Stomping Ground", 259, Rarity.RARE, mage.cards.s.StompingGround.class)); cards.add(new SetCardInfo("Stomping Ground", 259, Rarity.RARE, mage.cards.s.StompingGround.class));
cards.add(new SetCardInfo("Syndicate Guildmage", 211, Rarity.UNCOMMON, mage.cards.s.SyndicateGuildmage.class)); cards.add(new SetCardInfo("Syndicate Guildmage", 211, Rarity.UNCOMMON, mage.cards.s.SyndicateGuildmage.class));

View file

@ -1,8 +1,5 @@
package mage.abilities; package mage.abilities;
import java.util.Optional;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
@ -12,17 +9,15 @@ import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlashAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.SplitCard; import mage.cards.SplitCard;
import mage.constants.AbilityType; import mage.constants.*;
import mage.constants.AsThoughEffectType;
import mage.constants.SpellAbilityCastMode;
import mage.constants.SpellAbilityType;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.players.Player; import mage.players.Player;
import java.util.Optional;
import java.util.UUID;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -224,12 +219,16 @@ public class SpellAbility extends ActivatedAbilityImpl {
if (event.getType() != GameEvent.EventType.CAST_SPELL) { if (event.getType() != GameEvent.EventType.CAST_SPELL) {
return null; return null;
} }
Card card = game.getCard(event.getSourceId()); Card card = game.getCard(event.getSourceId());
Optional<Ability> ability = card.getAbilities(game).get(event.getTargetId()); if (card != null) {
if (ability.isPresent() && ability.get() instanceof SpellAbility) { Optional<Ability> ability = card.getAbilities(game).get(event.getTargetId());
return (SpellAbility) ability.get(); if (ability.isPresent() && ability.get() instanceof SpellAbility) {
return (SpellAbility) ability.get();
}
return card.getSpellAbility();
} }
return card.getSpellAbility(); return null;
} }
public void setId(UUID idToUse) { public void setId(UUID idToUse) {

View file

@ -5,7 +5,6 @@
*/ */
package mage.abilities.costs.common; package mage.abilities.costs.common;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl; import mage.abilities.costs.CostImpl;
@ -16,8 +15,9 @@ import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
@ -40,7 +40,7 @@ public class PutCardFromHandOnTopOfLibraryCost extends CostImpl {
if (targetCardInHand.canChoose(controllerId, game) if (targetCardInHand.canChoose(controllerId, game)
&& controller.choose(Outcome.PreventDamage, targetCardInHand, sourceId, game)) { && controller.choose(Outcome.PreventDamage, targetCardInHand, sourceId, game)) {
card = game.getCard(targetCardInHand.getFirstTarget()); card = game.getCard(targetCardInHand.getFirstTarget());
paid = controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.HAND, true, true); paid = card != null && controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.HAND, true, true);
} }
return paid; return paid;
} }

View file

@ -1,7 +1,5 @@
package mage.abilities.keyword; package mage.abilities.keyword;
import java.util.UUID;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
@ -19,18 +17,19 @@ import mage.target.Target;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* 702.46. Offering # 702.46a Offering is a static ability of a card that * 702.46. Offering # 702.46a Offering is a static ability of a card that
* functions in any zone from which the card can be cast. "[Subtype] offering" * functions in any zone from which the card can be cast. "[Subtype] offering"
* means "You may cast this card any time you could cast an instant by * means "You may cast this card any time you could cast an instant by
* sacrificing a [subtype] permanent. If you do, the total cost to cast this * sacrificing a [subtype] permanent. If you do, the total cost to cast this
* card is reduced by the sacrificed permanent's mana cost." # * card is reduced by the sacrificed permanent's mana cost." #
* * <p>
* 702.46b The permanent is sacrificed at the same time the spell is announced * 702.46b The permanent is sacrificed at the same time the spell is announced
* (see rule 601.2a). The total cost of the spell is reduced by the sacrificed * (see rule 601.2a). The total cost of the spell is reduced by the sacrificed
* permanent's mana cost (see rule 601.2e). # * permanent's mana cost (see rule 601.2e). #
* * <p>
* 702.46c Generic mana in the sacrificed permanent's mana cost reduces generic * 702.46c Generic mana in the sacrificed permanent's mana cost reduces generic
* mana in the total cost to cast the card with offering. Colored mana in the * mana in the total cost to cast the card with offering. Colored mana in the
* sacrificed permanent's mana cost reduces mana of the same color in the total * sacrificed permanent's mana cost reduces mana of the same color in the total
@ -39,7 +38,6 @@ import mage.util.CardUtil;
* cost of the card with offering, or is in excess of the card's colored mana * cost of the card with offering, or is in excess of the card's colored mana
* cost, reduces that much generic mana in the total cost. # * cost, reduces that much generic mana in the total cost. #
* *
*
* @author LevelX2 * @author LevelX2
*/ */
public class OfferingAbility extends StaticAbility { public class OfferingAbility extends StaticAbility {
@ -47,7 +45,6 @@ public class OfferingAbility extends StaticAbility {
private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
/** /**
*
* @param subtype name of the subtype that can be offered * @param subtype name of the subtype that can be offered
*/ */
public OfferingAbility(SubType subtype) { public OfferingAbility(SubType subtype) {
@ -107,7 +104,7 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl {
public boolean applies(UUID sourceId, Ability affectedAbility, Ability source, Game game, UUID playerId) { public boolean applies(UUID sourceId, Ability affectedAbility, Ability source, Game game, UUID playerId) {
if (sourceId.equals(source.getSourceId())) { if (sourceId.equals(source.getSourceId())) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
if (!card.isOwnedBy(source.getControllerId())) { if (card == null || !card.isOwnedBy(source.getControllerId())) {
return false; return false;
} }
// because can activate is always called twice, result from first call will be used // because can activate is always called twice, result from first call will be used
@ -129,6 +126,9 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl {
} }
FilterControlledCreaturePermanent filter = ((OfferingAbility) source).getFilter(); FilterControlledCreaturePermanent filter = ((OfferingAbility) source).getFilter();
Card spellToCast = game.getCard(source.getSourceId()); Card spellToCast = game.getCard(source.getSourceId());
if (spellToCast == null) {
return false;
}
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null && !CardUtil.isCheckPlayableMode(affectedAbility) if (player != null && !CardUtil.isCheckPlayableMode(affectedAbility)
&& player.chooseUse(Outcome.Benefit, "Offer a " + filter.getMessage() + " to cast " + spellToCast.getName() + '?', source, game)) { && player.chooseUse(Outcome.Benefit, "Offer a " + filter.getMessage() + " to cast " + spellToCast.getName() + '?', source, game)) {
@ -146,7 +146,6 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl {
game.getState().setValue("offering_ok_" + card.getId(), true); game.getState().setValue("offering_ok_" + card.getId(), true);
game.getState().setValue("offering_Id_" + card.getId(), activationId); game.getState().setValue("offering_Id_" + card.getId(), activationId);
return true; return true;
} }
} else { } else {
game.getState().setValue("offering_" + card.getId(), true); game.getState().setValue("offering_" + card.getId(), true);
@ -201,7 +200,7 @@ class OfferingCostReductionEffect extends CostModificationEffectImpl {
Card card = game.getCard(source.getSourceId()); Card card = game.getCard(source.getSourceId());
if (card != null) { if (card != null) {
Object object = game.getState().getValue("offering_Id_" + card.getId()); Object object = game.getState().getValue("offering_Id_" + card.getId());
if (object != null && ((UUID) object).equals(this.activationId) && offeredPermanent.getPermanent(game) != null) { if (object != null && object.equals(this.activationId) && offeredPermanent.getPermanent(game) != null) {
return true; return true;
} }
} }

View file

@ -0,0 +1,23 @@
package mage.game.command.emblems;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.constants.TargetController;
import mage.game.command.Emblem;
import mage.game.permanent.token.SoldierToken;
/**
* @author TheElk801
*/
public final class DomriChaosBringerEmblem extends Emblem {
// -8: You get an emblem with "At the beginning of each end step, create a 4/4 red and green Beast creature token with trample."
public DomriChaosBringerEmblem() {
this.setName("Emblem Domri");
this.setExpansionSetCodeForImage("RNA");
this.getAbilities().add(new BeginningOfEndStepTriggeredAbility(
new CreateTokenEffect(new SoldierToken()),
TargetController.ANY, false
));
}
}

View file

@ -0,0 +1,33 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.abilities.keyword.TrampleAbility;
import mage.constants.CardType;
import mage.constants.SubType;
/**
* @author TheElk801
*/
public final class DomriChaosBringerToken extends TokenImpl {
public DomriChaosBringerToken() {
super("Beast", "4/4 red and green Beast creature token with trample");
cardType.add(CardType.CREATURE);
color.setRed(true);
color.setGreen(true);
subtype.add(SubType.BEAST);
power = new MageInt(4);
toughness = new MageInt(4);
this.addAbility(TrampleAbility.getInstance());
}
private DomriChaosBringerToken(final DomriChaosBringerToken token) {
super(token);
}
public DomriChaosBringerToken copy() {
return new DomriChaosBringerToken(this);
}
}

View file

@ -619,9 +619,7 @@ public abstract class PlayerImpl implements Player, Serializable {
return false; return false;
} }
} }
if (hasProtectionFrom(source, game)) { return !hasProtectionFrom(source, game);
return false;
}
} }
return true; return true;
@ -1122,6 +1120,9 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean playLand(Card card, Game game, boolean ignoreTiming) { public boolean playLand(Card card, Game game, boolean ignoreTiming) {
// Check for alternate casting possibilities: e.g. land with Morph // Check for alternate casting possibilities: e.g. land with Morph
if (card == null) {
return false;
}
ActivatedAbility playLandAbility = null; ActivatedAbility playLandAbility = null;
boolean found = false; boolean found = false;
for (Ability ability : card.getAbilities()) { for (Ability ability : card.getAbilities()) {
@ -1342,7 +1343,7 @@ public abstract class PlayerImpl implements Player, Serializable {
switch (((SpellAbility) ability).getSpellAbilityType()) { switch (((SpellAbility) ability).getSpellAbilityType()) {
case SPLIT_FUSED: case SPLIT_FUSED:
if (zone == Zone.HAND) { if (zone == Zone.HAND) {
if (((SpellAbility) ability).canChooseTarget(game)) { if (ability.canChooseTarget(game)) {
useable.put(ability.getId(), (SpellAbility) ability); useable.put(ability.getId(), (SpellAbility) ability);
} }
} }
@ -1456,37 +1457,39 @@ public abstract class PlayerImpl implements Player, Serializable {
for (ActivatedAbility ability : otherAbilities) { for (ActivatedAbility ability : otherAbilities) {
if (canUse || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) { if (canUse || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
Card card = game.getCard(ability.getSourceId()); Card card = game.getCard(ability.getSourceId());
if (card.isSplitCard() && ability instanceof FlashbackAbility) { if (card != null) {
FlashbackAbility flashbackAbility; if (card.isSplitCard() && ability instanceof FlashbackAbility) {
// Left Half FlashbackAbility flashbackAbility;
if (card.isInstant()) { // Left Half
flashbackAbility = new FlashbackAbility(((SplitCard) card).getLeftHalfCard().getManaCost(), TimingRule.INSTANT); if (card.isInstant()) {
} else { flashbackAbility = new FlashbackAbility(((SplitCard) card).getLeftHalfCard().getManaCost(), TimingRule.INSTANT);
flashbackAbility = new FlashbackAbility(((SplitCard) card).getLeftHalfCard().getManaCost(), TimingRule.SORCERY); } else {
} flashbackAbility = new FlashbackAbility(((SplitCard) card).getLeftHalfCard().getManaCost(), TimingRule.SORCERY);
flashbackAbility.setSourceId(card.getId()); }
flashbackAbility.setControllerId(card.getOwnerId()); flashbackAbility.setSourceId(card.getId());
flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_LEFT); flashbackAbility.setControllerId(card.getOwnerId());
flashbackAbility.setAbilityName(((SplitCard) card).getLeftHalfCard().getName()); flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_LEFT);
if (flashbackAbility.canActivate(playerId, game).canActivate()) { flashbackAbility.setAbilityName(((SplitCard) card).getLeftHalfCard().getName());
useable.put(flashbackAbility.getId(), flashbackAbility); if (flashbackAbility.canActivate(playerId, game).canActivate()) {
} useable.put(flashbackAbility.getId(), flashbackAbility);
// Right Half }
if (card.isInstant()) { // Right Half
flashbackAbility = new FlashbackAbility(((SplitCard) card).getRightHalfCard().getManaCost(), TimingRule.INSTANT); if (card.isInstant()) {
} else { flashbackAbility = new FlashbackAbility(((SplitCard) card).getRightHalfCard().getManaCost(), TimingRule.INSTANT);
flashbackAbility = new FlashbackAbility(((SplitCard) card).getRightHalfCard().getManaCost(), TimingRule.SORCERY); } else {
} flashbackAbility = new FlashbackAbility(((SplitCard) card).getRightHalfCard().getManaCost(), TimingRule.SORCERY);
flashbackAbility.setSourceId(card.getId()); }
flashbackAbility.setControllerId(card.getOwnerId()); flashbackAbility.setSourceId(card.getId());
flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_RIGHT); flashbackAbility.setControllerId(card.getOwnerId());
flashbackAbility.setAbilityName(((SplitCard) card).getRightHalfCard().getName()); flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_RIGHT);
if (flashbackAbility.canActivate(playerId, game).canActivate()) { flashbackAbility.setAbilityName(((SplitCard) card).getRightHalfCard().getName());
useable.put(flashbackAbility.getId(), flashbackAbility); if (flashbackAbility.canActivate(playerId, game).canActivate()) {
} useable.put(flashbackAbility.getId(), flashbackAbility);
}
} else { } else {
useable.put(ability.getId(), ability); useable.put(ability.getId(), ability);
}
} }
} }
} }
@ -1690,9 +1693,7 @@ public abstract class PlayerImpl implements Player, Serializable {
leftForUntap = getPermanentsThatCanBeUntapped(game, canBeUntapped, handledEntry.getKey().getKey(), notMoreThanEffectsUsage); leftForUntap = getPermanentsThatCanBeUntapped(game, canBeUntapped, handledEntry.getKey().getKey(), notMoreThanEffectsUsage);
// remove already selected permanents // remove already selected permanents
for (Permanent permanent : selectedToUntap) { for (Permanent permanent : selectedToUntap) {
if (leftForUntap.contains(permanent)) { leftForUntap.remove(permanent);
leftForUntap.remove(permanent);
}
} }
} else { } else {
@ -1961,7 +1962,7 @@ public abstract class PlayerImpl implements Player, Serializable {
sourceControllerId = ((Card) source).getOwnerId(); sourceControllerId = ((Card) source).getOwnerId();
} else if (source instanceof CommandObject) { } else if (source instanceof CommandObject) {
sourceControllerId = ((CommandObject) source).getControllerId(); sourceControllerId = ((CommandObject) source).getControllerId();
sourceAbilities = ((CommandObject) source).getAbilities(); sourceAbilities = source.getAbilities();
} }
} else { } else {
sourceAbilities = ((Permanent) source).getAbilities(game); sourceAbilities = ((Permanent) source).getAbilities(game);
@ -2847,9 +2848,7 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
} }
} }
if (canPlayCardByAlternateCost(card, available, ability, game)) { return canPlayCardByAlternateCost(card, available, ability, game);
return true;
}
} }
return false; return false;
} }
@ -3582,7 +3581,7 @@ public abstract class PlayerImpl implements Player, Serializable {
case OUTSIDE: case OUTSIDE:
for (Card card : cards) { for (Card card : cards) {
if (card instanceof Permanent) { if (card instanceof Permanent) {
game.getBattlefield().removePermanent(((Permanent) card).getId()); game.getBattlefield().removePermanent(card.getId());
ZoneChangeEvent event = new ZoneChangeEvent(card.getId(), (source == null ? null : source.getSourceId()), ZoneChangeEvent event = new ZoneChangeEvent(card.getId(), (source == null ? null : source.getSourceId()),
byOwner ? card.getOwnerId() : getId(), Zone.BATTLEFIELD, Zone.OUTSIDE, appliedEffects); byOwner ? card.getOwnerId() : getId(), Zone.BATTLEFIELD, Zone.OUTSIDE, appliedEffects);
game.fireEvent(event); game.fireEvent(event);
@ -3731,7 +3730,7 @@ public abstract class PlayerImpl implements Player, Serializable {
} }
boolean result = false; boolean result = false;
// Zone fromZone = game.getState().getZone(card.getId()); // Zone fromZone = game.getState().getZone(card.getId());
if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null ? fromZone == Zone.BATTLEFIELD : false)) { if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null && fromZone == Zone.BATTLEFIELD)) {
if (!game.isSimulation()) { if (!game.isSimulation()) {
if (card instanceof PermanentCard && game.getCard(card.getId()) != null) { if (card instanceof PermanentCard && game.getCard(card.getId()) != null) {
card = game.getCard(card.getId()); card = game.getCard(card.getId());