mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
* AI: fixed rollback errors with copy spell abilities;
Tests: added copy spell support for test player;
This commit is contained in:
parent
c0df1d6e8a
commit
fac7ea1388
3 changed files with 137 additions and 73 deletions
|
|
@ -146,6 +146,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
abilityControllerId = target.getAbilityController();
|
||||
}
|
||||
|
||||
boolean required = target.isRequired(sourceId, game);
|
||||
Set<UUID> possibleTargets = target.possibleTargets(sourceId, abilityControllerId, game);
|
||||
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
UUID randomOpponentId;
|
||||
if (target.getTargetController() != null) {
|
||||
randomOpponentId = getRandomOpponent(target.getTargetController(), game);
|
||||
|
|
@ -156,7 +162,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
||||
return setTargetPlayer(outcome, target, null, sourceId, abilityControllerId, randomOpponentId, game);
|
||||
return setTargetPlayer(outcome, target, null, sourceId, abilityControllerId, randomOpponentId, game, required);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetDiscard) {
|
||||
|
|
@ -287,7 +293,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
target.add(randomOpponentId, game);
|
||||
return true;
|
||||
}
|
||||
if (!target.isRequired(sourceId, game)) {
|
||||
if (!required) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -318,7 +324,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
target.add(randomOpponentId, game);
|
||||
return true;
|
||||
}
|
||||
if (!target.isRequired(sourceId, game)) {
|
||||
if (!required) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -405,7 +411,8 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
if (target.getOriginalTarget() instanceof TargetCardInYourGraveyard
|
||||
|| target.getOriginalTarget() instanceof TargetCardInASingleGraveyard) {
|
||||
List<UUID> alreadyTargeted = target.getTargets();
|
||||
List<Card> cards = new ArrayList<>(game.getPlayer(abilityControllerId).getGraveyard().getCards((FilterCard) target.getFilter(), game));
|
||||
TargetCard originalTarget = (TargetCard) target.getOriginalTarget();
|
||||
List<Card> cards = new ArrayList<>(game.getPlayer(abilityControllerId).getGraveyard().getCards(originalTarget.getFilter(), game));
|
||||
while (!cards.isEmpty()) {
|
||||
Card card = pickTarget(abilityControllerId, cards, outcome, target, null, game);
|
||||
if (card != null && alreadyTargeted != null && !alreadyTargeted.contains(card.getId())) {
|
||||
|
|
@ -433,7 +440,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!target.isRequired(sourceId, game)) {
|
||||
if (!required) {
|
||||
return false;
|
||||
}
|
||||
throw new IllegalStateException("TargetSource wasn't handled. class: " + target.getClass().toString());
|
||||
|
|
@ -448,6 +455,10 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
log.debug("chooseTarget: " + outcome.toString() + ':' + target.toString());
|
||||
}
|
||||
|
||||
// target - real target, make all changes and add targets to it
|
||||
// target.getOriginalTarget() - copy spell effect replaces original target with TargetWithAdditionalFilter
|
||||
// use originalTarget to get filters and target class info
|
||||
|
||||
// source can be null (as example: legendary rule permanent selection)
|
||||
UUID sourceId = source != null ? source.getSourceId() : null;
|
||||
|
||||
|
|
@ -482,7 +493,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
||||
return setTargetPlayer(outcome, target, source, sourceId, abilityControllerId, randomOpponentId, game);
|
||||
return setTargetPlayer(outcome, target, source, sourceId, abilityControllerId, randomOpponentId, game, required);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetDiscard
|
||||
|
|
@ -555,15 +566,8 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
// TODO: add findBest*Targets for all target types
|
||||
if (target.getOriginalTarget() instanceof TargetPermanent) {
|
||||
TargetPermanent origTarget = (TargetPermanent) target.getOriginalTarget();
|
||||
findBestPermanentTargets(outcome, abilityControllerId, sourceId, ((TargetPermanent) target).getFilter(),
|
||||
game, target, goodList, badList, allList);
|
||||
findBestPermanentTargets(outcome, abilityControllerId, sourceId, origTarget.getFilter(),
|
||||
game, target, goodList2, badList2, allList2);
|
||||
if (goodList.size() != goodList2.size() || badList.size() != badList2.size() || allList.size() != allList2.size()
|
||||
|| !origTarget.getFilter().equals(target.getFilter())) {
|
||||
// TODO: remove double check after servers testing
|
||||
log.error("Different filters in target and origTarget: " + target.getClass().getName() + " - " + origTarget.getClass().getName());
|
||||
}
|
||||
game, target, goodList, badList, allList);
|
||||
|
||||
// use good list all the time and add maximum targets
|
||||
for (Permanent permanent : goodList) {
|
||||
|
|
@ -589,7 +593,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
if (target.getOriginalTarget() instanceof TargetCreatureOrPlayer) {
|
||||
List<Permanent> targets;
|
||||
TargetCreatureOrPlayer origTarget = ((TargetCreatureOrPlayer) target);
|
||||
TargetCreatureOrPlayer origTarget = ((TargetCreatureOrPlayer) target.getOriginalTarget());
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(abilityControllerId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
||||
} else {
|
||||
|
|
@ -626,13 +630,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
return tryAddTarget(target, randomOpponentId, source, game);
|
||||
}
|
||||
|
||||
//if (!target.isRequired())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetAnyTarget) {
|
||||
List<Permanent> targets;
|
||||
TargetAnyTarget origTarget = ((TargetAnyTarget) target);
|
||||
TargetAnyTarget origTarget = ((TargetAnyTarget) target.getOriginalTarget());
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(abilityControllerId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
||||
} else {
|
||||
|
|
@ -649,7 +652,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
if (targets.isEmpty() && target.isRequired(source)) {
|
||||
if (targets.isEmpty() && required) {
|
||||
targets = game.getBattlefield().getActivePermanents(((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getCreatureFilter(), playerId, game);
|
||||
}
|
||||
for (Permanent permanent : targets) {
|
||||
|
|
@ -675,7 +678,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
|
||||
List<Permanent> targets;
|
||||
TargetPermanentOrPlayer origTarget = ((TargetPermanentOrPlayer) target);
|
||||
TargetPermanentOrPlayer origTarget = ((TargetPermanentOrPlayer) target.getOriginalTarget());
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
} else {
|
||||
|
|
@ -707,7 +710,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
if (target.getOriginalTarget() instanceof TargetPlayerOrPlaneswalker) {
|
||||
List<Permanent> targets;
|
||||
TargetPlayerOrPlaneswalker origTarget = ((TargetPlayerOrPlaneswalker) target);
|
||||
TargetPlayerOrPlaneswalker origTarget = ((TargetPlayerOrPlaneswalker) target.getOriginalTarget());
|
||||
|
||||
// TODO: if effect is bad and no opponent's targets available then AI can't target yourself but must by rules
|
||||
/*
|
||||
|
|
@ -739,7 +742,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
// can't find targets (e.g. effect is bad, but you need take targets from yourself)
|
||||
if (targets.isEmpty() && target.isRequired(source)) {
|
||||
if (targets.isEmpty() && required) {
|
||||
targets = game.getBattlefield().getActivePermanents(origTarget.getFilterPermanent(), playerId, game);
|
||||
}
|
||||
|
||||
|
|
@ -762,7 +765,6 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
return tryAddTarget(target, randomOpponentId, source, game);
|
||||
}
|
||||
|
||||
//if (!target.isRequired())
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -821,7 +823,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
} else {
|
||||
targets = threats(randomOpponentId, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
|
||||
}
|
||||
if (targets.isEmpty() && target.isRequired(source)) {
|
||||
if (targets.isEmpty() && required) {
|
||||
targets = threats(null, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
|
||||
Collections.reverse(targets);
|
||||
outcomeTargets = false;
|
||||
|
|
@ -1315,6 +1317,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: wtf?! change to player.getPlayable
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
|
||||
for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
|
||||
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(playerId, game).canActivate()) {
|
||||
|
|
@ -2654,7 +2657,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
/**
|
||||
* Sets a possible target player
|
||||
*/
|
||||
private boolean setTargetPlayer(Outcome outcome, Target target, Ability source, UUID sourceId, UUID abilityControllerId, UUID randomOpponentId, Game game) {
|
||||
private boolean setTargetPlayer(Outcome outcome, Target target, Ability source, UUID sourceId, UUID abilityControllerId, UUID randomOpponentId, Game game, boolean required) {
|
||||
if (target.getOriginalTarget() instanceof TargetOpponent) {
|
||||
if (source == null) {
|
||||
if (target.canTarget(randomOpponentId, game)) {
|
||||
|
|
@ -2721,7 +2724,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
target.add(randomOpponentId, game);
|
||||
return true;
|
||||
}
|
||||
if (target.isRequired(sourceId, game)) {
|
||||
if (required) {
|
||||
if (target.canTarget(abilityControllerId, game)) {
|
||||
target.add(abilityControllerId, game);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.cards.triggers;
|
||||
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
|
|
@ -8,7 +7,6 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ZadaHedronGrinderTest extends CardTestPlayerBase {
|
||||
|
|
@ -43,7 +41,70 @@ public class ZadaHedronGrinderTest extends CardTestPlayerBase {
|
|||
assertAbility(playerA, "Zada, Hedron Grinder", TrampleAbility.getInstance(), true);
|
||||
assertPowerToughness(playerA, "Silvercoat Lion", 4, 2);
|
||||
assertAbility(playerA, "Silvercoat Lion", TrampleAbility.getInstance(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetsByTestPlayer() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
|
||||
// Whenever you cast an instant or sorcery spell that targets only Zada, Hedron Grinder, copy that spell for
|
||||
// each other creature you control that the spell could target. Each copy targets a different one of those creatures.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Zada, Hedron Grinder", 1); // 3/3
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
|
||||
//
|
||||
// Put a +1/+1 counter on target creature. That creature gains reach until end of turn.
|
||||
addCard(Zone.HAND, playerA, "Arbor Armament", 1); // {G}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
// cast
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Arbor Armament", "Zada, Hedron Grinder");
|
||||
addTarget(playerA, "Balduvian Bears^Silvercoat Lion");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertGraveyardCount(playerA, "Arbor Armament", 1);
|
||||
assertPowerToughness(playerA, "Zada, Hedron Grinder", 3 + 1, 3 + 1);
|
||||
assertPowerToughness(playerA, "Silvercoat Lion", 2 + 1, 2 + 1);
|
||||
assertPowerToughness(playerA, "Balduvian Bears", 2 + 1, 2 + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetsByAI() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
|
||||
// Whenever you cast an instant or sorcery spell that targets only Zada, Hedron Grinder, copy that spell for
|
||||
// each other creature you control that the spell could target. Each copy targets a different one of those creatures.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Zada, Hedron Grinder", 1); // 3/3
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
|
||||
//
|
||||
// Put a +1/+1 counter on target creature. That creature gains reach until end of turn.
|
||||
addCard(Zone.HAND, playerA, "Arbor Armament", 1); // {G}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
|
||||
// cast
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Arbor Armament", "Zada, Hedron Grinder");
|
||||
//addTarget(playerA, "Balduvian Bears^Silvercoat Lion");
|
||||
|
||||
//setStrictChooseMode(true); // no strict mode for AI
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertGraveyardCount(playerA, "Arbor Armament", 1);
|
||||
assertPowerToughness(playerA, "Zada, Hedron Grinder", 3 + 1, 3 + 1);
|
||||
assertPowerToughness(playerA, "Silvercoat Lion", 2 + 1, 2 + 1);
|
||||
assertPowerToughness(playerA, "Balduvian Bears", 2 + 1, 2 + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -453,9 +453,9 @@ public class TestPlayer implements Player {
|
|||
if (currentTarget.getNumberOfTargets() == 1) {
|
||||
currentTarget.clearChosen();
|
||||
}
|
||||
if (currentTarget instanceof TargetCreaturePermanentAmount) {
|
||||
if (currentTarget.getOriginalTarget() instanceof TargetCreaturePermanentAmount) {
|
||||
// supports only to set the complete amount to one target
|
||||
TargetCreaturePermanentAmount targetAmount = (TargetCreaturePermanentAmount) currentTarget;
|
||||
TargetCreaturePermanentAmount targetAmount = (TargetCreaturePermanentAmount) currentTarget.getOriginalTarget();
|
||||
targetAmount.setAmount(ability, game);
|
||||
int amount = targetAmount.getAmountRemaining();
|
||||
targetAmount.addTarget(id, amount, ability, game);
|
||||
|
|
@ -1540,12 +1540,13 @@ public class TestPlayer implements Player {
|
|||
source = stackObject.getStackAbility();
|
||||
}
|
||||
|
||||
if ((target instanceof TargetPermanent) || (target instanceof TargetPermanentOrPlayer)) { // player target not implemted yet
|
||||
if ((target.getOriginalTarget() instanceof TargetPermanent)
|
||||
|| (target.getOriginalTarget() instanceof TargetPermanentOrPlayer)) { // player target not implemted yet
|
||||
FilterPermanent filterPermanent;
|
||||
if (target instanceof TargetPermanentOrPlayer) {
|
||||
filterPermanent = ((TargetPermanentOrPlayer) target).getFilterPermanent();
|
||||
if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
|
||||
filterPermanent = ((TargetPermanentOrPlayer) target.getOriginalTarget()).getFilterPermanent();
|
||||
} else {
|
||||
filterPermanent = ((TargetPermanent) target).getFilter();
|
||||
filterPermanent = ((TargetPermanent) target.getOriginalTarget()).getFilter();
|
||||
}
|
||||
for (String choose2 : choices) {
|
||||
String[] targetList = choose2.split("\\^");
|
||||
|
|
@ -1608,7 +1609,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
// TODO: add same choices fixes for other target types (one choice must uses only one time for one target)
|
||||
if (target instanceof TargetCard) {
|
||||
if (target.getOriginalTarget() instanceof TargetCard) {
|
||||
// one choice per target
|
||||
// only unique targets
|
||||
//TargetCard targetFull = ((TargetCard) target);
|
||||
|
|
@ -1674,9 +1675,9 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
if (target instanceof TargetSource) {
|
||||
if (target.getOriginalTarget() instanceof TargetSource) {
|
||||
Set<UUID> possibleTargets;
|
||||
TargetSource t = ((TargetSource) target);
|
||||
TargetSource t = ((TargetSource) target.getOriginalTarget());
|
||||
possibleTargets = t.possibleTargets(sourceId, abilityControllerId, game);
|
||||
for (String choose2 : choices) {
|
||||
String[] targetList = choose2.split("\\^");
|
||||
|
|
@ -1760,11 +1761,11 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
// player
|
||||
if (target instanceof TargetPlayer
|
||||
|| target instanceof TargetAnyTarget
|
||||
|| target instanceof TargetCreatureOrPlayer
|
||||
|| target instanceof TargetPermanentOrPlayer
|
||||
|| target instanceof TargetDefender) {
|
||||
if (target.getOriginalTarget() instanceof TargetPlayer
|
||||
|| target.getOriginalTarget() instanceof TargetAnyTarget
|
||||
|| target.getOriginalTarget() instanceof TargetCreatureOrPlayer
|
||||
|| target.getOriginalTarget() instanceof TargetPermanentOrPlayer
|
||||
|| target.getOriginalTarget() instanceof TargetDefender) {
|
||||
for (String targetDefinition : targets) {
|
||||
checkTargetDefinitionMarksSupport(target, targetDefinition, "=");
|
||||
if (targetDefinition.startsWith("targetPlayer=")) {
|
||||
|
|
@ -1779,15 +1780,14 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// permanent in battlefield
|
||||
if ((target instanceof TargetPermanent)
|
||||
|| (target instanceof TargetPermanentOrPlayer)
|
||||
|| (target instanceof TargetAnyTarget)
|
||||
|| (target instanceof TargetCreatureOrPlayer)
|
||||
|| (target instanceof TargetDefender)) {
|
||||
if ((target.getOriginalTarget() instanceof TargetPermanent)
|
||||
|| (target.getOriginalTarget() instanceof TargetPermanentOrPlayer)
|
||||
|| (target.getOriginalTarget() instanceof TargetAnyTarget)
|
||||
|| (target.getOriginalTarget() instanceof TargetCreatureOrPlayer)
|
||||
|| (target.getOriginalTarget() instanceof TargetDefender)) {
|
||||
for (String targetDefinition : targets) {
|
||||
checkTargetDefinitionMarksSupport(target, targetDefinition, "^[]");
|
||||
String[] targetList = targetDefinition.split("\\^");
|
||||
|
|
@ -1805,7 +1805,7 @@ public class TestPlayer implements Player {
|
|||
targetName = targetName.substring(0, targetName.length() - 11);
|
||||
}
|
||||
}
|
||||
Filter filter = target.getFilter();
|
||||
Filter filter = target.getOriginalTarget().getFilter();
|
||||
if (filter instanceof FilterCreatureOrPlayer) {
|
||||
filter = ((FilterCreatureOrPlayer) filter).getCreatureFilter();
|
||||
}
|
||||
|
|
@ -1824,12 +1824,11 @@ public class TestPlayer implements Player {
|
|||
if ((permanent.isCopy() && !originOnly) || (!permanent.isCopy() && !copyOnly)) {
|
||||
target.add(permanent.getId(), game);
|
||||
targetFound = true;
|
||||
break;
|
||||
break; // return to for (String targetName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (targetFound) {
|
||||
targets.remove(targetDefinition);
|
||||
|
|
@ -1839,18 +1838,18 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
// card in hand
|
||||
if (target instanceof TargetCardInHand) {
|
||||
if (target.getOriginalTarget() instanceof TargetCardInHand) {
|
||||
for (String targetDefinition : targets) {
|
||||
checkTargetDefinitionMarksSupport(target, targetDefinition, "^");
|
||||
String[] targetList = targetDefinition.split("\\^");
|
||||
boolean targetFound = false;
|
||||
for (String targetName : targetList) {
|
||||
for (Card card : computerPlayer.getHand().getCards(((TargetCardInHand) target).getFilter(), game)) {
|
||||
for (Card card : computerPlayer.getHand().getCards(((TargetCardInHand) target.getOriginalTarget()).getFilter(), game)) {
|
||||
if (card.getName().equals(targetName) || (card.getName() + '-' + card.getExpansionSetCode()).equals(targetName)) {
|
||||
if (target.canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) {
|
||||
target.add(card.getId(), game);
|
||||
targetFound = true;
|
||||
break;
|
||||
break; // return to for (String targetName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1863,8 +1862,8 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
// card in exile
|
||||
if (target instanceof TargetCardInExile) {
|
||||
TargetCardInExile targetFull = (TargetCardInExile) target;
|
||||
if (target.getOriginalTarget() instanceof TargetCardInExile) {
|
||||
TargetCardInExile targetFull = (TargetCardInExile) target.getOriginalTarget();
|
||||
for (String targetDefinition : targets) {
|
||||
checkTargetDefinitionMarksSupport(target, targetDefinition, "^");
|
||||
String[] targetList = targetDefinition.split("\\^");
|
||||
|
|
@ -1872,10 +1871,10 @@ public class TestPlayer implements Player {
|
|||
for (String targetName : targetList) {
|
||||
for (Card card : game.getExile().getCards(targetFull.getFilter(), game)) {
|
||||
if (card.getName().equals(targetName) || (card.getName() + '-' + card.getExpansionSetCode()).equals(targetName)) {
|
||||
if (targetFull.canTarget(abilityControllerId, card.getId(), source, game) && !targetFull.getTargets().contains(card.getId())) {
|
||||
targetFull.add(card.getId(), game);
|
||||
if (target.canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) {
|
||||
target.add(card.getId(), game);
|
||||
targetFound = true;
|
||||
break;
|
||||
break; // return to for (String targetName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1900,7 +1899,7 @@ public class TestPlayer implements Player {
|
|||
if (targetFull.canTarget(abilityControllerId, card.getId(), source, game) && !targetFull.getTargets().contains(card.getId())) {
|
||||
targetFull.add(card.getId(), game);
|
||||
targetFound = true;
|
||||
break;
|
||||
break; // return to for (String targetName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1914,22 +1913,22 @@ public class TestPlayer implements Player {
|
|||
|
||||
|
||||
// card in graveyard
|
||||
if (target instanceof TargetCardInOpponentsGraveyard
|
||||
|| target instanceof TargetCardInYourGraveyard
|
||||
|| target instanceof TargetCardInGraveyard
|
||||
|| target instanceof TargetCardInGraveyardOrBattlefield) {
|
||||
TargetCard targetFull = (TargetCard) target;
|
||||
if (target.getOriginalTarget() instanceof TargetCardInOpponentsGraveyard
|
||||
|| target.getOriginalTarget() instanceof TargetCardInYourGraveyard
|
||||
|| target.getOriginalTarget() instanceof TargetCardInGraveyard
|
||||
|| target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) {
|
||||
TargetCard targetFull = (TargetCard) target.getOriginalTarget();
|
||||
|
||||
List<UUID> needPlayers = game.getState().getPlayersInRange(getId(), game).toList();
|
||||
// fix for opponent graveyard
|
||||
if (target instanceof TargetCardInOpponentsGraveyard) {
|
||||
if (target.getOriginalTarget() instanceof TargetCardInOpponentsGraveyard) {
|
||||
// current player remove
|
||||
Assert.assertTrue(needPlayers.contains(getId()));
|
||||
needPlayers.remove(getId());
|
||||
Assert.assertFalse(needPlayers.contains(getId()));
|
||||
}
|
||||
// fix for your graveyard
|
||||
if (target instanceof TargetCardInYourGraveyard) {
|
||||
if (target.getOriginalTarget() instanceof TargetCardInYourGraveyard) {
|
||||
// only current player
|
||||
Assert.assertTrue(needPlayers.contains(getId()));
|
||||
needPlayers.clear();
|
||||
|
|
@ -1948,17 +1947,16 @@ public class TestPlayer implements Player {
|
|||
Player player = game.getPlayer(playerId);
|
||||
for (Card card : player.getGraveyard().getCards(targetFull.getFilter(), game)) {
|
||||
if (card.getName().equals(targetName) || (card.getName() + '-' + card.getExpansionSetCode()).equals(targetName)) {
|
||||
if (targetFull.canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) {
|
||||
if (target.canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) {
|
||||
target.add(card.getId(), game);
|
||||
targetFound = true;
|
||||
break IterateGraveyards;
|
||||
break IterateGraveyards; // return to for (String targetName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (targetFound) {
|
||||
targets.remove(targetDefinition);
|
||||
return true;
|
||||
|
|
@ -1968,7 +1966,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
// stack
|
||||
if (target instanceof TargetSpell) {
|
||||
if (target.getOriginalTarget() instanceof TargetSpell) {
|
||||
for (String targetDefinition : targets) {
|
||||
checkTargetDefinitionMarksSupport(target, targetDefinition, "^");
|
||||
String[] targetList = targetDefinition.split("\\^");
|
||||
|
|
@ -1976,9 +1974,11 @@ public class TestPlayer implements Player {
|
|||
for (String targetName : targetList) {
|
||||
for (StackObject stackObject : game.getStack()) {
|
||||
if (stackObject.getName().equals(targetName)) {
|
||||
target.add(stackObject.getId(), game);
|
||||
targetFound = true;
|
||||
break;
|
||||
if (target.canTarget(abilityControllerId, stackObject.getId(), source, game) && !target.getTargets().contains(stackObject.getId())) {
|
||||
target.add(stackObject.getId(), game);
|
||||
targetFound = true;
|
||||
break; // return to for (String targetName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue