diff --git a/Mage.Sets/src/mage/cards/a/ArcticFoxes.java b/Mage.Sets/src/mage/cards/a/ArcticFoxes.java
index b658e56e0e..d6b86a7d42 100644
--- a/Mage.Sets/src/mage/cards/a/ArcticFoxes.java
+++ b/Mage.Sets/src/mage/cards/a/ArcticFoxes.java
@@ -68,6 +68,6 @@ enum ArcticFoxesCondition implements Condition {
if (defenderId == null) {
return false;
}
- return game.getBattlefield().contains(filter, defenderId, 1, game);
+ return game.getBattlefield().contains(filter, source.getSourceId(), defenderId, game, 1);
}
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/CityInABottle.java b/Mage.Sets/src/mage/cards/c/CityInABottle.java
index 8a570d692a..0d36c7ffbc 100644
--- a/Mage.Sets/src/mage/cards/c/CityInABottle.java
+++ b/Mage.Sets/src/mage/cards/c/CityInABottle.java
@@ -1,8 +1,5 @@
package mage.cards.c;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.StateTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -11,7 +8,6 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import static mage.cards.c.CityInABottle.getArabianNightsNamePredicates;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
@@ -23,11 +19,15 @@ import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import static mage.cards.c.CityInABottle.getArabianNightsNamePredicates;
+
/**
- *
* @author emerald000
*/
public final class CityInABottle extends CardImpl {
@@ -158,7 +158,7 @@ class CityInABottleStateTriggeredAbility extends StateTriggeredAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- return game.getBattlefield().contains(filter, this.getControllerId(), game, 1);
+ return game.getBattlefield().contains(filter, this.getSourceId(), this.getControllerId(), game, 1);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/c/ConcertedEffort.java b/Mage.Sets/src/mage/cards/c/ConcertedEffort.java
index 3d17beca5d..cd7ddf4724 100644
--- a/Mage.Sets/src/mage/cards/c/ConcertedEffort.java
+++ b/Mage.Sets/src/mage/cards/c/ConcertedEffort.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@@ -18,14 +16,15 @@ import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class ConcertedEffort extends CardImpl {
public ConcertedEffort(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
// At the beginning of each upkeep, creatures you control gain flying until end of turn if a creature you control has flying. The same is true for fear, first strike, double strike, landwalk, protection, trample, and vigilance.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ConcertedEffortEffect(), TargetController.ANY, false));
@@ -81,22 +80,22 @@ class ConcertedEffortEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
// Flying
- if (game.getBattlefield().contains(filterFlying, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().contains(filterFlying, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Fear
- if (game.getBattlefield().contains(filterFear, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().contains(filterFear, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(FearAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// First strike
- if (game.getBattlefield().contains(filterFirstStrike, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().contains(filterFirstStrike, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Double strike
- if (game.getBattlefield().contains(filterDoubleStrike, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().contains(filterDoubleStrike, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
@@ -119,12 +118,12 @@ class ConcertedEffortEffect extends OneShotEffect {
}
// Trample
- if (game.getBattlefield().contains(filterTrample, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().contains(filterTrample, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Vigilance
- if (game.getBattlefield().contains(filterVigilance, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().contains(filterVigilance, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/c/CullingScales.java b/Mage.Sets/src/mage/cards/c/CullingScales.java
index 5c8a890a79..4917bc673b 100644
--- a/Mage.Sets/src/mage/cards/c/CullingScales.java
+++ b/Mage.Sets/src/mage/cards/c/CullingScales.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.common.DestroyTargetEffect;
@@ -12,27 +10,30 @@ import mage.constants.ComparisonType;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterNonlandPermanent;
-import mage.filter.predicate.Predicate;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
+import java.util.UUID;
+
/**
- *
* @author cg5
*/
public final class CullingScales extends CardImpl {
private static final FilterPermanent filterNonlandPermanentWithLowestCmc = new FilterNonlandPermanent(
- "nonland permanent with the lowest converted mana cost (If two or more permanents are tied for lowest cost, target any one of them.)"
+ "nonland permanent with the lowest converted mana cost (If two or more permanents are tied for lowest cost, target any one of them.)"
);
+
static {
filterNonlandPermanentWithLowestCmc.add(new HasLowestCMCAmongstNonlandPermanentsPredicate());
}
-
+
public CullingScales(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// At the beginning of your upkeep, destroy target nonland permanent with the lowest converted mana cost.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new DestroyTargetEffect(), TargetController.YOU, false);
@@ -48,16 +49,16 @@ public final class CullingScales extends CardImpl {
public CullingScales copy() {
return new CullingScales(this);
}
-
+
}
-class HasLowestCMCAmongstNonlandPermanentsPredicate implements Predicate {
-
+class HasLowestCMCAmongstNonlandPermanentsPredicate implements ObjectSourcePlayerPredicate> {
+
@Override
- public boolean apply(Permanent input, Game game) {
+ public boolean apply(ObjectSourcePlayer input, Game game) {
FilterPermanent filter = new FilterNonlandPermanent();
- filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, input.getConvertedManaCost()));
- return !game.getBattlefield().contains(filter, 1, game);
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, input.getObject().getConvertedManaCost()));
+ return !game.getBattlefield().contains(filter, input.getSourceId(), input.getPlayerId(), game, 1);
}
-
+
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/d/DoomForetold.java b/Mage.Sets/src/mage/cards/d/DoomForetold.java
index 294e46acda..090c663cc4 100644
--- a/Mage.Sets/src/mage/cards/d/DoomForetold.java
+++ b/Mage.Sets/src/mage/cards/d/DoomForetold.java
@@ -84,7 +84,7 @@ class DoomForetoldEffect extends OneShotEffect {
}
FilterPermanent filter2 = filter.copy();
filter2.add(new ControllerIdPredicate(player.getId()));
- if (game.getBattlefield().contains(filter2, 1, game)) {
+ if (game.getBattlefield().contains(filter2, source, game, 1)) {
TargetPermanent target = new TargetPermanent(filter2);
target.setNotTarget(true);
if (player.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) {
diff --git a/Mage.Sets/src/mage/cards/h/HedronAlignment.java b/Mage.Sets/src/mage/cards/h/HedronAlignment.java
index 2468d05c77..c825a61407 100644
--- a/Mage.Sets/src/mage/cards/h/HedronAlignment.java
+++ b/Mage.Sets/src/mage/cards/h/HedronAlignment.java
@@ -1,7 +1,5 @@
-
package mage.cards.h;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@@ -24,14 +22,15 @@ import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class HedronAlignment extends CardImpl {
public HedronAlignment(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
// Hexproof
this.addAbility(HexproofAbility.getInstance());
@@ -85,7 +84,7 @@ class HedronAlignmentEffect extends OneShotEffect {
Cards cardsToReveal = new CardsImpl();
controller.revealCards(sourceObject.getIdName(), cardsToReveal, game);
// Check battlefield
- if (!game.getBattlefield().contains(filterPermanent, source.getControllerId(), game, 1)) {
+ if (!game.getBattlefield().contains(filterPermanent, source, game, 1)) {
return true;
}
if (controller.getHand().getCards(filterCard, source.getSourceId(), controller.getId(), game).isEmpty()) {
diff --git a/Mage.Sets/src/mage/cards/h/HeraldOfLeshrac.java b/Mage.Sets/src/mage/cards/h/HeraldOfLeshrac.java
index 9545ca7f1e..7425917715 100644
--- a/Mage.Sets/src/mage/cards/h/HeraldOfLeshrac.java
+++ b/Mage.Sets/src/mage/cards/h/HeraldOfLeshrac.java
@@ -1,7 +1,5 @@
-
package mage.cards.h;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
@@ -17,12 +15,7 @@ import mage.abilities.keyword.CumulativeUpkeepAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.TargetController;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.common.FilterLandPermanent;
@@ -34,13 +27,15 @@ import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class HeraldOfLeshrac extends CardImpl {
private static final FilterPermanent filter = new FilterControlledLandPermanent("land you control but don't own");
+
static {
filter.add(TargetController.NOT_YOU.getOwnerPredicate());
}
@@ -78,6 +73,7 @@ public final class HeraldOfLeshrac extends CardImpl {
class HeraldOfLeshracCumulativeCost extends CostImpl {
private static final FilterPermanent filter = new FilterLandPermanent("land you don't control");
+
static {
filter.add(TargetController.NOT_YOU.getControllerPredicate());
}
@@ -105,7 +101,7 @@ class HeraldOfLeshracCumulativeCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return game.getBattlefield().contains(filter, controllerId, game, 1);
+ return game.getBattlefield().contains(filter, source.getSourceId(), controllerId, game, 1);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/m/MajesticMyriarch.java b/Mage.Sets/src/mage/cards/m/MajesticMyriarch.java
index 847eb1ed20..c0475fb234 100644
--- a/Mage.Sets/src/mage/cards/m/MajesticMyriarch.java
+++ b/Mage.Sets/src/mage/cards/m/MajesticMyriarch.java
@@ -103,62 +103,62 @@ class MajesticMyriarchEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
// Flying
- if (game.getBattlefield().contains(filterFlying, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterFlying, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), source);
}
// First strike
- if (game.getBattlefield().contains(filterFirstStrike, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterFirstStrike, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), source);
}
// Double strike
- if (game.getBattlefield().contains(filterDoubleStrike, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterDoubleStrike, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn), source);
}
// Deathtouch
- if (game.getBattlefield().contains(filterDeathtouch, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterDeathtouch, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn), source);
}
// Haste
- if (game.getBattlefield().contains(filterHaste, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterHaste, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn), source);
}
// Hexproof
- if (game.getBattlefield().contains(filterHexproof, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterHexproof, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(HexproofAbility.getInstance(), Duration.EndOfTurn), source);
}
// Indestructible
- if (game.getBattlefield().contains(filterIndestructible, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterIndestructible, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), source);
}
// Lifelink
- if (game.getBattlefield().contains(filterLifelink, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterLifelink, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn), source);
}
// Menace
- if (game.getBattlefield().contains(filterMenace, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterMenace, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn), source);
}
// Reach
- if (game.getBattlefield().contains(filterReach, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterReach, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(ReachAbility.getInstance(), Duration.EndOfTurn), source);
}
// Trample
- if (game.getBattlefield().contains(filterTrample, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterTrample, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), source);
}
// Vigilance
- if (game.getBattlefield().contains(filterVigilance, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterVigilance, source, game, 1)) {
game.addEffect(new GainAbilitySourceEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn), source);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java b/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java
index bd0a2c6af4..34781787fe 100644
--- a/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java
+++ b/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java
@@ -1,4 +1,3 @@
-
package mage.cards.o;
import mage.MageInt;
@@ -94,67 +93,67 @@ class OdricLunarchMarshalEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
// First strike
- if (game.getBattlefield().contains(filterFirstStrike, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterFirstStrike, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Flying
- if (game.getBattlefield().contains(filterFlying, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterFlying, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Deathtouch
- if (game.getBattlefield().contains(filterDeathtouch, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterDeathtouch, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Double strike
- if (game.getBattlefield().contains(filterDoubleStrike, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterDoubleStrike, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Haste
- if (game.getBattlefield().contains(filterHaste, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterHaste, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Hexproof
- if (game.getBattlefield().contains(filterHexproof, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterHexproof, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(HexproofAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Indestructible
- if (game.getBattlefield().contains(filterIndestructible, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterIndestructible, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Lifelink
- if (game.getBattlefield().contains(filterLifelink, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterLifelink, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Menace
- if (game.getBattlefield().contains(filterMenace, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterMenace, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(new MenaceAbility(), Duration.EndOfTurn, filterCreatures), source);
}
// Reach
- if (game.getBattlefield().contains(filterReach, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterReach, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(ReachAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Skulk
- if (game.getBattlefield().contains(filterSkulk, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterSkulk, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(new SkulkAbility(), Duration.EndOfTurn, filterCreatures), source);
}
// Trample
- if (game.getBattlefield().contains(filterTrample, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterTrample, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
// Vigilance
- if (game.getBattlefield().contains(filterVigilance, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filterVigilance, source, game, 1)) {
game.addEffect(new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/r/RemorselessPunishment.java b/Mage.Sets/src/mage/cards/r/RemorselessPunishment.java
index 886c612107..e537dac680 100644
--- a/Mage.Sets/src/mage/cards/r/RemorselessPunishment.java
+++ b/Mage.Sets/src/mage/cards/r/RemorselessPunishment.java
@@ -1,7 +1,5 @@
-
package mage.cards.r;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
@@ -16,14 +14,15 @@ import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetOpponent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class RemorselessPunishment extends CardImpl {
public RemorselessPunishment(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{B}");
// Target opponent loses 5 life unless that player discards two cards or sacrifices a creature or planeswalker. Repeat this process once.
getSpellAbility().addEffect(new RemorselessPunishmentEffect());
@@ -80,7 +79,7 @@ class RemorselessPunishmentEffect extends OneShotEffect {
return;
}
}
- if (game.getBattlefield().contains(filter, opponent.getId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filter, source.getSourceId(), opponent.getId(), game, 1)) {
if (opponent.chooseUse(outcome, "Choose your " + iteration + " punishment.", null, "Sacrifice a creature or planeswalker", "Lose 5 life", source, game)) {
TargetPermanent target = new TargetPermanent(1, 1, filter, true);
if (target.choose(Outcome.Sacrifice, opponent.getId(), source.getId(), game)) {
diff --git a/Mage.Sets/src/mage/cards/s/ShelteringAncient.java b/Mage.Sets/src/mage/cards/s/ShelteringAncient.java
index 272bbc5e05..531688db7b 100644
--- a/Mage.Sets/src/mage/cards/s/ShelteringAncient.java
+++ b/Mage.Sets/src/mage/cards/s/ShelteringAncient.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
@@ -11,8 +9,8 @@ import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
@@ -22,8 +20,9 @@ import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class ShelteringAncient extends CardImpl {
@@ -82,7 +81,7 @@ class ShelteringAncientCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return game.getBattlefield().contains(filter, source.getSourceId(), game, 1);
+ return game.getBattlefield().contains(filter, source, game, 1);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/t/TheCheeseStandsAlone.java b/Mage.Sets/src/mage/cards/t/TheCheeseStandsAlone.java
index 51a15f4c2f..571754535a 100644
--- a/Mage.Sets/src/mage/cards/t/TheCheeseStandsAlone.java
+++ b/Mage.Sets/src/mage/cards/t/TheCheeseStandsAlone.java
@@ -1,7 +1,5 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
@@ -18,8 +16,9 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author spjspj
*/
public final class TheCheeseStandsAlone extends CardImpl {
@@ -47,6 +46,7 @@ class CheeseStandsAloneContinuousEffect extends ContinuousRuleModifyingEffectImp
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
private boolean wonAlready = false;
+
static {
filter.add(new NamePredicate("The Cheese Stands Alone"));
}
@@ -57,7 +57,7 @@ class CheeseStandsAloneContinuousEffect extends ContinuousRuleModifyingEffectImp
}
public CheeseStandsAloneContinuousEffect(final CheeseStandsAloneContinuousEffect effect) {
- super(effect);
+ super(effect);
}
@Override
@@ -72,7 +72,7 @@ class CheeseStandsAloneContinuousEffect extends ContinuousRuleModifyingEffectImp
if (controller.getHand().isEmpty()) {
int numberPerms = new PermanentsOnBattlefieldCount(new FilterControlledPermanent()).calculate(game, source, this);
if (numberPerms == 1) {
- if (game.getBattlefield().contains(filter, source.getControllerId(), 1, game)) {
+ if (game.getBattlefield().containsControlled(filter, source, game, 1)) {
if (!wonAlready) {
wonAlready = true;
controller.won(game);
diff --git a/Mage.Sets/src/mage/cards/t/TidalInfluence.java b/Mage.Sets/src/mage/cards/t/TidalInfluence.java
index cdb1f64ed2..a25f2d06c0 100644
--- a/Mage.Sets/src/mage/cards/t/TidalInfluence.java
+++ b/Mage.Sets/src/mage/cards/t/TidalInfluence.java
@@ -1,7 +1,5 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.StateTriggeredAbility;
@@ -31,8 +29,9 @@ import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
+import java.util.UUID;
+
/**
- *
* @author LoneFox
*/
public final class TidalInfluence extends CardImpl {
@@ -44,26 +43,26 @@ public final class TidalInfluence extends CardImpl {
}
public TidalInfluence(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
// Cast Tidal Influence only if no permanents named Tidal Influence are on the battlefield.
this.getSpellAbility().addCost(new TidalInfluenceCost());
// Tidal Influence enters the battlefield with a tide counter on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.TIDE.createInstance()),
- "with a tide counter on it."));
+ "with a tide counter on it."));
// At the beginning of your upkeep, put a tide counter on Tidal Influence.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.TIDE.createInstance()),
- TargetController.YOU, false));
+ TargetController.YOU, false));
// As long as there is exactly one tide counter on Tidal Influence, all blue creatures get -2/-0.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
- new BoostAllEffect(-2, -0, Duration.WhileOnBattlefield, filter, false),
- new SourceHasCounterCondition(CounterType.TIDE, 1, 1),
- "As long as there is exactly one tide counter on {this}, all blue creatures get -2/-0.")));
+ new BoostAllEffect(-2, -0, Duration.WhileOnBattlefield, filter, false),
+ new SourceHasCounterCondition(CounterType.TIDE, 1, 1),
+ "As long as there is exactly one tide counter on {this}, all blue creatures get -2/-0.")));
// As long as there are exactly three tide counters on Tidal Influence, all blue creatures get +2/+0.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
- new BoostAllEffect(2, -0, Duration.WhileOnBattlefield, filter, false),
- new SourceHasCounterCondition(CounterType.TIDE, 3, 3),
- "As long as there are exactly three tide counter on {this}, all blue creatures get +2/-0.")));
+ new BoostAllEffect(2, -0, Duration.WhileOnBattlefield, filter, false),
+ new SourceHasCounterCondition(CounterType.TIDE, 3, 3),
+ "As long as there are exactly three tide counter on {this}, all blue creatures get +2/-0.")));
// Whenever there are four tide counters on Tidal Influence, remove all tide counters from it.
this.addAbility(new TidalInfluenceTriggeredAbility(new RemoveAllCountersSourceEffect(CounterType.TIDE)));
}
@@ -97,7 +96,7 @@ class TidalInfluenceCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return !game.getBattlefield().contains(filter, 1, game);
+ return !game.getBattlefield().contains(filter, source, game, 1);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/t/TravelersCloak.java b/Mage.Sets/src/mage/cards/t/TravelersCloak.java
index 474de5cc44..c78c2a1471 100644
--- a/Mage.Sets/src/mage/cards/t/TravelersCloak.java
+++ b/Mage.Sets/src/mage/cards/t/TravelersCloak.java
@@ -1,13 +1,13 @@
-
package mage.cards.t;
-import java.util.UUID;
+import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.ChooseCreatureTypeEffect;
import mage.abilities.effects.common.ChooseLandTypeEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
@@ -15,24 +15,24 @@ import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.LandwalkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AttachmentType;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.common.FilterLandPermanent;
-import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class TravelersCloak extends CardImpl {
public TravelersCloak(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
this.subtype.add(SubType.AURA);
// Enchant creature
@@ -41,18 +41,17 @@ public final class TravelersCloak extends CardImpl {
this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
-
+
// As Traveler's Cloak enters the battlefield, choose a land type.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseLandTypeEffect(Outcome.AddAbility)));
-
+
// When Traveler's Cloak enters the battlefield, draw a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), false));
-
+
// Enchanted creature has landwalk of the chosen type.
FilterLandPermanent filter = new FilterLandPermanent("Landwalk of the chosen type");
- filter.add(ChosenSubtypePredicate.instance);
- Ability landwalkAbility = new LandwalkAbility(filter);
- Effect effect = new GainAbilityAttachedEffect(landwalkAbility, AttachmentType.AURA);
+ filter.add(TravelersCloakChosenSubtypePredicate.instance);
+ Effect effect = new TravelersCloakGainAbilityAttachedEffect(filter);
effect.setText("Enchanted creature has landwalk of the chosen type");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
}
@@ -66,3 +65,35 @@ public final class TravelersCloak extends CardImpl {
return new TravelersCloak(this);
}
}
+
+class TravelersCloakGainAbilityAttachedEffect extends GainAbilityAttachedEffect {
+
+ public TravelersCloakGainAbilityAttachedEffect(FilterLandPermanent filter) {
+ super(new LandwalkAbility(filter), AttachmentType.AURA);
+ }
+
+ @Override
+ public void afterGain(Game game, Ability source, Permanent permanent, Ability addedAbility) {
+ super.afterGain(game, source, permanent, addedAbility);
+
+ // ChooseLandTypeEffect keep settings in original source, but we must transfer it to real permanent
+ Object val = game.getState().getValue(source.getSourceId() + "_type");
+ game.getState().setValue(permanent.getId() + "_landwalk_type", val);
+ }
+}
+
+enum TravelersCloakChosenSubtypePredicate implements ObjectSourcePlayerPredicate> {
+ instance;
+
+ @Override
+ public boolean apply(ObjectSourcePlayer input, Game game) {
+ SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(input.getSourceId(), game, "_landwalk_type");
+ return input.getObject().hasSubtype(subType, game);
+ }
+
+ @Override
+ public String toString() {
+ return "Chosen subtype";
+ }
+}
+
diff --git a/Mage.Sets/src/mage/cards/w/WeightOfConscience.java b/Mage.Sets/src/mage/cards/w/WeightOfConscience.java
index 49f6d7c665..96a45851fd 100644
--- a/Mage.Sets/src/mage/cards/w/WeightOfConscience.java
+++ b/Mage.Sets/src/mage/cards/w/WeightOfConscience.java
@@ -1,9 +1,5 @@
package mage.cards.w;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -25,8 +21,12 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class WeightOfConscience extends CardImpl {
@@ -84,8 +84,8 @@ class WeightOfConscienceEffect extends OneShotEffect {
// It was not blinked, use the standard method
enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
}
- if (controller != null
- && enchantment != null
+ if (controller != null
+ && enchantment != null
&& enchantment.getAttachedTo() != null) {
Permanent creature = game.getPermanent(enchantment.getAttachedTo());
if (creature != null) {
@@ -119,10 +119,10 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent {
if (player != null) {
// Choosing first target
if (this.getTargets().isEmpty()) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, sourceId, game)) {
for (SubType subtype : permanent.getSubtype(game)) {
if (subtype.getSubTypeSet() == SubTypeSet.CreatureType) {
- if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(subtype, subtype.toString()), sourceControllerId, game, 2)) {
+ if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(subtype, subtype.toString()), sourceId, sourceControllerId, game, 2)) {
possibleTargets.add(permanent.getId());
}
}
@@ -133,7 +133,7 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent {
UUID firstTargetId = this.getTargets().get(0);
Permanent firstTargetCreature = game.getPermanent(firstTargetId);
if (firstTargetCreature != null) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, sourceId, game)) {
if (!permanent.getId().equals(firstTargetId) && firstTargetCreature.shareCreatureTypes(permanent, game)) {
possibleTargets.add(permanent.getId());
}
@@ -146,8 +146,8 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent {
@Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
- for (Permanent permanent1 : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) {
- for (Permanent permanent2 : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) {
+ for (Permanent permanent1 : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, sourceId, game)) {
+ for (Permanent permanent2 : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, sourceId, game)) {
if (!Objects.equals(permanent1, permanent2) && permanent1.shareCreatureTypes(permanent2, game)) {
return true;
}
@@ -162,10 +162,10 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent {
Permanent targetPermanent = game.getPermanent(id);
if (targetPermanent != null) {
if (this.getTargets().isEmpty()) {
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, source.getControllerId(), game)) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, source.getControllerId(), source.getSourceId(), game)) {
for (SubType subtype : permanent.getSubtype(game)) {
if (subtype.getSubTypeSet() == SubTypeSet.CreatureType) {
- if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(subtype, subtype.toString()), source.getControllerId(), game, 2)) {
+ if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(subtype, subtype.toString()), source, game, 2)) {
return true;
}
}
@@ -173,9 +173,7 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent {
}
} else {
Permanent firstTarget = game.getPermanent(this.getTargets().get(0));
- if (firstTarget != null && firstTarget.shareCreatureTypes(targetPermanent, game)) {
- return true;
- }
+ return firstTarget != null && firstTarget.shareCreatureTypes(targetPermanent, game);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/w/Wirecat.java b/Mage.Sets/src/mage/cards/w/Wirecat.java
index d7de3f3729..79bb613a15 100644
--- a/Mage.Sets/src/mage/cards/w/Wirecat.java
+++ b/Mage.Sets/src/mage/cards/w/Wirecat.java
@@ -69,7 +69,7 @@ public final class Wirecat extends CardImpl {
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(source.getSourceId())) {
- return game.getBattlefield().contains(StaticFilters.FILTER_ENCHANTMENT_PERMANENT, 1, game);
+ return game.getBattlefield().contains(StaticFilters.FILTER_ENCHANTMENT_PERMANENT, source, game, 1);
}
return false;
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/LegendarySorceryTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/LegendarySorceryTest.java
index 68936f2290..aa70d08789 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/LegendarySorceryTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/LegendarySorceryTest.java
@@ -1,4 +1,3 @@
-
package org.mage.test.cards.conditional;
import mage.constants.PhaseStep;
@@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
- *
* @author LevelX2
*/
public class LegendarySorceryTest extends CardTestPlayerBase {
@@ -55,10 +53,13 @@ public class LegendarySorceryTest extends CardTestPlayerBase {
// Flying, first strike, vigilance, trample, haste, protection from black and from red
addCard(Zone.BATTLEFIELD, playerB, "Akroma, Angel of Wrath", 1); // Legendary
+ // can't cast cause you don't have a legendary creature (only opponent have)
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Urza's Ruinous Blast");
+ //setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
+ //assertAllCommandsUsed();
assertGraveyardCount(playerA, "Urza's Ruinous Blast", 0);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/inv/TravelersCloakTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/inv/TravelersCloakTest.java
new file mode 100644
index 0000000000..4e83fda10f
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/inv/TravelersCloakTest.java
@@ -0,0 +1,54 @@
+package org.mage.test.cards.single.inv;
+
+import mage.abilities.keyword.LandwalkAbility;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.game.permanent.Permanent;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author JayDi85
+ */
+
+public class TravelersCloakTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_MustHaveLandWalkOfTheChosenType() {
+ // Enchant creature
+ // As Traveler's Cloak enters the battlefield, choose a land type.
+ // When Traveler's Cloak enters the battlefield, draw a card.
+ // Enchanted creature has landwalk of the chosen type.
+ addCard(Zone.HAND, playerA, "Traveler's Cloak"); // {2}{U}
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
+ //
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Kitesail Corsair", 1);
+
+ // cast and assign landwalk ability to creature
+ checkAbility("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", LandwalkAbility.class, false);
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Traveler's Cloak", "Grizzly Bears");
+ setChoice(playerA, "Swamp"); // land type for landwalk
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
+ checkAbility("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", LandwalkAbility.class, true);
+
+ // check that it can't be blocked
+ attack(1, playerA, "Grizzly Bears");
+ runCode("check blocking", 1, PhaseStep.DECLARE_BLOCKERS, playerB, (info, player, game) -> {
+ Permanent blocker = game.getBattlefield().getAllActivePermanents()
+ .stream()
+ .filter(p -> p.getName().equals("Kitesail Corsair"))
+ .findFirst()
+ .get();
+ Assert.assertFalse("Grizzly Bears must be protected from blocking by Kitesail Corsair",
+ game.getCombat().getGroups().get(0).canBlock(blocker, game));
+ });
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+ }
+}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/m21/ConspicuousSnoopTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/m21/ConspicuousSnoopTest.java
index 140b141c3d..d9424400c9 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/m21/ConspicuousSnoopTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/m21/ConspicuousSnoopTest.java
@@ -9,7 +9,7 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class ConspicuousSnoopTest extends CardTestPlayerBase {
@Test
- public void testTopCardLibraryRevealed(){
+ public void test_TopCardLibraryRevealed() {
// Play with the top card of your library revealed.
addCard(Zone.BATTLEFIELD, playerA, "Conspicuous Snoop");
addCard(Zone.LIBRARY, playerA, "Swamp");
@@ -23,43 +23,49 @@ public class ConspicuousSnoopTest extends CardTestPlayerBase {
}
@Test
- public void castGoblinSpellsFromLibrary(){
+ public void test_castGoblinSpellsFromLibrary() {
+ skipInitShuffling();
+ removeAllCardsFromLibrary(playerA);
+
// You may cast Goblin spells from the top of your library.
addCard(Zone.BATTLEFIELD, playerA, "Conspicuous Snoop");
-
- addCard(Zone.LIBRARY, playerA, "Goblin Lackey");
- skipInitShuffling();
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
- // Whenever Goblin Lackey deals damage to a player, you may put a Goblin permanent card from your hand onto the battlefield.
+ addCard(Zone.LIBRARY, playerA, "Atog", 1); // second from top
+ addCard(Zone.LIBRARY, playerA, "Goblin Lackey", 1); // first from top
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2 * 2);
+
+ // Whenever Goblin Lackey deals damage to a player, you may put a Goblin permanent card from your hand onto the battlefield.
+ checkPlayableAbility("can play goblin", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Lackey", true);
+ checkPlayableAbility("can't play non goblin before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Atog", false);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Goblin Lackey");
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
+ checkPlayableAbility("can't play non goblin after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Atog", false);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
setStrictChooseMode(true);
execute();
assertAllCommandsUsed();
- assertPermanentCount(playerA, "Goblin Lackey", 1);
+ assertPermanentCount(playerA, "Goblin Lackey", 1);
}
@Test
- public void hasActivatedAbilities(){
+ public void test_hasActivatedAbilities() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
// Play with the top card of your library revealed.
// You may cast Goblin spells from the top of your library.
// As long as the top card of your library is a Goblin card, Conspicuous Snoop has all activated abilities of that card.
addCard(Zone.BATTLEFIELD, playerA, "Conspicuous Snoop");
// {R}: Goblin Balloon Brigade gains flying until end of turn.
- addCard(Zone.LIBRARY, playerA, "Goblin Balloon Brigade");
+ addCard(Zone.LIBRARY, playerA, "Goblin Balloon Brigade");
skipInitShuffling();
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
-
+
setStrictChooseMode(true);
execute();
-
+
assertAllCommandsUsed();
assertAbilityCount(playerA, "Conspicuous Snoop", ActivatedAbility.class, 3); // (2 X casts + gains flying )
-
}
}
diff --git a/Mage/src/main/java/mage/abilities/common/LegendarySpellAbility.java b/Mage/src/main/java/mage/abilities/common/LegendarySpellAbility.java
index 0cc00740fd..2ad18db7a9 100644
--- a/Mage/src/main/java/mage/abilities/common/LegendarySpellAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/LegendarySpellAbility.java
@@ -2,11 +2,7 @@ package mage.abilities.common;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.SuperType;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
@@ -65,7 +61,7 @@ class LegendarySpellAbilityCheckEffect extends ContinuousRuleModifyingEffectImpl
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getSourceId().equals(source.getSourceId())
- && !game.getBattlefield().contains(filter, event.getPlayerId(), 1, game);
+ && !game.getBattlefield().containsControlled(filter, source, game, 1);
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/condition/common/MetalcraftCondition.java b/Mage/src/main/java/mage/abilities/condition/common/MetalcraftCondition.java
index 51e7683679..66cc9ce3bb 100644
--- a/Mage/src/main/java/mage/abilities/condition/common/MetalcraftCondition.java
+++ b/Mage/src/main/java/mage/abilities/condition/common/MetalcraftCondition.java
@@ -22,7 +22,7 @@ public enum MetalcraftCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
- return game.getBattlefield().contains(filter, source.getControllerId(), 3, game);
+ return game.getBattlefield().containsControlled(filter, source, game, 3);
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/costs/common/ControlPermanentCost.java b/Mage/src/main/java/mage/abilities/costs/common/ControlPermanentCost.java
index 17c366f5fc..c557d3b7d8 100644
--- a/Mage/src/main/java/mage/abilities/costs/common/ControlPermanentCost.java
+++ b/Mage/src/main/java/mage/abilities/costs/common/ControlPermanentCost.java
@@ -1,15 +1,15 @@
package mage.abilities.costs.common;
import mage.abilities.Ability;
+import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import java.util.UUID;
-import mage.abilities.costs.Cost;
public class ControlPermanentCost extends CostImpl {
- private FilterControlledPermanent filter;
+ private final FilterControlledPermanent filter;
public ControlPermanentCost(FilterControlledPermanent filter) {
this.filter = filter.copy();
@@ -23,7 +23,7 @@ public class ControlPermanentCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- return game.getBattlefield().contains(filter, controllerId, 1, game);
+ return game.getBattlefield().containsControlled(filter, source.getSourceId(), controllerId, game, 1);
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java
index c1bdd3f9f4..1f89ff5a78 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java
@@ -1,7 +1,5 @@
-
package mage.abilities.effects.common;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@@ -14,6 +12,8 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
+import java.util.UUID;
+
/**
* @author LevelX2
*/
@@ -56,15 +56,19 @@ public class ChooseCreatureTypeEffect extends OneShotEffect {
return new ChooseCreatureTypeEffect(this);
}
+ public static SubType getChosenCreatureType(UUID objectId, Game game) {
+ return getChosenCreatureType(objectId, game, "_type");
+ }
+
/**
- *
- * @param objectId sourceId the effect was exeuted under
+ * @param objectId sourceId the effect was exeuted under
* @param game
+ * @param typePostfix special postfix if you want to store multiple choices from different effects
* @return
*/
- public static SubType getChosenCreatureType(UUID objectId, Game game) {
+ public static SubType getChosenCreatureType(UUID objectId, Game game, String typePostfix) {
SubType creatureType = null;
- Object savedCreatureType = game.getState().getValue(objectId + "_type");
+ Object savedCreatureType = game.getState().getValue(objectId + typePostfix);
if (savedCreatureType != null) {
creatureType = SubType.byDescription(savedCreatureType.toString());
}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java
index 3eb23d9a7b..437d4a8b9d 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java
@@ -96,10 +96,23 @@ public class GainAbilityAttachedEffect extends ContinuousEffectImpl {
}
if (permanent != null) {
permanent.addAbility(ability, source.getSourceId(), game);
+ afterGain(game, source, permanent, ability);
}
return true;
}
+ /**
+ * Calls after ability gain. Override it to apply additional data (example: transfer ability's settings from original to destination source)
+ *
+ * @param game
+ * @param source
+ * @param permanent
+ * @param addedAbility
+ */
+ public void afterGain(Game game, Ability source, Permanent permanent, Ability addedAbility) {
+ //
+ }
+
private void setText() {
StringBuilder sb = new StringBuilder();
sb.append(attachmentType.verb());
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java
index b0119f9485..34b136f26a 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java
@@ -61,7 +61,7 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl {
&& playerId.equals(source.getControllerId())
&& cardToCheck.isOwnedBy(source.getControllerId())
&& (!cardToCheck.getManaCost().isEmpty() || cardToCheck.isLand())
- && filter.match(cardToCheck, game)) {
+ && filter.match(cardToCheck, source.getSourceId(), source.getControllerId(), game)) {
Player player = game.getPlayer(cardToCheck.getOwnerId());
UUID needCardID = player.getLibrary().getFromTop(game) == null ? null : player.getLibrary().getFromTop(game).getId();
diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/AmassEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/AmassEffect.java
index f443ca65bc..fab9b36f96 100644
--- a/Mage/src/main/java/mage/abilities/effects/keyword/AmassEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/keyword/AmassEffect.java
@@ -67,7 +67,7 @@ public class AmassEffect extends OneShotEffect {
if (player == null) {
return false;
}
- if (!game.getBattlefield().contains(filter, source.getControllerId(), 1, game)) {
+ if (!game.getBattlefield().containsControlled(filter, source, game, 1)) {
new CreateTokenEffect(new ZombieArmyToken()).apply(game, source);
}
Target target = new TargetPermanent(filter);
diff --git a/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java b/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java
index 7af6c49a48..b5728d69b6 100644
--- a/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java
@@ -104,7 +104,7 @@ public class ConvokeAbility extends SimpleStaticAbility implements AlternateMana
@Override
public void addSpecialAction(Ability source, Game game, ManaCost unpaid) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null && game.getBattlefield().contains(filterUntapped, controller.getId(), 1, game)) {
+ if (controller != null && game.getBattlefield().containsControlled(filterUntapped, source, game, 1)) {
if (source.getAbilityType() == AbilityType.SPELL) {
SpecialAction specialAction = new ConvokeSpecialAction(unpaid, this);
specialAction.setControllerId(source.getControllerId());
diff --git a/Mage/src/main/java/mage/abilities/keyword/LandwalkAbility.java b/Mage/src/main/java/mage/abilities/keyword/LandwalkAbility.java
index dc4c59aee1..fad955ee02 100644
--- a/Mage/src/main/java/mage/abilities/keyword/LandwalkAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/LandwalkAbility.java
@@ -14,6 +14,12 @@ import mage.game.permanent.Permanent;
*/
public class LandwalkAbility extends EvasionAbility {
+ /**
+ * Don't use source related filters here (example: landwalk for user selected land type).
+ * If you want it then use workaround from Traveler's Cloak to transfer settings after gain
+ *
+ * @param filter
+ */
public LandwalkAbility(FilterLandPermanent filter) {
this(filter, true);
}
@@ -39,7 +45,6 @@ public class LandwalkAbility extends EvasionAbility {
}
return ruleText;
}
-
}
class LandwalkEffect extends RestrictionEffect {
@@ -59,7 +64,7 @@ class LandwalkEffect extends RestrictionEffect {
@Override
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) {
- if (game.getBattlefield().contains(filter, blocker.getControllerId(), 1, game)
+ if (game.getBattlefield().contains(filter, source.getSourceId(), blocker.getControllerId(), game, 1)
&& null == game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_LANDWALK, source, blocker.getControllerId(), game)) {
switch (filter.getMessage()) {
case "plains":
@@ -74,7 +79,6 @@ class LandwalkEffect extends RestrictionEffect {
return null != game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_FORESTWALK, source, blocker.getControllerId(), game);
default:
return false;
-
}
}
return true;
diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenSubtypePredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenSubtypePredicate.java
index bbde6c6b86..ab0deb49f2 100644
--- a/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenSubtypePredicate.java
+++ b/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenSubtypePredicate.java
@@ -1,4 +1,3 @@
-
package mage.filter.predicate.mageobject;
import mage.MageObject;
@@ -9,6 +8,9 @@ import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
/**
+ * Warning, chosen type assign to original source ability, but after gain you will see another sourceId,
+ * see Traveler's Cloak for workaround to trasfer settings
+ *
* @author LoneFox
*/
public enum ChosenSubtypePredicate implements ObjectSourcePlayerPredicate> {
diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java
index 122b55f330..d187a5ff4d 100644
--- a/Mage/src/main/java/mage/game/GameImpl.java
+++ b/Mage/src/main/java/mage/game/GameImpl.java
@@ -2276,7 +2276,7 @@ public abstract class GameImpl implements Game, Serializable {
filterLegendName.add(SuperType.LEGENDARY.getPredicate());
filterLegendName.add(new NamePredicate(legend.getName()));
filterLegendName.add(new ControllerIdPredicate(legend.getControllerId()));
- if (getBattlefield().contains(filterLegendName, legend.getControllerId(), this, 2)) {
+ if (getBattlefield().contains(filterLegendName, null, legend.getControllerId(), this, 2)) {
if (!replaceEvent(GameEvent.getEvent(GameEvent.EventType.DESTROY_PERMANENT_BY_LEGENDARY_RULE, legend.getId(), legend.getControllerId()))) {
Player controller = this.getPlayer(legend.getControllerId());
if (controller != null) {
diff --git a/Mage/src/main/java/mage/game/command/emblems/GideonOfTheTrialsEmblem.java b/Mage/src/main/java/mage/game/command/emblems/GideonOfTheTrialsEmblem.java
index 700ba7591e..d426531082 100644
--- a/Mage/src/main/java/mage/game/command/emblems/GideonOfTheTrialsEmblem.java
+++ b/Mage/src/main/java/mage/game/command/emblems/GideonOfTheTrialsEmblem.java
@@ -50,7 +50,7 @@ class GideonOfTheTrialsCantLoseEffect extends ContinuousRuleModifyingEffectImpl
public boolean applies(GameEvent event, Ability source, Game game) {
if ((event.getType() == GameEvent.EventType.WINS && game.getOpponents(source.getControllerId()).contains(event.getPlayerId()))
|| (event.getType() == GameEvent.EventType.LOSES && event.getPlayerId().equals(source.getControllerId()))) {
- return game.getBattlefield().contains(filter, source.getControllerId(), 1, game);
+ return game.getBattlefield().containsControlled(filter, source, game, 1);
}
return false;
}
diff --git a/Mage/src/main/java/mage/game/permanent/Battlefield.java b/Mage/src/main/java/mage/game/permanent/Battlefield.java
index 054dfcbd4f..24c53796f4 100644
--- a/Mage/src/main/java/mage/game/permanent/Battlefield.java
+++ b/Mage/src/main/java/mage/game/permanent/Battlefield.java
@@ -1,5 +1,6 @@
package mage.game.permanent;
+import mage.abilities.Ability;
import mage.abilities.keyword.PhasingAbility;
import mage.constants.CardType;
import mage.constants.RangeOfInfluence;
@@ -92,21 +93,8 @@ public class Battlefield implements Serializable {
}
}
- /**
- * Returns true if the battlefield contains at least 1 {@link Permanent}
- * that matches the filter. This method ignores the range of influence.
- *
- * @param filter
- * @param num
- * @param game
- * @return boolean
- */
- public boolean contains(FilterPermanent filter, int num, Game game) {
- return field.values()
- .stream()
- .filter(permanent -> filter.match(permanent, game)
- && permanent.isPhasedIn()).count() >= num;
-
+ public boolean containsControlled(FilterPermanent filter, Ability source, Game game, int num) {
+ return containsControlled(filter, source.getSourceId(), source.getControllerId(), game, num);
}
/**
@@ -115,43 +103,49 @@ public class Battlefield implements Serializable {
* ignores the range of influence.
*
* @param filter
- * @param controllerId
+ * @param sourceId
+ * @param controllerId controller and source can be different (from different players)
* @param num
* @param game
* @return boolean
*/
- public boolean contains(FilterPermanent filter, UUID controllerId, int num, Game game) {
+ public boolean containsControlled(FilterPermanent filter, UUID sourceId, UUID controllerId, Game game, int num) {
return field.values()
.stream()
.filter(permanent -> permanent.isControlledBy(controllerId)
- && filter.match(permanent, game)
+ && filter.match(permanent, sourceId, controllerId, game)
&& permanent.isPhasedIn())
.count() >= num;
}
+ public boolean contains(FilterPermanent filter, Ability source, Game game, int num) {
+ return contains(filter, source.getSourceId(), source.getControllerId(), game, num);
+ }
+
/**
* Returns true if the battlefield contains num or more {@link Permanent}
* that is within the range of influence of the specified player id and that
* matches the supplied filter.
*
* @param filter
+ * @param sourceId can be null for default SBA checks like legendary rule
* @param sourcePlayerId
* @param game
* @param num
* @return boolean
*/
- public boolean contains(FilterPermanent filter, UUID sourcePlayerId, Game game, int num) {
+ public boolean contains(FilterPermanent filter, UUID sourceId, UUID sourcePlayerId, Game game, int num) {
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
return field.values().stream()
- .filter(permanent -> filter.match(permanent, null, sourcePlayerId, game)
+ .filter(permanent -> filter.match(permanent, sourceId, sourcePlayerId, game)
&& permanent.isPhasedIn()).count() >= num;
} else {
List range = game.getState().getPlayersInRange(sourcePlayerId, game);
return field.values().stream()
.filter(permanent -> range.contains(permanent.getControllerId())
- && filter.match(permanent, null, sourcePlayerId, game)
+ && filter.match(permanent, sourceId, sourcePlayerId, game)
&& permanent.isPhasedIn())
.count() >= num;
}