diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index ea73a9d567d..8f4bda9b1a5 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -432,24 +432,24 @@ public class ComputerPlayer extends PlayerImpl implements Player { UUID opponentId = game.getOpponents(playerId).iterator().next(); if (target instanceof TargetPlayer) { if (outcome.isGood()) { - if (target.canTarget(playerId, source, game)) { + if (target.canTarget(playerId, playerId, source, game)) { target.addTarget(playerId, source, game); return true; } if (target.isRequired(source)) { - if (target.canTarget(opponentId, source, game)) { + if (target.canTarget(playerId, opponentId, source, game)) { target.addTarget(opponentId, source, game); return true; } } } else { - if (target.canTarget(opponentId, source, game)) { + if (target.canTarget(playerId, opponentId, source, game)) { target.addTarget(opponentId, source, game); return true; } if (target.isRequired(source)) { - if (target.canTarget(playerId, source, game)) { + if (target.canTarget(playerId, playerId, source, game)) { target.addTarget(playerId, source, game); return true; } diff --git a/Mage.Sets/src/mage/sets/magic2013/SublimeArchangel.java b/Mage.Sets/src/mage/sets/magic2013/SublimeArchangel.java index 5411cc7e1e3..bb7e890e6a6 100644 --- a/Mage.Sets/src/mage/sets/magic2013/SublimeArchangel.java +++ b/Mage.Sets/src/mage/sets/magic2013/SublimeArchangel.java @@ -51,7 +51,6 @@ public class SublimeArchangel extends CardImpl { this.expansionSetCode = "M13"; this.subtype.add("Angel"); - this.color.setWhite(true); this.power = new MageInt(4); this.toughness = new MageInt(3); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/rules/DontUntapTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/rules/DontUntapTest.java index 78fe3765978..37fd54aa11e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/rules/DontUntapTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/rules/DontUntapTest.java @@ -74,4 +74,30 @@ public class DontUntapTest extends CardTestPlayerBase { assertLife(playerB, 20); } + + /** + * I used Ajani Vengeant's +1 on a Sublime Archangel and it untap on it's controller's upkeep. + */ + @Test + public void TestAjaniVengeantFirst() { + + addCard(Zone.BATTLEFIELD, playerA, "Sublime Archangel", 1); // 4/3 + + // +1: Target permanent doesn't untap during its controller's next untap step. + addCard(Zone.BATTLEFIELD, playerB, "Ajani Vengeant", 1); + + attack(1, playerA, "Sublime Archangel"); + + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "+1: Target permanent doesn't","Sublime Archangel"); + + setStopAt(3, PhaseStep.DRAW); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 15); // 4 + 1 from Exalted + + assertTapped("Sublime Archangel", true); + + } + } \ No newline at end of file diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index f9cbb0666c7..f514bee9956 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -261,7 +261,7 @@ public interface Player extends MageItem, Copyable { boolean playLand(Card card, Game game); boolean activateAbility(ActivatedAbility ability, Game game); boolean triggerAbility(TriggeredAbility ability, Game game); - boolean canBeTargetedBy(MageObject source, Game game); + boolean canBeTargetedBy(MageObject source, UUID sourceControllerId, Game game); boolean hasProtectionFrom(MageObject source, Game game); boolean flipCoin(Game game); boolean flipCoin(Game game, ArrayList appliedEffects); diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 9307ff0d293..0832a81f224 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -583,7 +583,7 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean canBeTargetedBy(MageObject source, Game game) { + public boolean canBeTargetedBy(MageObject source, UUID sourceControllerId, Game game) { if (this.hasLost() || this.hasLeft()) { return false; } @@ -592,13 +592,7 @@ public abstract class PlayerImpl implements Player, Serializable { return false; } if (abilities.containsKey(HexproofAbility.getInstance().getId())) { - UUID controllerId = null; - if (source instanceof Permanent) { - controllerId = ((Permanent) source).getControllerId(); - } else if (source instanceof StackObject) { - controllerId = ((StackObject) source).getControllerId(); - } - if (controllerId != null && this.hasOpponent(controllerId, game) + if (sourceControllerId != null && this.hasOpponent(sourceControllerId, game) && !game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, this.getId(), game)) { return false; } diff --git a/Mage/src/mage/target/TargetPlayer.java b/Mage/src/mage/target/TargetPlayer.java index a190d517ec7..1cd83f26d4f 100644 --- a/Mage/src/mage/target/TargetPlayer.java +++ b/Mage/src/mage/target/TargetPlayer.java @@ -92,7 +92,7 @@ public class TargetPlayer extends TargetImpl { for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); if (player != null && !player.hasLeft() && filter.match(player, sourceId, sourceControllerId, game)) { - if (player.canBeTargetedBy(targetSource, game)) { + if (player.canBeTargetedBy(targetSource, sourceControllerId, game)) { count++; if (count >= this.minNumberOfTargets) { return true; @@ -133,7 +133,7 @@ public class TargetPlayer extends TargetImpl { for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); if (player != null && !player.hasLeft() && filter.match(player, sourceId, sourceControllerId, game)) { - if (isNotTarget() || player.canBeTargetedBy(targetSource, game)) { + if (isNotTarget() || player.canBeTargetedBy(targetSource, sourceControllerId, game)) { possibleTargets.add(playerId); } } @@ -178,7 +178,7 @@ public class TargetPlayer extends TargetImpl { Player player = game.getPlayer(id); if (player != null) { if (source != null) { - return (isNotTarget() || player.canBeTargetedBy(game.getObject(source.getSourceId()), game)) + return (isNotTarget() || player.canBeTargetedBy(game.getObject(source.getSourceId()), source.getControllerId(), game)) && filter.match(player, source.getSourceId(), source.getControllerId(), game); } else { return filter.match(player, game); diff --git a/Mage/src/mage/target/common/TargetCreatureOrPlayer.java b/Mage/src/mage/target/common/TargetCreatureOrPlayer.java index 2f5283ed297..9c18a671d1a 100644 --- a/Mage/src/mage/target/common/TargetCreatureOrPlayer.java +++ b/Mage/src/mage/target/common/TargetCreatureOrPlayer.java @@ -106,7 +106,7 @@ public class TargetCreatureOrPlayer extends TargetImpl { return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game); } if (player != null) { - return player.canBeTargetedBy(targetSource, game) && filter.match(player, game); + return player.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(player, game); } } @@ -134,7 +134,7 @@ public class TargetCreatureOrPlayer extends TargetImpl { MageObject targetSource = game.getObject(sourceId); for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); - if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { + if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) { count++; if (count >= this.minNumberOfTargets) { return true; @@ -189,7 +189,7 @@ public class TargetCreatureOrPlayer extends TargetImpl { MageObject targetSource = game.getObject(sourceId); for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); - if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { + if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) { possibleTargets.add(playerId); } } diff --git a/Mage/src/mage/target/common/TargetCreatureOrPlayerAmount.java b/Mage/src/mage/target/common/TargetCreatureOrPlayerAmount.java index 8287b257981..9709f99edf5 100644 --- a/Mage/src/mage/target/common/TargetCreatureOrPlayerAmount.java +++ b/Mage/src/mage/target/common/TargetCreatureOrPlayerAmount.java @@ -102,7 +102,7 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount { return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game); } if (player != null) { - return player.canBeTargetedBy(targetSource, game) && filter.match(player, game); + return player.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(player, game); } } @@ -126,7 +126,7 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount { MageObject targetSource = game.getObject(sourceId); for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); - if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { + if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) { count++; if (count >= this.minNumberOfTargets) { return true; @@ -173,7 +173,7 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount { MageObject targetSource = game.getObject(sourceId); for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); - if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { + if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) { possibleTargets.add(playerId); } } diff --git a/Mage/src/mage/target/common/TargetDefender.java b/Mage/src/mage/target/common/TargetDefender.java index a4ab49eec12..1fe5435d37d 100644 --- a/Mage/src/mage/target/common/TargetDefender.java +++ b/Mage/src/mage/target/common/TargetDefender.java @@ -87,7 +87,7 @@ public class TargetDefender extends TargetImpl { for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); // removed canBeTargeted because it's not correct to check it for attacking target - if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { + if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) { count++; if (count >= this.minNumberOfTargets) { return true; @@ -135,7 +135,7 @@ public class TargetDefender extends TargetImpl { MageObject targetSource = game.getObject(sourceId); for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); - if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { + if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) { possibleTargets.add(playerId); } } @@ -198,7 +198,7 @@ public class TargetDefender extends TargetImpl { Player player = game.getPlayer(id); MageObject targetSource = game.getObject(attackerId); if (player != null) { - return notTarget || (player.canBeTargetedBy(targetSource, game) && filter.match(player, game)); + return notTarget || (player.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(player, game)); } Permanent permanent = game.getPermanent(id); if (permanent != null) { diff --git a/Mage/src/mage/target/common/TargetPermanentOrPlayer.java b/Mage/src/mage/target/common/TargetPermanentOrPlayer.java index 66ddcb7a68b..8047006ebff 100644 --- a/Mage/src/mage/target/common/TargetPermanentOrPlayer.java +++ b/Mage/src/mage/target/common/TargetPermanentOrPlayer.java @@ -126,7 +126,7 @@ public class TargetPermanentOrPlayer extends TargetImpl { } if (player != null) { if (!isNotTarget()) { - if (!player.canBeTargetedBy(targetSource, game)) { + if (!player.canBeTargetedBy(targetSource, source.getControllerId(), game)) { return false; } } @@ -158,7 +158,7 @@ public class TargetPermanentOrPlayer extends TargetImpl { MageObject targetSource = game.getObject(sourceId); for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); - if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { + if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) { count++; if (count >= this.minNumberOfTargets) { return true; @@ -213,7 +213,7 @@ public class TargetPermanentOrPlayer extends TargetImpl { MageObject targetSource = game.getObject(sourceId); for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) { Player player = game.getPlayer(playerId); - if (player != null && (notTarget || player.canBeTargetedBy(targetSource, game)) && filter.match(player, game)) { + if (player != null && (notTarget || player.canBeTargetedBy(targetSource, sourceControllerId, game)) && filter.match(player, game)) { possibleTargets.add(playerId); } }