forked from External/mage
* Fixed some cards/effects that checked for permanents with the same name and did not work correctly with face down creatures.
This commit is contained in:
parent
062ce8dd41
commit
bc7a64677e
19 changed files with 214 additions and 115 deletions
|
|
@ -46,6 +46,7 @@ public class MaelstromPulse extends CardImpl {
|
|||
this.expansionSetCode = "ARB";
|
||||
|
||||
|
||||
// Destroy target nonland permanent and all other permanents with the same name as that permanent.
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
this.getSpellAbility().addEffect(new DestroyAllNamedPermanentsEffect());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,16 +79,18 @@ class BileBlightEffect extends BoostAllEffect {
|
|||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
|
||||
if (this.affectedObjectsSet) {
|
||||
this.objects.clear();
|
||||
UUID permanentId = targetPointer.getFirst(game, source);
|
||||
Permanent target = game.getPermanent(permanentId);
|
||||
Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (target != null) {
|
||||
String name = target.getName();
|
||||
for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||
if (perm.getName().equals(name)) {
|
||||
this.objects.add(perm.getId());
|
||||
if (target.getName().isEmpty()) { // face down creature
|
||||
this.objects.add(target.getId());
|
||||
} else {
|
||||
String name = target.getLogName();
|
||||
for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||
if (perm.getLogName().equals(name)) {
|
||||
this.objects.add(perm.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@
|
|||
package mage.sets.darksteel;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Rarity;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
/**
|
||||
|
|
@ -57,6 +57,7 @@ public class EchoingCalm extends CardImpl {
|
|||
|
||||
this.color.setWhite(true);
|
||||
|
||||
// Destroy target enchantment and all other enchantments with the same name as that enchantment.
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(filter));
|
||||
this.getSpellAbility().addEffect(new EchoingCalmEffect());
|
||||
}
|
||||
|
|
@ -88,15 +89,19 @@ class EchoingCalmEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
String name = permanent.getName();
|
||||
|
||||
permanent.destroy(source.getSourceId(), game, false);
|
||||
for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||
if (perm.getName().equals(name) && perm.getCardType().contains(CardType.ENCHANTMENT))
|
||||
perm.destroy(source.getSourceId(), game, false);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (controller != null && permanent != null) {
|
||||
permanent.destroy(source.getSourceId(), game, false);
|
||||
if (!permanent.getName().isEmpty()) { // in case of face down enchantment creature
|
||||
for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||
if (!perm.getId().equals(permanent.getId()) && perm.getName().equals(permanent.getName()) && perm.getCardType().contains(CardType.ENCHANTMENT)) {
|
||||
perm.destroy(source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,9 @@ import mage.constants.Duration;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
|
@ -53,8 +55,6 @@ public class EchoingDecay extends CardImpl {
|
|||
super(ownerId, 41, "Echoing Decay", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{B}");
|
||||
this.expansionSetCode = "DST";
|
||||
|
||||
this.color.setBlack(true);
|
||||
|
||||
// Target creature and all other creatures with the same name as that creature get -2/-2 until end of turn.
|
||||
this.getSpellAbility().addEffect(new EchoingDecayEffect());
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
|
|
@ -91,7 +91,11 @@ class EchoingDecayEffect extends OneShotEffect {
|
|||
Permanent targetPermanent = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
if (targetPermanent != null) {
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
if (targetPermanent.getName().isEmpty()) {
|
||||
filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected
|
||||
} else {
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
}
|
||||
ContinuousEffect effect = new BoostAllEffect(-2,-2, Duration.EndOfTurn, filter, false);
|
||||
game.addEffect(effect, source);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -37,9 +37,12 @@ import mage.constants.Outcome;
|
|||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
|
|
@ -53,8 +56,6 @@ public class EchoingTruth extends CardImpl {
|
|||
super(ownerId, 66, "Echoing Truth", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}");
|
||||
this.expansionSetCode = "DDF";
|
||||
|
||||
this.color.setBlue(true);
|
||||
|
||||
// Return target nonland permanent and all other permanents with the same name as that permanent to their owners' hands.
|
||||
Target target = new TargetNonlandPermanent();
|
||||
this.getSpellAbility().addTarget(target);
|
||||
|
|
@ -88,13 +89,19 @@ class ReturnToHandAllNamedPermanentsEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
if (controller != null && permanent != null) {
|
||||
FilterPermanent filter = new FilterPermanent();
|
||||
filter.add(new NamePredicate(permanent.getName()));
|
||||
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
|
||||
perm.moveToZone(Zone.HAND, source.getSourceId(), game, false);
|
||||
if (permanent.getName().isEmpty()) {
|
||||
filter.add(new PermanentIdPredicate(permanent.getId())); // if no name (face down creature) only the creature itself is selected
|
||||
} else {
|
||||
filter.add(new NamePredicate(permanent.getLogName()));
|
||||
}
|
||||
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
|
||||
controller.moveCardToHandWithInfo(perm, source.getSourceId(), game, Zone.BATTLEFIELD);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
*/
|
||||
package mage.sets.gatecrash;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.constants.CardType;
|
||||
|
|
@ -38,6 +37,7 @@ import mage.cards.CardImpl;
|
|||
import mage.constants.Outcome;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
|
@ -82,22 +82,22 @@ class HomingLightningEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent target = game.getPermanent(source.getFirstTarget());
|
||||
if (target == null) {
|
||||
Permanent targetPermanent = game.getPermanent(source.getFirstTarget());
|
||||
if (targetPermanent == null) {
|
||||
return false;
|
||||
}
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
filter.add(new NamePredicate(target.getName()));
|
||||
List<Permanent> creatures = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game);
|
||||
if (target != null) {
|
||||
for (Permanent creature : creatures) {
|
||||
if (creature != null) {
|
||||
creature.damage(4, id, game, false, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (targetPermanent.getName().isEmpty()) {
|
||||
filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected
|
||||
} else {
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
}
|
||||
return false;
|
||||
for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
|
||||
if (creature != null) {
|
||||
creature.damage(4, source.getSourceId(), game, false, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -88,9 +88,11 @@ public class EvilTwin extends CardImpl {
|
|||
class EvilTwinApplyToPermanent extends ApplyToPermanent {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with the same name as this creature");
|
||||
|
||||
static {
|
||||
filter.add(new EvilTwinPredicate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(Game game, Permanent permanent) {
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{U}{B}"));
|
||||
|
|
@ -107,8 +109,7 @@ class EvilTwinPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlaye
|
|||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
Permanent permanent = input.getObject();
|
||||
Permanent twin = game.getPermanent(input.getSourceId());
|
||||
|
||||
return permanent != null && twin != null && permanent.getName().equals(twin.getName());
|
||||
return permanent != null && twin != null && !twin.getName().isEmpty() && permanent.getName().equals(twin.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
*/
|
||||
package mage.sets.innistrad;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -38,10 +37,13 @@ import mage.abilities.costs.mana.ManaCostsImpl;
|
|||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.FlashbackAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
|
|
@ -91,13 +93,17 @@ class SeverTheBloodlineEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent targetPermanent = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
if (targetPermanent != null) {
|
||||
if (controller != null && targetPermanent != null) {
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
|
||||
for (Permanent permanent : permanents) {
|
||||
permanent.moveToExile(null, "", source.getSourceId(), game);
|
||||
if (targetPermanent.getName().isEmpty()) {
|
||||
filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected
|
||||
} else {
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
}
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
||||
controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.BATTLEFIELD);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import mage.constants.Outcome;
|
|||
import mage.constants.Rarity;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
|
@ -91,7 +92,11 @@ class EchoingCourageEffect extends OneShotEffect {
|
|||
Permanent targetPermanent = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
if (targetPermanent != null) {
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
if (targetPermanent.getName().isEmpty()) {
|
||||
filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected
|
||||
} else {
|
||||
filter.add(new NamePredicate(targetPermanent.getLogName()));
|
||||
}
|
||||
ContinuousEffect effect = new BoostAllEffect(2,2, Duration.EndOfTurn, filter, false);
|
||||
game.addEffect(effect, source);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
|||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.filter.FilterPermanent;
|
||||
|
|
@ -44,6 +43,7 @@ import mage.filter.predicate.mageobject.CardTypePredicate;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
/**
|
||||
|
|
@ -94,8 +94,9 @@ class ExclusionRitualImprintEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
Permanent targetPermanent = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
if (sourcePermanent != null && targetPermanent != null) {
|
||||
targetPermanent.moveToExile(getId(), sourcePermanent.getLogName() + " (Imprint)", source.getSourceId(), game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null && sourcePermanent != null && targetPermanent != null) {
|
||||
controller.moveCardToExileWithInfo(targetPermanent, getId(), sourcePermanent.getLogName(), source.getSourceId(), game, Zone.BATTLEFIELD);
|
||||
sourcePermanent.imprint(targetPermanent.getId(), game);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
package mage.sets.returntoravnica;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -109,11 +110,17 @@ class DetentionSphereEntersEffect extends OneShotEffect {
|
|||
UUID exileId = source.getSourceId();
|
||||
Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (exileId != null && targetPermanent != null && controller != null) {
|
||||
String name = targetPermanent.getName();
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||
if (permanent != null && permanent.getName().equals(name)) {
|
||||
controller.moveCardToExileWithInfo(permanent, exileId, "Detention Sphere", source.getSourceId(), game, Zone.BATTLEFIELD);
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (sourceObject != null && exileId != null && targetPermanent != null && controller != null) {
|
||||
|
||||
if (targetPermanent.getName().isEmpty()) { // face down creature
|
||||
controller.moveCardToExileWithInfo(targetPermanent, exileId, sourceObject.getLogName(), source.getSourceId(), game, Zone.BATTLEFIELD);
|
||||
} else {
|
||||
String name = targetPermanent.getLogName();
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||
if (permanent != null && permanent.getLogName().equals(name)) {
|
||||
controller.moveCardToExileWithInfo(permanent, exileId, sourceObject.getLogName(), source.getSourceId(), game, Zone.BATTLEFIELD);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import mage.constants.Outcome;
|
|||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
|
@ -107,13 +108,16 @@ class IzzetStaticasterDamageEffect extends OneShotEffect {
|
|||
Permanent targetPermanent = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
if (targetPermanent != null) {
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
|
||||
for (Permanent permanent : permanents) {
|
||||
if (targetPermanent.getName().isEmpty()) {
|
||||
filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected
|
||||
} else {
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
}
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
||||
permanent.damage(1, source.getSourceId(), game, false, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@
|
|||
package mage.sets.riseoftheeldrazi;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
|
|
@ -43,8 +45,10 @@ import mage.filter.FilterCard;
|
|||
import mage.filter.common.FilterLandCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -56,8 +60,6 @@ public class RealmsUncharted extends CardImpl {
|
|||
super(ownerId, 206, "Realms Uncharted", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{G}");
|
||||
this.expansionSetCode = "ROE";
|
||||
|
||||
this.color.setGreen(true);
|
||||
|
||||
// Search your library for four land cards with different names and reveal them. An opponent chooses two of those cards. Put the chosen cards into your graveyard and the rest into your hand. Then shuffle your library.
|
||||
this.getSpellAbility().addEffect(new RealmsUnchartedEffect());
|
||||
}
|
||||
|
|
@ -90,29 +92,38 @@ class RealmsUnchartedEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (controller == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RealmsUnchartedTarget target = new RealmsUnchartedTarget();
|
||||
if (player.searchLibrary(target, game)) {
|
||||
if (controller.searchLibrary(target, game)) {
|
||||
if (target.getTargets().size() > 0) {
|
||||
Cards cards = new CardsImpl();
|
||||
for (UUID cardId : (List<UUID>) target.getTargets()) {
|
||||
Card card = player.getLibrary().remove(cardId, game);
|
||||
Card card = controller.getLibrary().getCard(cardId, game);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
}
|
||||
}
|
||||
player.revealCards("Realms Uncharted", cards, game);
|
||||
controller.revealCards(sourceObject.getLogName(), cards, game);
|
||||
|
||||
CardsImpl cardsToKeep = new CardsImpl();
|
||||
if (cards.size() > 2) {
|
||||
cardsToKeep.addAll(cards);
|
||||
|
||||
Player opponent = game.getPlayer(game.getOpponents(player.getId()).iterator().next());
|
||||
TargetCard targetDiscard = new TargetCard(2, Zone.PICK, new FilterCard("cards to put in graveyard"));
|
||||
Player opponent;
|
||||
Set<UUID> opponents = game.getOpponents(controller.getId());
|
||||
if (opponents.size() == 1) {
|
||||
opponent = game.getPlayer(opponents.iterator().next());
|
||||
} else {
|
||||
Target targetOpponent = new TargetOpponent(true);
|
||||
controller.chooseTarget(Outcome.Detriment, targetOpponent, source, game);
|
||||
opponent = game.getPlayer(targetOpponent.getFirstTarget());
|
||||
}
|
||||
TargetCard targetDiscard = new TargetCard(2, Zone.LIBRARY, new FilterCard("cards to put in graveyard"));
|
||||
if (opponent != null && opponent.choose(Outcome.Discard, cards, targetDiscard, game)) {
|
||||
cardsToKeep.removeAll(targetDiscard.getTargets());
|
||||
cards.removeAll(cardsToKeep);
|
||||
|
|
@ -122,20 +133,20 @@ class RealmsUnchartedEffect extends OneShotEffect {
|
|||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true);
|
||||
controller.moveCardToGraveyardWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
|
||||
}
|
||||
}
|
||||
for (UUID cardId : cardsToKeep) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, true);
|
||||
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
|
||||
}
|
||||
}
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
controller.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
controller.shuffleLibrary(game);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -44,6 +45,7 @@ import mage.constants.Zone;
|
|||
import mage.filter.FilterCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
|
|
@ -94,28 +96,32 @@ class SteamAuguryEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (controller == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Cards cards = new CardsImpl(Zone.PICK);
|
||||
int count = Math.min(player.getLibrary().size(), 5);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
game.setZone(card.getId(), Zone.PICK);
|
||||
}
|
||||
Cards cards = new CardsImpl();
|
||||
cards.addAll(controller.getLibrary().getTopCards(game, 5));
|
||||
controller.revealCards(sourceObject.getLogName(), cards, game);
|
||||
|
||||
Player opponent;
|
||||
Set<UUID> opponents = game.getOpponents(controller.getId());
|
||||
if (opponents.size() == 1) {
|
||||
opponent = game.getPlayer(opponents.iterator().next());
|
||||
} else {
|
||||
Target target = new TargetOpponent(true);
|
||||
controller.chooseTarget(Outcome.Detriment, target, source, game);
|
||||
opponent = game.getPlayer(target.getFirstTarget());
|
||||
}
|
||||
player.revealCards("Steam Augury", cards, game);
|
||||
Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source));
|
||||
|
||||
if (opponent != null) {
|
||||
TargetCard target = new TargetCard(0, cards.size(), Zone.PICK, new FilterCard("cards to put in the first pile"));
|
||||
List<Card> pile1 = new ArrayList<>();
|
||||
Cards pile1CardsIds = new CardsImpl();
|
||||
target.setRequired(false);
|
||||
if (player.choose(Outcome.Neutral, cards, target, game)) {
|
||||
if (controller.choose(Outcome.Neutral, cards, target, game)) {
|
||||
List<UUID> targets = target.getTargets();
|
||||
for (UUID targetId : targets) {
|
||||
Card card = game.getCard(targetId);
|
||||
|
|
@ -134,7 +140,7 @@ class SteamAuguryEffect extends OneShotEffect {
|
|||
pile2CardsIds.add(card.getId());
|
||||
}
|
||||
}
|
||||
boolean choice = opponent.choosePile(Outcome.Detriment, new StringBuilder("Choose a pile to put into ").append(player.getName()).append("'s hand.").toString(), pile1, pile2, game);
|
||||
boolean choice = opponent.choosePile(Outcome.Detriment, new StringBuilder("Choose a pile to put into ").append(controller.getName()).append("'s hand.").toString(), pile1, pile2, game);
|
||||
|
||||
Zone pile1Zone = Zone.GRAVEYARD;
|
||||
Zone pile2Zone = Zone.HAND;
|
||||
|
|
@ -143,7 +149,7 @@ class SteamAuguryEffect extends OneShotEffect {
|
|||
pile2Zone = Zone.GRAVEYARD;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder("Steam Augury: Pile 1, going to ").append(pile1Zone.equals(Zone.HAND)?"Hand":"Graveyard").append (": ");
|
||||
StringBuilder sb = new StringBuilder(sourceObject.getLogName() + ": Pile 1, going to ").append(pile1Zone.equals(Zone.HAND)?"Hand":"Graveyard").append (": ");
|
||||
int i = 0;
|
||||
for (UUID cardUuid : pile1CardsIds) {
|
||||
i++;
|
||||
|
|
@ -158,7 +164,7 @@ class SteamAuguryEffect extends OneShotEffect {
|
|||
}
|
||||
game.informPlayers(sb.toString());
|
||||
|
||||
sb = new StringBuilder("Steam Augury: Pile 2, going to ").append(pile2Zone.equals(Zone.HAND)?"Hand":"Graveyard").append (":");
|
||||
sb = new StringBuilder(sourceObject.getLogName() + ": Pile 2, going to ").append(pile2Zone.equals(Zone.HAND)?"Hand":"Graveyard").append (":");
|
||||
i = 0;
|
||||
for (UUID cardUuid : pile2CardsIds) {
|
||||
Card card = game.getCard(cardUuid);
|
||||
|
|
|
|||
|
|
@ -359,4 +359,43 @@ public class MorphTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerA, "face down creature", 1);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that an effect like "arget creature and all other creatures with the same name" does
|
||||
* only effect one face down creature, also if multiple on the battlefield. Because they have no
|
||||
* name, they don't have the same name.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testEchoingDecaySameNameEffect() {
|
||||
// Sagu Mauler 6/6 - Creature - Beast
|
||||
// Trample, hexproof
|
||||
// Morph {3}{G}{B} (You may cast this card face down as a 2/2 creature for . Turn it face up any time for its morph cost.)
|
||||
addCard(Zone.HAND, playerA, "Sagu Mauler", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6);
|
||||
|
||||
// Echoing Decay {1}{B}
|
||||
// Instant
|
||||
// Target creature and all other creatures with the same name as that creature get -2/-2 until end of turn.
|
||||
addCard(Zone.HAND, playerB, "Echoing Decay");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sagu Mauler");
|
||||
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sagu Mauler");
|
||||
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Echoing Decay", "face down creature");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertHandCount(playerA, "Sagu Mauler", 0);
|
||||
assertHandCount(playerB, "Echoing Decay", 0);
|
||||
|
||||
assertPermanentCount(playerA, "face down creature", 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -592,7 +592,7 @@ public class TestPlayer extends ComputerPlayer {
|
|||
}
|
||||
for (UUID id: ability.getTargets().get(0).possibleTargets(ability.getSourceId(), ability.getControllerId(), game)) {
|
||||
MageObject object = game.getObject(id);
|
||||
if (object != null && object.getName().equals(targetName)) {
|
||||
if (object != null && object.getLogName().equals(targetName)) {
|
||||
if (index >= ability.getTargets().size()) {
|
||||
index--;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,13 @@
|
|||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
|
|
@ -56,16 +59,19 @@ public class DestroyAllNamedPermanentsEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
String name = permanent.getName();
|
||||
|
||||
permanent.destroy(source.getSourceId(), game, false);
|
||||
for (Permanent perm: game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
|
||||
if (perm.getName().equals(name)) {
|
||||
perm.destroy(source.getSourceId(), game, false);
|
||||
}
|
||||
Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (targetPermanent == null) {
|
||||
return false;
|
||||
}
|
||||
FilterPermanent filter = new FilterPermanent();
|
||||
if (targetPermanent.getName().isEmpty()) {
|
||||
filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected
|
||||
} else {
|
||||
filter.add(new NamePredicate(targetPermanent.getName()));
|
||||
}
|
||||
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
|
||||
perm.destroy(source.getSourceId(), game, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
*/
|
||||
package mage.filter.predicate.mageobject;
|
||||
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.MageObject;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
|
|
@ -51,12 +51,12 @@ public class NamePredicate implements Predicate<MageObject> {
|
|||
// If a player names a card, the player may name either half of a split card, but not both.
|
||||
// A split card has the chosen name if one of its two names matches the chosen name.
|
||||
if (input instanceof SplitCard) {
|
||||
return name.equals(((SplitCard)input).getLeftHalfCard().getLogName()) || name.equals(((SplitCard)input).getRightHalfCard().getLogName());
|
||||
return name.equals(((SplitCard)input).getLeftHalfCard().getName()) || name.equals(((SplitCard)input).getRightHalfCard().getLogName());
|
||||
} else if (input instanceof Spell && ((Spell)input).getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.SPLIT_FUSED)){
|
||||
SplitCard card = (SplitCard) ((Spell)input).getCard();
|
||||
return name.equals(card.getLeftHalfCard().getLogName()) || name.equals(card.getRightHalfCard().getLogName());
|
||||
return name.equals(card.getLeftHalfCard().getName()) || name.equals(card.getRightHalfCard().getLogName());
|
||||
} else {
|
||||
return name.equals(input.getLogName());
|
||||
return name.equals(input.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,25 +40,20 @@ public class TraceUtil {
|
|||
* @param combat
|
||||
*/
|
||||
public static void traceCombatIfNeeded(Game game, Combat combat) {
|
||||
// trace non-flying vs flying
|
||||
// trace non-flying vs flying
|
||||
for (CombatGroup group : combat.getGroups()) {
|
||||
for (UUID attackerId : group.getAttackers()) {
|
||||
Permanent attacker = game.getPermanent(attackerId);
|
||||
if (attacker != null) {
|
||||
if (hasFlying(attacker)) {
|
||||
// boolean traceDone = false;
|
||||
|
||||
// traceCombat(game, attacker, null);
|
||||
for (UUID blockerId : group.getBlockers()) {
|
||||
Permanent blocker = game.getPermanent(blockerId);
|
||||
if (blocker != null && !hasFlying(blocker) && !hasReach(blocker)) {
|
||||
log.warn("Found non-flying non-reach creature blocking creature with flying");
|
||||
traceCombat(game, attacker, blocker);
|
||||
// traceDone = true;
|
||||
}
|
||||
}
|
||||
// if (!traceDone) {
|
||||
// traceCombat(game, attacker, null);
|
||||
// }
|
||||
}
|
||||
if (hasIntimidate(attacker)) {
|
||||
for (UUID blockerId : group.getBlockers()) {
|
||||
|
|
@ -70,7 +65,6 @@ public class TraceUtil {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasUnblockable(attacker)) {
|
||||
if (group.getBlockers().size() > 0) {
|
||||
Permanent blocker = game.getPermanent(group.getBlockers().get(0));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue