* Fixed a bug that the AI did for target selection not check correctly players with hexproof ability.

This commit is contained in:
LevelX2 2015-05-02 09:47:38 +02:00
parent 503dad24b3
commit 8686f4f777
10 changed files with 48 additions and 29 deletions

View file

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

View file

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

View file

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

View file

@ -261,7 +261,7 @@ public interface Player extends MageItem, Copyable<Player> {
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<UUID> appliedEffects);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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