mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
step 2 on hidden origins
This commit is contained in:
@@ -1101,65 +1101,18 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
* a {@link forge.game.player.Player} object.
|
* a {@link forge.game.player.Player} object.
|
||||||
* @param changeNum2
|
* @param changeNum2
|
||||||
* @param destination
|
* @param destination
|
||||||
|
* @param fetchList
|
||||||
* @param libraryPos2
|
* @param libraryPos2
|
||||||
* @param origin2
|
* @param origin2
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public static void hiddenOriginResolveAI(final Player ai, final SpellAbility sa, Player player, int changeNum, List<ZoneType> origin, ZoneType destination, int libraryPos2) {
|
public static List<Card> hiddenOriginResolveAI(final Player decider, final SpellAbility sa, Player player, int changeNum, List<ZoneType> origin, ZoneType destination, List<Card> fetchList, int libraryPos) {
|
||||||
|
|
||||||
final Card source = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
final boolean defined = sa.hasParam("Defined");
|
final boolean defined = sa.hasParam("Defined");
|
||||||
final Game game = ai.getGame();
|
final Game game = decider.getGame();
|
||||||
|
|
||||||
|
final List<Card> movedCards = new ArrayList<Card>();
|
||||||
String type = sa.getParam("ChangeType");
|
|
||||||
if (type == null) {
|
|
||||||
type = "Card";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
List<Card> fetchList;
|
|
||||||
boolean shuffleMandatory = true;
|
|
||||||
boolean searchedLibrary = false;
|
|
||||||
if (defined) {
|
|
||||||
fetchList = new ArrayList<Card>(AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa));
|
|
||||||
if (!sa.hasParam("ChangeNum")) {
|
|
||||||
changeNum = fetchList.size();
|
|
||||||
}
|
|
||||||
} else if (!origin.contains(ZoneType.Library) && !origin.contains(ZoneType.Hand)
|
|
||||||
&& !sa.hasParam("DefinedPlayer")) {
|
|
||||||
fetchList = game.getCardsIn(origin);
|
|
||||||
fetchList = AbilityUtils.filterListByType(fetchList, type, sa);
|
|
||||||
} else {
|
|
||||||
fetchList = player.getCardsIn(origin);
|
|
||||||
if (origin.contains(ZoneType.Library) && !sa.hasParam("NoLooking")) {
|
|
||||||
searchedLibrary = true;
|
|
||||||
if (ai.hasKeyword("LimitSearchLibrary")) {
|
|
||||||
// Aven Mindcensor
|
|
||||||
fetchList.removeAll(player.getCardsIn(ZoneType.Library));
|
|
||||||
final int fetchNum = Math.min(player.getCardsIn(ZoneType.Library).size(), 4);
|
|
||||||
fetchList.addAll(player.getCardsIn(ZoneType.Library, fetchNum));
|
|
||||||
if (fetchNum == 0) {
|
|
||||||
searchedLibrary = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ai.hasKeyword("CantSearchLibrary")) {
|
|
||||||
fetchList.removeAll(player.getCardsIn(ZoneType.Library));
|
|
||||||
// "if you do/sb does, shuffle" is not mandatory, should has this param.
|
|
||||||
// "then shuffle" is mandatory
|
|
||||||
shuffleMandatory = !sa.hasParam("ShuffleNonMandatory");
|
|
||||||
searchedLibrary = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fetchList = AbilityUtils.filterListByType(fetchList, type, sa);
|
|
||||||
}
|
|
||||||
if (searchedLibrary && ai.equals(player)) {
|
|
||||||
ai.incLibrarySearched();
|
|
||||||
}
|
|
||||||
if (sa.hasParam("NoShuffle")) {
|
|
||||||
shuffleMandatory = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Card> fetched = new ArrayList<Card>();
|
|
||||||
final boolean remember = sa.hasParam("RememberChanged");
|
final boolean remember = sa.hasParam("RememberChanged");
|
||||||
final boolean forget = sa.hasParam("ForgetChanged");
|
final boolean forget = sa.hasParam("ForgetChanged");
|
||||||
final boolean champion = sa.hasParam("Champion");
|
final boolean champion = sa.hasParam("Champion");
|
||||||
@@ -1167,19 +1120,15 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
final String totalcmc = sa.getParam("WithTotalCMC");
|
final String totalcmc = sa.getParam("WithTotalCMC");
|
||||||
int totcmc = AbilityUtils.calculateAmount(source, totalcmc, sa);
|
int totcmc = AbilityUtils.calculateAmount(source, totalcmc, sa);
|
||||||
|
|
||||||
if (sa.hasParam("Unimprint")) {
|
|
||||||
source.clearImprinted();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < changeNum; i++) {
|
for (int i = 0; i < changeNum; i++) {
|
||||||
if (sa.hasParam("DifferentNames")) {
|
if (sa.hasParam("DifferentNames")) {
|
||||||
for (Card c : fetched) {
|
for (Card c : movedCards) {
|
||||||
fetchList = CardLists.filter(fetchList, Predicates.not(CardPredicates.nameEquals(c.getName())));
|
fetchList = CardLists.filter(fetchList, Predicates.not(CardPredicates.nameEquals(c.getName())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (totalcmc != null) {
|
if (totalcmc != null) {
|
||||||
if (totcmc >= 0) {
|
if (totcmc >= 0) {
|
||||||
fetchList = CardLists.getValidCards(fetchList, "Card.cmcLE" + Integer.toString(totcmc), ai, source);
|
fetchList = CardLists.getValidCards(fetchList, "Card.cmcLE" + Integer.toString(totcmc), decider, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((fetchList.size() == 0) || (destination == null)) {
|
if ((fetchList.size() == 0) || (destination == null)) {
|
||||||
@@ -1193,129 +1142,30 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
} else if (defined) {
|
} else if (defined) {
|
||||||
c = fetchList.get(0);
|
c = fetchList.get(0);
|
||||||
} else {
|
} else {
|
||||||
final Player activator = sa.getActivatingPlayer();
|
c = chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player, decider);
|
||||||
|
|
||||||
CardLists.shuffle(fetchList);
|
|
||||||
// Save a card as a default, in case we can't find anything suitable.
|
|
||||||
Card first = fetchList.get(0);
|
|
||||||
if (ZoneType.Battlefield.equals(destination)) {
|
|
||||||
fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
if (c.isType("Legendary")) {
|
|
||||||
if (!ai.getCardsIn(ZoneType.Battlefield, c.getName()).isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (player.isOpponentOf(ai) && sa.hasParam("GainControl") && activator.equals(ai)) {
|
|
||||||
fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
if (c.hasSVar("RemAIDeck") || c.hasSVar("RemRandomDeck")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ZoneType.Exile.equals(destination) || origin.contains(ZoneType.Battlefield)
|
|
||||||
|| (ZoneType.Library.equals(destination) && origin.contains(ZoneType.Hand))) {
|
|
||||||
// Exiling or bouncing stuff
|
|
||||||
if (player.isOpponentOf(ai)) {
|
|
||||||
c = ComputerUtilCard.getBestAI(fetchList);
|
|
||||||
} else {
|
|
||||||
c = ComputerUtilCard.getWorstAI(fetchList);
|
|
||||||
}
|
|
||||||
} else if (origin.contains(ZoneType.Library)
|
|
||||||
&& (type.contains("Basic") || areAllBasics(type))) {
|
|
||||||
c = basicManaFixing(ai, fetchList);
|
|
||||||
} else if (ZoneType.Hand.equals(destination) && CardLists.getNotType(fetchList, "Creature").isEmpty()) {
|
|
||||||
c = chooseCreature(ai, fetchList);
|
|
||||||
} else if (ZoneType.Battlefield.equals(destination) || ZoneType.Graveyard.equals(destination)) {
|
|
||||||
if (!activator.equals(ai) && sa.hasParam("GainControl")) {
|
|
||||||
c = ComputerUtilCard.getWorstAI(fetchList);
|
|
||||||
} else {
|
|
||||||
c = ComputerUtilCard.getBestAI(fetchList);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Don't fetch another tutor with the same name
|
|
||||||
List<Card> sameNamed = CardLists.filter(fetchList, Predicates.not(CardPredicates.nameEquals(source.getName())));
|
|
||||||
if (origin.contains(ZoneType.Library) && !sameNamed.isEmpty()) {
|
|
||||||
fetchList = sameNamed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does AI need a land?
|
movedCards.add(c);
|
||||||
List<Card> hand = ai.getCardsIn(ZoneType.Hand);
|
|
||||||
if (CardLists.filter(hand, Presets.LANDS).isEmpty() && CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), Presets.LANDS).size() < 4) {
|
|
||||||
boolean canCastSomething = false;
|
|
||||||
for (Card cardInHand : hand) {
|
|
||||||
canCastSomething |= ComputerUtilMana.hasEnoughManaSourcesToCast(cardInHand.getFirstSpellAbility(), ai);
|
|
||||||
}
|
|
||||||
if (!canCastSomething) {
|
|
||||||
System.out.println("Pulling a land as there are none in hand, less than 4 on the board, and nothing in hand is castable.");
|
|
||||||
c = basicManaFixing(ai, fetchList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c == null) {
|
|
||||||
System.out.println("Don't need a land or none available; trying for a creature.");
|
|
||||||
fetchList = CardLists.getNotType(fetchList, "Land");
|
|
||||||
// Prefer to pull a creature, generally more useful for AI.
|
|
||||||
c = chooseCreature(ai, CardLists.filter(fetchList, CardPredicates.Presets.CREATURES));
|
|
||||||
}
|
|
||||||
if (c == null) { // Could not find a creature.
|
|
||||||
if (ai.getLife() <= 5) { // Desperate?
|
|
||||||
// Get something AI can cast soon.
|
|
||||||
System.out.println("5 Life or less, trying to find something castable.");
|
|
||||||
CardLists.sortByCmcDesc(fetchList);
|
|
||||||
for (Card potentialCard : fetchList) {
|
|
||||||
if (ComputerUtilMana.hasEnoughManaSourcesToCast(potentialCard.getFirstSpellAbility(), ai)) {
|
|
||||||
c = potentialCard;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Get the best card in there.
|
|
||||||
System.out.println("No creature and lots of life, finding something good.");
|
|
||||||
c = ComputerUtilCard.getBestAI(fetchList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c == null) {
|
|
||||||
c = first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fetched.add(c);
|
|
||||||
fetchList.remove(c);
|
fetchList.remove(c);
|
||||||
if (totalcmc != null) {
|
if (totalcmc != null) {
|
||||||
totcmc -= c.getCMC();
|
totcmc -= c.getCMC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (origin.contains(ZoneType.Library) && !defined && !"False".equals(sa.getParam("Shuffle")) && shuffleMandatory) {
|
for (final Card c : movedCards) {
|
||||||
player.shuffle(sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Card c : fetched) {
|
|
||||||
Card movedCard = null;
|
Card movedCard = null;
|
||||||
if (ZoneType.Library.equals(destination)) {
|
if (ZoneType.Library.equals(destination)) {
|
||||||
final int libraryPos = sa.hasParam("LibraryPosition") ? AbilityUtils.calculateAmount(source, sa.getParam("LibraryPosition"), sa) : 0;
|
|
||||||
movedCard = game.getAction().moveToLibrary(c, libraryPos);
|
movedCard = game.getAction().moveToLibrary(c, libraryPos);
|
||||||
} else if (ZoneType.Battlefield.equals(destination)) {
|
} else if (ZoneType.Battlefield.equals(destination)) {
|
||||||
if (sa.hasParam("Tapped")) {
|
if (sa.hasParam("Tapped")) {
|
||||||
c.setTapped(true);
|
c.setTapped(true);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("GainControl")) {
|
if (sa.hasParam("GainControl")) {
|
||||||
|
Player newController = sa.getActivatingPlayer();
|
||||||
if (sa.hasParam("NewController")) {
|
if (sa.hasParam("NewController")) {
|
||||||
final Player p = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DefinedPlayer"), sa).get(0);
|
newController = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa).get(0);
|
||||||
c.setController(p, game.getNextTimestamp());
|
|
||||||
} else {
|
|
||||||
c.setController(sa.getActivatingPlayer(), game.getNextTimestamp());
|
|
||||||
}
|
}
|
||||||
|
c.setController(newController, game.getNextTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("AttachedTo")) {
|
if (sa.hasParam("AttachedTo")) {
|
||||||
@@ -1400,18 +1250,113 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("True".equals(sa.getParam("Shuffle"))) {
|
return movedCards;
|
||||||
player.shuffle(sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((!ZoneType.Battlefield.equals(destination) && !"Card".equals(type) && !defined)
|
|
||||||
|| (sa.hasParam("Reveal") && !fetched.isEmpty()))
|
|
||||||
&& !sa.hasParam("NoReveal")) {
|
|
||||||
|
|
||||||
game.getAction().reveal(fetched, player);
|
|
||||||
}
|
|
||||||
} // end changeHiddenOriginResolveAI
|
} // end changeHiddenOriginResolveAI
|
||||||
|
|
||||||
|
private static Card chooseCardToHiddenOriginChangeZone(ZoneType destination, List<ZoneType> origin, SpellAbility sa, List<Card> fetchList, Player player, final Player decider) {
|
||||||
|
|
||||||
|
String type = sa.getParam("ChangeType");
|
||||||
|
if (type == null) {
|
||||||
|
type = "Card";
|
||||||
|
}
|
||||||
|
|
||||||
|
Card c = null;
|
||||||
|
final Player activator = sa.getActivatingPlayer();
|
||||||
|
|
||||||
|
CardLists.shuffle(fetchList);
|
||||||
|
// Save a card as a default, in case we can't find anything suitable.
|
||||||
|
Card first = fetchList.get(0);
|
||||||
|
if (ZoneType.Battlefield.equals(destination)) {
|
||||||
|
fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
if (c.isType("Legendary")) {
|
||||||
|
if (!decider.getCardsIn(ZoneType.Battlefield, c.getName()).isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (player.isOpponentOf(decider) && sa.hasParam("GainControl") && activator.equals(decider)) {
|
||||||
|
fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
if (c.hasSVar("RemAIDeck") || c.hasSVar("RemRandomDeck")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ZoneType.Exile.equals(destination) || origin.contains(ZoneType.Battlefield)
|
||||||
|
|| (ZoneType.Library.equals(destination) && origin.contains(ZoneType.Hand))) {
|
||||||
|
// Exiling or bouncing stuff
|
||||||
|
if (player.isOpponentOf(decider)) {
|
||||||
|
c = ComputerUtilCard.getBestAI(fetchList);
|
||||||
|
} else {
|
||||||
|
c = ComputerUtilCard.getWorstAI(fetchList);
|
||||||
|
}
|
||||||
|
} else if (origin.contains(ZoneType.Library) && (type.contains("Basic") || areAllBasics(type))) {
|
||||||
|
c = basicManaFixing(decider, fetchList);
|
||||||
|
} else if (ZoneType.Hand.equals(destination) && CardLists.getNotType(fetchList, "Creature").isEmpty()) {
|
||||||
|
c = chooseCreature(decider, fetchList);
|
||||||
|
} else if (ZoneType.Battlefield.equals(destination) || ZoneType.Graveyard.equals(destination)) {
|
||||||
|
if (!activator.equals(decider) && sa.hasParam("GainControl")) {
|
||||||
|
c = ComputerUtilCard.getWorstAI(fetchList);
|
||||||
|
} else {
|
||||||
|
c = ComputerUtilCard.getBestAI(fetchList);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Don't fetch another tutor with the same name
|
||||||
|
List<Card> sameNamed = CardLists.filter(fetchList, Predicates.not(CardPredicates.nameEquals(sa.getSourceCard().getName())));
|
||||||
|
if (origin.contains(ZoneType.Library) && !sameNamed.isEmpty()) {
|
||||||
|
fetchList = sameNamed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does AI need a land?
|
||||||
|
List<Card> hand = decider.getCardsIn(ZoneType.Hand);
|
||||||
|
if (CardLists.filter(hand, Presets.LANDS).isEmpty() && CardLists.filter(decider.getCardsIn(ZoneType.Battlefield), Presets.LANDS).size() < 4) {
|
||||||
|
boolean canCastSomething = false;
|
||||||
|
for (Card cardInHand : hand) {
|
||||||
|
canCastSomething |= ComputerUtilMana.hasEnoughManaSourcesToCast(cardInHand.getFirstSpellAbility(), decider);
|
||||||
|
}
|
||||||
|
if (!canCastSomething) {
|
||||||
|
System.out.println("Pulling a land as there are none in hand, less than 4 on the board, and nothing in hand is castable.");
|
||||||
|
c = basicManaFixing(decider, fetchList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c == null) {
|
||||||
|
System.out.println("Don't need a land or none available; trying for a creature.");
|
||||||
|
fetchList = CardLists.getNotType(fetchList, "Land");
|
||||||
|
// Prefer to pull a creature, generally more useful for AI.
|
||||||
|
c = chooseCreature(decider, CardLists.filter(fetchList, CardPredicates.Presets.CREATURES));
|
||||||
|
}
|
||||||
|
if (c == null) { // Could not find a creature.
|
||||||
|
if (decider.getLife() <= 5) { // Desperate?
|
||||||
|
// Get something AI can cast soon.
|
||||||
|
System.out.println("5 Life or less, trying to find something castable.");
|
||||||
|
CardLists.sortByCmcDesc(fetchList);
|
||||||
|
for (Card potentialCard : fetchList) {
|
||||||
|
if (ComputerUtilMana.hasEnoughManaSourcesToCast(potentialCard.getFirstSpellAbility(), decider)) {
|
||||||
|
c = potentialCard;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Get the best card in there.
|
||||||
|
System.out.println("No creature and lots of life, finding something good.");
|
||||||
|
c = ComputerUtilCard.getBestAI(fetchList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c == null) {
|
||||||
|
c = first;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.ability.SpellAbilityAi#confirmAction(forge.game.player.Player, forge.card.spellability.SpellAbility, forge.game.player.PlayerActionConfirmMode, java.lang.String)
|
* @see forge.card.ability.SpellAbilityAi#confirmAction(forge.game.player.Player, forge.card.spellability.SpellAbility, forge.game.player.PlayerActionConfirmMode, java.lang.String)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -644,19 +644,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if( optional && !decider.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneGeneral, defined ? "Put that card from " + origin + "to " + destination : "Search " + origin + "?"))
|
if( optional && !decider.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneGeneral, defined ? "Put that card from " + origin + "to " + destination : "Search " + origin + "?"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (decider.isHuman()) {
|
String changeType = sa.getParam("ChangeType");
|
||||||
changeHiddenOriginResolveHuman(decider, sa, player, changeNum, origin, destination, libraryPos);
|
|
||||||
} else {
|
|
||||||
ChangeZoneAi.hiddenOriginResolveAI(decider, sa, player, changeNum, origin, destination, libraryPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void changeHiddenOriginResolveHuman(final Player decider, final SpellAbility sa, Player player, int changeNum, List<ZoneType> origin, ZoneType destination, int libraryPos) {
|
|
||||||
final Card source = sa.getSourceCard();
|
|
||||||
final boolean defined = sa.hasParam("Defined");
|
|
||||||
final Game game = player.getGame();
|
|
||||||
|
|
||||||
final List<Card> movedCards = new ArrayList<Card>();
|
|
||||||
|
|
||||||
List<Card> fetchList;
|
List<Card> fetchList;
|
||||||
boolean shuffleMandatory = true;
|
boolean shuffleMandatory = true;
|
||||||
@@ -668,7 +656,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
} else if (!origin.contains(ZoneType.Library) && !origin.contains(ZoneType.Hand)
|
} else if (!origin.contains(ZoneType.Library) && !origin.contains(ZoneType.Hand)
|
||||||
&& !sa.hasParam("DefinedPlayer")) {
|
&& !sa.hasParam("DefinedPlayer")) {
|
||||||
fetchList = game.getCardsIn(origin);
|
fetchList = player.getGame().getCardsIn(origin);
|
||||||
} else {
|
} else {
|
||||||
fetchList = player.getCardsIn(origin);
|
fetchList = player.getCardsIn(origin);
|
||||||
if (origin.contains(ZoneType.Library) && !sa.hasParam("NoLooking")) {
|
if (origin.contains(ZoneType.Library) && !sa.hasParam("NoLooking")) {
|
||||||
@@ -676,9 +664,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (decider.hasKeyword("LimitSearchLibrary")) { // Aven Mindcensor
|
if (decider.hasKeyword("LimitSearchLibrary")) { // Aven Mindcensor
|
||||||
fetchList.removeAll(player.getCardsIn(ZoneType.Library));
|
fetchList.removeAll(player.getCardsIn(ZoneType.Library));
|
||||||
final int fetchNum = Math.min(player.getCardsIn(ZoneType.Library).size(), 4);
|
final int fetchNum = Math.min(player.getCardsIn(ZoneType.Library).size(), 4);
|
||||||
if (fetchNum == 0) {
|
if (fetchNum == 0)
|
||||||
searchedLibrary = false;
|
searchedLibrary = false;
|
||||||
}
|
else
|
||||||
fetchList.addAll(player.getCardsIn(ZoneType.Library, fetchNum));
|
fetchList.addAll(player.getCardsIn(ZoneType.Library, fetchNum));
|
||||||
}
|
}
|
||||||
if (decider.hasKeyword("CantSearchLibrary")) {
|
if (decider.hasKeyword("CantSearchLibrary")) {
|
||||||
@@ -691,14 +679,13 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!defined && changeType != null)
|
||||||
|
fetchList = AbilityUtils.filterListByType(fetchList, sa.getParam("ChangeType"), sa);
|
||||||
|
|
||||||
if (searchedLibrary && decider.equals(player)) { // should only count the number of searching player's own library
|
if (searchedLibrary && decider.equals(player)) { // should only count the number of searching player's own library
|
||||||
decider.incLibrarySearched();
|
decider.incLibrarySearched();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("NoShuffle")) {
|
|
||||||
shuffleMandatory = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!defined) {
|
if (!defined) {
|
||||||
if (origin.contains(ZoneType.Library) && !defined && !sa.hasParam("NoLooking") && !decider.hasKeyword("CantSearchLibrary")) {
|
if (origin.contains(ZoneType.Library) && !defined && !sa.hasParam("NoLooking") && !decider.hasKeyword("CantSearchLibrary")) {
|
||||||
final int fetchNum = Math.min(player.getCardsIn(ZoneType.Library).size(), 4);
|
final int fetchNum = Math.min(player.getCardsIn(ZoneType.Library).size(), 4);
|
||||||
@@ -711,9 +698,40 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (origin.contains(ZoneType.Hand) && player.isOpponentOf(decider)) {
|
if (origin.contains(ZoneType.Hand) && player.isOpponentOf(decider)) {
|
||||||
decider.getController().reveal(player.getCardsIn(ZoneType.Hand), ZoneType.Hand, player, source.getName() + " - Looking at cards in ");
|
decider.getController().reveal(player.getCardsIn(ZoneType.Hand), ZoneType.Hand, player, source.getName() + " - Looking at cards in ");
|
||||||
}
|
}
|
||||||
fetchList = AbilityUtils.filterListByType(fetchList, sa.getParam("ChangeType"), sa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("NoShuffle")) {
|
||||||
|
shuffleMandatory = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Game game = player.getGame();
|
||||||
|
if (sa.hasParam("Unimprint")) {
|
||||||
|
source.clearImprinted();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Card> movedCards;
|
||||||
|
if (decider.isHuman()) {
|
||||||
|
movedCards = changeHiddenOriginResolveHuman(decider, sa, player, changeNum, origin, destination, fetchList, libraryPos);
|
||||||
|
} else {
|
||||||
|
movedCards = ChangeZoneAi.hiddenOriginResolveAI(decider, sa, player, changeNum, origin, destination, fetchList, libraryPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((!ZoneType.Battlefield.equals(destination) && changeType != null && !defined)
|
||||||
|
|| (sa.hasParam("Reveal") && !movedCards.isEmpty())) && !sa.hasParam("NoReveal")) {
|
||||||
|
game.getAction().reveal(movedCards, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((origin.contains(ZoneType.Library) && !destination.equals(ZoneType.Library) && !defined && shuffleMandatory)
|
||||||
|
|| (sa.hasParam("Shuffle") && "True".equals(sa.getParam("Shuffle")))) {
|
||||||
|
player.shuffle(sa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Card> changeHiddenOriginResolveHuman(final Player decider, final SpellAbility sa, Player player, int changeNum, List<ZoneType> origin, ZoneType destination, List<Card> fetchList, int libraryPos) {
|
||||||
|
final Card source = sa.getSourceCard();
|
||||||
|
final Game game = player.getGame();
|
||||||
|
|
||||||
final boolean remember = sa.hasParam("RememberChanged");
|
final boolean remember = sa.hasParam("RememberChanged");
|
||||||
final boolean champion = sa.hasParam("Champion");
|
final boolean champion = sa.hasParam("Champion");
|
||||||
final boolean forget = sa.hasParam("ForgetChanged");
|
final boolean forget = sa.hasParam("ForgetChanged");
|
||||||
@@ -722,9 +740,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
final String totalcmc = sa.getParam("WithTotalCMC");
|
final String totalcmc = sa.getParam("WithTotalCMC");
|
||||||
int totcmc = AbilityUtils.calculateAmount(source, totalcmc, sa);
|
int totcmc = AbilityUtils.calculateAmount(source, totalcmc, sa);
|
||||||
|
|
||||||
if (sa.hasParam("Unimprint")) {
|
final List<Card> movedCards = new ArrayList<Card>();
|
||||||
source.clearImprinted();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < changeNum && destination != null; i++) {
|
for (int i = 0; i < changeNum && destination != null; i++) {
|
||||||
if (sa.hasParam("DifferentNames")) {
|
if (sa.hasParam("DifferentNames")) {
|
||||||
@@ -773,12 +789,11 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
c.setTapped(true);
|
c.setTapped(true);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("GainControl")) {
|
if (sa.hasParam("GainControl")) {
|
||||||
|
Player newController = sa.getActivatingPlayer();
|
||||||
if (sa.hasParam("NewController")) {
|
if (sa.hasParam("NewController")) {
|
||||||
final Player p = AbilityUtils.getDefinedPlayers(source, sa.getParam("NewController"), sa).get(0);
|
newController = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa).get(0);
|
||||||
c.setController(p, game.getNextTimestamp());
|
|
||||||
} else {
|
|
||||||
c.setController(sa.getActivatingPlayer(), game.getNextTimestamp());
|
|
||||||
}
|
}
|
||||||
|
c.setController(newController, game.getNextTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("AttachedTo")) {
|
if (sa.hasParam("AttachedTo")) {
|
||||||
@@ -896,18 +911,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
totcmc -= movedCard.getCMC();
|
totcmc -= movedCard.getCMC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sa.hasParam("Reveal") && !movedCards.isEmpty()) {
|
|
||||||
ZoneType zt = null;
|
|
||||||
if (!origin.isEmpty()) {
|
|
||||||
zt = origin.get(0);
|
|
||||||
}
|
|
||||||
decider.getController().reveal(movedCards, zt, player, source + " - Revealed card" + (movedCards.size() > 1 ? "s" : "") + " from ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((origin.contains(ZoneType.Library) && !destination.equals(ZoneType.Library) && !defined && shuffleMandatory)
|
return movedCards;
|
||||||
|| (sa.hasParam("Shuffle") && "True".equals(sa.getParam("Shuffle")))) {
|
|
||||||
player.shuffle(sa);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user