This commit is contained in:
tool4EvEr
2023-02-24 14:17:56 +01:00
parent 2a88ac8402
commit d6e479705f
28 changed files with 41 additions and 89 deletions

View File

@@ -376,7 +376,7 @@ public class AiController {
}
private CardCollection filterLandsToPlay(CardCollection landList) {
final CardCollection hand = new CardCollection(player.getCardsIn(ZoneType.Hand));
final CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
CardCollection nonLandList = CardLists.filter(hand, Predicates.not(CardPredicates.Presets.LANDS));
if (landList.size() == 1 && nonLandList.size() < 3) {
CardCollectionView cardsInPlay = player.getCardsIn(ZoneType.Battlefield);
@@ -1148,7 +1148,6 @@ public class AiController {
public CardCollection getCardsToDiscard(final int numDiscard, final String[] uTypes, final SpellAbility sa) {
return getCardsToDiscard(numDiscard, uTypes, sa, CardCollection.EMPTY);
}
public CardCollection getCardsToDiscard(final int numDiscard, final String[] uTypes, final SpellAbility sa, final CardCollectionView exclude) {
boolean noFiltering = sa != null && "DiscardCMCX".equals(sa.getParam("AILogic")); // list AI logic for which filtering is taken care of elsewhere
CardCollection hand = new CardCollection(player.getCardsIn(ZoneType.Hand));

View File

@@ -340,9 +340,9 @@ public class AiCostDecision extends CostDecisionMakerBase {
CardCollectionView list;
if (cost.isSameZone()) {
list = new CardCollection(game.getCardsIn(cost.getFrom()));
list = game.getCardsIn(cost.getFrom());
} else {
list = new CardCollection(player.getCardsIn(cost.getFrom()));
list = player.getCardsIn(cost.getFrom());
}
int c = cost.getAbilityAmount(ability);

View File

@@ -2324,7 +2324,7 @@ public class ComputerUtil {
CardLists.sortByCmcDesc(goodChoices);
return new CardCollection(Aggregates.random(goodChoices, max));
return goodChoices.subList(0, max);
}
public static CardCollection getCardsToDiscardFromFriend(Player aiChooser, Player p, SpellAbility sa, CardCollection validCards, int min, int max) {

View File

@@ -537,7 +537,7 @@ public class ComputerUtilCard {
public static final Card getCheapestSpellAI(final Iterable<Card> list) {
if (!Iterables.isEmpty(list)) {
CardCollection cc = CardLists.filter(new CardCollection(list),
CardCollection cc = CardLists.filter(list,
Predicates.or(CardPredicates.isType("Instant"), CardPredicates.isType("Sorcery")));
Collections.sort(cc, CardLists.CmcComparatorInv);

View File

@@ -435,9 +435,7 @@ public class ComputerUtilCost {
final int vehicleValue = ComputerUtilCard.evaluateCreature(vehicle);
String totalP = type.split("withTotalPowerGE")[1];
type = TextUtil.fastReplace(type, TextUtil.concatNoSpace("+withTotalPowerGE", totalP), "");
CardCollection exclude = CardLists.getValidCards(
new CardCollection(ai.getCardsIn(ZoneType.Battlefield)), type.split(";"),
source.getController(), source, sa);
CardCollection exclude = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, sa);
exclude = CardLists.filter(exclude, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {

View File

@@ -1253,7 +1253,7 @@ public abstract class GameState {
c.setBackSide(true);
}
else if (info.startsWith("OnAdventure")) {
String abAdventure = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ExileOnMoved$ Exile | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.nonCopiedSpell";
String abAdventure = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ForgetOnMoved$ Exile | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.nonCopiedSpell";
SpellAbility saAdventure = AbilityFactory.getAbility(abAdventure, c);
StringBuilder sbPlay = new StringBuilder();
sbPlay.append("Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonAdventure");

View File

@@ -1333,8 +1333,7 @@ public class AttachAi extends SpellAbilityAi {
// Is a SA that moves target attachment
if ("MoveTgtAura".equals(sa.getParam("AILogic"))) {
CardCollection list = new CardCollection(CardUtil.getValidCardsToTarget(tgt, sa));
list = CardLists.filter(list, Predicates.or(CardPredicates.isControlledByAnyOf(aiPlayer.getOpponents()), new Predicate<Card>() {
CardCollection list = CardLists.filter(CardUtil.getValidCardsToTarget(tgt, sa), Predicates.or(CardPredicates.isControlledByAnyOf(aiPlayer.getOpponents()), new Predicate<Card>() {
@Override
public boolean apply(final Card card) {
return ComputerUtilCard.isUselessCreature(aiPlayer, card.getAttachedTo());
@@ -1343,7 +1342,7 @@ public class AttachAi extends SpellAbilityAi {
return !list.isEmpty() ? ComputerUtilCard.getBestAI(list) : null;
} else if ("Unenchanted".equals(sa.getParam("AILogic"))) {
CardCollection list = new CardCollection(CardUtil.getValidCardsToTarget(tgt, sa));
List<Card> list = CardUtil.getValidCardsToTarget(tgt, sa);
CardCollection preferred = CardLists.filter(list, new Predicate<Card>() {
@Override
public boolean apply(final Card card) {

View File

@@ -18,8 +18,7 @@ public class ConniveAi extends SpellAbilityAi {
return false; // can't draw anything
}
CardCollection list;
list = CardLists.getTargetableCards(new CardCollection(ai.getCardsIn(ZoneType.Battlefield)), sa);
CardCollection list = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
// Filter AI-specific targets if provided
list = ComputerUtil.filterAITgts(sa, ai, list, false);
@@ -69,8 +68,7 @@ public class ConniveAi extends SpellAbilityAi {
}
boolean preferred = true;
CardCollection list;
list = CardLists.getTargetableCards(new CardCollection(ai.getCardsIn(ZoneType.Battlefield)), sa);
CardCollection list = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
// Filter AI-specific targets if provided
list = ComputerUtil.filterAITgts(sa, ai, list, false);

View File

@@ -341,7 +341,7 @@ public class CountersPutAi extends CountersAi {
if (sa.hasParam("Bolster")) {
CardCollection creatsYouCtrl = ai.getCreaturesInPlay();
CardCollection leastToughness = new CardCollection(Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetNetToughness));
List<Card> leastToughness = Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetNetToughness);
if (leastToughness.isEmpty()) {
return false;
}

View File

@@ -431,7 +431,7 @@ public class DamageDealAi extends DamageAiBase {
final Game game = source.getGame();
List<Card> hPlay = CardLists.filter(getTargetableCards(ai, sa, pl, tgt, activator, source, game), CardPredicates.Presets.PLANESWALKERS);
List<Card> killables = CardLists.filter(hPlay, new Predicate<Card>() {
CardCollection killables = CardLists.filter(hPlay, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.getSVar("Targeting").equals("Dies")
@@ -442,7 +442,7 @@ public class DamageDealAi extends DamageAiBase {
});
// Filter AI-specific targets if provided
killables = ComputerUtil.filterAITgts(sa, ai, new CardCollection(killables), true);
killables = ComputerUtil.filterAITgts(sa, ai, killables, true);
// We can kill a planeswalker, so go for it
if (pl.isOpponentOf(ai) && activator.equals(ai) && !killables.isEmpty()) {

View File

@@ -918,9 +918,6 @@ public class GameAction {
return changeZone(game.getZoneOf(c), library, c, libPosition, cause, params);
}
public final Card moveToVariantDeck(Card c, ZoneType zone, int deckPosition, SpellAbility cause) {
return moveToVariantDeck(c, zone, deckPosition, cause, null);
}
public final Card moveToVariantDeck(Card c, ZoneType zone, int deckPosition, SpellAbility cause, Map<AbilityKey, Object> params) {
final PlayerZone deck = c.getOwner().getZone(zone);
if (deckPosition == -1 || deckPosition > deck.size()) {
@@ -1809,7 +1806,6 @@ public class GameAction {
// remove the ones that got already removed by other legend rule above
emptyNameAllNonLegendary.removeAll(removed);
if (emptyNameAllNonLegendary.size() > 1) {
recheck = true;
Card toKeep = p.getController().chooseSingleEntityForEffect(emptyNameAllNonLegendary, new SpellAbility.EmptySa(ApiType.InternalLegendaryRule, new Card(-1, game), p),

View File

@@ -34,7 +34,7 @@ public class AttachEffect extends SpellAbilityEffect {
final Card source = sa.getHostCard();
final Game game = source.getGame();
CardCollection attachments;
CardCollectionView attachments;
final Player p = sa.getActivatingPlayer();
@@ -130,7 +130,7 @@ public class AttachEffect extends SpellAbilityEffect {
attachToName = attachTo.toString();
}
attachments = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, attachments, ZoneType.Battlefield, sa);
attachments = GameActionUtil.orderCardsByTheirOwners(game, attachments, ZoneType.Battlefield, sa);
// If Cast Targets will be checked on the Stack
for (final Card attachment : attachments) {

View File

@@ -136,7 +136,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
if (!random && !((destination == ZoneType.Library || destination == ZoneType.PlanarDeck) && sa.hasParam("Shuffle"))) {
if ((destination == ZoneType.Library || destination == ZoneType.PlanarDeck) && cards.size() >= 2) {
Player p = AbilityUtils.getDefinedPlayers(source, sa.getParamOrDefault("DefinedPlayer", "You"), sa).get(0);
Player p = AbilityUtils.getDefinedPlayers(source, sa.getParam("DefinedPlayer"), sa).get(0);
cards = (CardCollection) p.getController().orderMoveToZoneList(cards, destination, sa);
//the last card in this list will be the closest to the top, but we want the first card to be closest.
//so reverse it here before moving them to the library.

View File

@@ -448,7 +448,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
* a {@link forge.game.spellability.SpellAbility} object.
*/
private void changeKnownOriginResolve(final SpellAbility sa) {
Iterable<Card> tgtCards = getTargetCards(sa);
CardCollectionView tgtCards = getTargetCards(sa);
final Player player = sa.getActivatingPlayer();
final Card hostCard = sa.getHostCard();
final Game game = player.getGame();
@@ -517,15 +517,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
CardCollectionView lastStateGraveyard = game.copyLastStateGraveyard();
// CR 401.4
if (destination.equals(ZoneType.Library) && !shuffle && Iterables.size(tgtCards) > 1) {
if (destination.equals(ZoneType.Library) && !shuffle && tgtCards.size() > 1) {
if (sa.hasParam("RandomOrder")) {
final CardCollection random = new CardCollection(tgtCards);
CardLists.shuffle(random);
tgtCards = random;
} else if (sa.hasParam("Chooser")) {
tgtCards = chooser.getController().orderMoveToZoneList(new CardCollection(tgtCards), destination, sa);
tgtCards = chooser.getController().orderMoveToZoneList(tgtCards, destination, sa);
} else {
tgtCards = GameActionUtil.orderCardsByTheirOwners(game, new CardCollection(tgtCards), destination, sa);
tgtCards = GameActionUtil.orderCardsByTheirOwners(game, tgtCards, destination, sa);
}
}

View File

@@ -120,7 +120,6 @@ public class DigEffect extends SpellAbilityEffect {
int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : -1;
int destZone1ChangeNum = 1;
final boolean mitosis = sa.hasParam("Mitosis");
String changeValid = sa.getParamOrDefault("ChangeValid", "");
final boolean anyNumber = sa.hasParam("AnyNumber");
@@ -245,9 +244,7 @@ public class DigEffect extends SpellAbilityEffect {
CardCollection movedCards;
rest.addAll(top);
CardCollection valid;
if (mitosis) {
valid = sharesNameWithCardOnBattlefield(game, top);
} else if (!changeValid.isEmpty()) {
if (!changeValid.isEmpty()) {
if (changeValid.contains("ChosenType")) {
changeValid = changeValid.replace("ChosenType", host.getChosenType());
}
@@ -395,10 +392,7 @@ public class DigEffect extends SpellAbilityEffect {
final PlayerZone zone = c.getOwner().getZone(destZone1);
if (zone.is(ZoneType.Library) || zone.is(ZoneType.PlanarDeck) || zone.is(ZoneType.SchemeDeck)) {
if (libraryPosition == -1 || libraryPosition > zone.size()) {
libraryPosition = zone.size();
}
c = game.getAction().moveTo(zone, c, libraryPosition, sa);
c = game.getAction().moveTo(destZone1, c, libraryPosition, sa);
} else {
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
moveParams.put(AbilityKey.LastStateBattlefield, lastStateBattlefield);
@@ -472,14 +466,10 @@ public class DigEffect extends SpellAbilityEffect {
// Closest to top
Collections.reverse(afterOrder);
}
for (final Card c : afterOrder) {
final ZoneType origin = c.getZone().getZoneType();
Card m;
if (destZone2 == ZoneType.Library) {
m = game.getAction().moveToLibrary(c, libraryPosition2, sa);
} else {
m = game.getAction().moveToVariantDeck(c, destZone2, libraryPosition2, sa);
}
Card m = game.getAction().moveTo(destZone2, c, libraryPosition2, sa);
if (m != null && !origin.equals(m.getZone().getZoneType())) {
table.put(origin, m.getZone().getZoneType(), m);
}
@@ -520,19 +510,4 @@ public class DigEffect extends SpellAbilityEffect {
counterTable.replaceCounterEffect(game, sa, true);
}
// TODO This should be somewhere else, maybe like CardUtil or something like that
// returns a List<Card> that is a subset of list with cards that share a name
// with a permanent on the battlefield
private static CardCollection sharesNameWithCardOnBattlefield(final Game game, final List<Card> list) {
final CardCollection toReturn = new CardCollection();
final CardCollectionView play = game.getCardsIn(ZoneType.Battlefield);
for (final Card c : list) {
for (final Card p : play) {
if (p.sharesNameWith(c) && !toReturn.contains(c)) {
toReturn.add(c);
}
}
}
return toReturn;
}
}

View File

@@ -120,10 +120,7 @@ public class DigMultipleEffect extends SpellAbilityEffect {
if (!sa.hasParam("ChangeLater")) {
if (zone.is(ZoneType.Library) || zone.is(ZoneType.PlanarDeck) || zone.is(ZoneType.SchemeDeck)) {
if (libraryPosition == -1 || libraryPosition > zone.size()) {
libraryPosition = zone.size();
}
c = game.getAction().moveTo(zone, c, libraryPosition, sa);
c = game.getAction().moveTo(destZone1, c, libraryPosition, sa);
} else {
if (destZone1.equals(ZoneType.Battlefield)) {
if (sa.hasParam("Tapped")) {
@@ -167,12 +164,7 @@ public class DigMultipleEffect extends SpellAbilityEffect {
}
for (final Card c : afterOrder) {
final ZoneType origin = c.getZone().getZoneType();
Card m;
if (destZone2 == ZoneType.Library) {
m = game.getAction().moveToLibrary(c, libraryPosition2, sa);
} else {
m = game.getAction().moveToVariantDeck(c, destZone2, libraryPosition2, sa);
}
Card m = game.getAction().moveTo(destZone2, c, libraryPosition2, sa);
if (m != null && !origin.equals(m.getZone().getZoneType())) {
table.put(origin, m.getZone().getZoneType(), m);
}

View File

@@ -255,7 +255,7 @@ public class EffectEffect extends SpellAbilityEffect {
// Set Chosen Cards
if (hostCard.hasChosenCard()) {
eff.setChosenCards(new CardCollection(hostCard.getChosenCards()));
eff.setChosenCards(hostCard.getChosenCards());
}
// Set Chosen Player

View File

@@ -43,7 +43,7 @@ public class ManifestEffect extends SpellAbilityEffect {
if (sa.hasParam("ChoiceZone")) {
choiceZone = ZoneType.smartValueOf(sa.getParam("ChoiceZone"));
}
CardCollection choices = new CardCollection(game.getCardsIn(choiceZone));
CardCollectionView choices = game.getCardsIn(choiceZone);
if (sa.hasParam("Choices")) {
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, source, sa);
}

View File

@@ -1844,7 +1844,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final CardCollectionView getChosenCards() {
return CardCollection.getView(chosenCards);
}
public final void setChosenCards(final CardCollection cards) {
public final void setChosenCards(final Iterable<Card> cards) {
chosenCards = view.setCards(chosenCards, cards, TrackableProperty.ChosenCards);
}
public boolean hasChosenCard() {

View File

@@ -268,7 +268,7 @@ public final class CardUtil {
newCopy.addRemembered(in.getRemembered());
newCopy.addImprintedCards(in.getImprintedCards());
newCopy.setChosenCards(new CardCollection(in.getChosenCards()));
newCopy.setChosenCards(in.getChosenCards());
newCopy.setChosenType(in.getChosenType());
newCopy.setChosenType2(in.getChosenType2());

View File

@@ -141,10 +141,7 @@ public class AttackConstraints {
attackersToRemove.add(attacker);
}
}
myPossibleAttackers.removeAll((Iterable<Card>) attackersToRemove);
for (final Card toRemove : attackersToRemove) {
reqs.removeAll(findAll(reqs, toRemove));
}
myPossibleAttackers.removeAll(attackersToRemove);
attackersToRemove.clear();
// Next, remove creatures with constraints that can't be fulfilled.

View File

@@ -157,7 +157,7 @@ public class CostPutCardToLib extends CostPartWithList {
@Override
protected Card doPayment(SpellAbility ability, Card targetCard, final boolean effect) {
return targetCard.getGame().getAction().moveToLibrary(targetCard, Integer.parseInt(getLibPos()),null);
return targetCard.getGame().getAction().moveToLibrary(targetCard, Integer.parseInt(getLibPos()), null);
}
public <T> T accept(ICostVisitor<T> visitor) {

View File

@@ -3,7 +3,7 @@ ManaCost:3 W W
Types:Legendary Creature Human Soldier
PT:4/4
K:Flash
T:Mode$ DamageDone | ValidSource$ Creature | ValidTarget$ You | CombatDamage$ True | IsPresent$ Card.Self+ThisTurnEntered | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature deals combat damage to you, if CARDNAME entered the battlefield this turn, exile that creature until CARDNAME leaves the battlefield.
T:Mode$ DamageDone | ValidSource$ Creature | ValidTarget$ You | CombatDamage$ True | IsPresent$ Card.Self+ThisTurnEntered | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature deals combat damage to you, if CARDNAME entered the battlefield this turn, exile that creature until NICKNAME leaves the battlefield.
SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | Defined$ TriggeredSourceLKICopy | Duration$ UntilHostLeavesPlay
SVar:AmbushAI:BlockOnly
Oracle:Flash (You may cast this spell any time you could cast an instant.)\nWhenever a creature deals combat damage to you, if Hixus, Prison Warden entered the battlefield this turn, exile that creature until Hixus leaves the battlefield. (That creature returns under its owner's control.)

View File

@@ -1,6 +1,6 @@
Name:Mitotic Manipulation
ManaCost:1 U U
Types:Sorcery
A:SP$ Dig | Cost$ 1 U U | DigNum$ 7 | ChangeValid$ Permanent | ChangeNum$ 1 | Optional$ True | Mitosis$ True | DestinationZone$ Battlefield | SpellDescription$ Look at the top seven cards of your library. You may put one of those cards onto the battlefield if it has the same name as a permanent. Put the rest on the bottom of your library in any order.
A:SP$ Dig | Cost$ 1 U U | DigNum$ 7 | ChangeValid$ Permanent.sharesNameWith Battlefield | ChangeNum$ 1 | Optional$ True | DestinationZone$ Battlefield | SpellDescription$ Look at the top seven cards of your library. You may put one of those cards onto the battlefield if it has the same name as a permanent. Put the rest on the bottom of your library in any order.
AI:RemoveDeck:All
Oracle:Look at the top seven cards of your library. You may put one of those cards onto the battlefield if it has the same name as a permanent. Put the rest on the bottom of your library in any order.

View File

@@ -1,11 +1,9 @@
Name:Retraced Image
ManaCost:U
Types:Sorcery
# You can not clear a remembered object from a card on the stack, so this card is cleaned beforehand.
A:SP$ Pump | Cost$ U | SubAbility$ DBCleanup | StackDescription$ None | SpellDescription$ Reveal a card in your hand, then put that card onto the battlefield if it has the same name as a permanent.
SVar:DBReveal:DB$ Reveal | RememberRevealed$ True | SubAbility$ DBChangeZone
SVar:DBChangeZone:DB$ ChangeZone | Defined$ Remembered | Origin$ Hand | Destination$ Battlefield | ConditionDefined$ Remembered | ConditionPresent$ Card.sharesNameWith Battlefield | ConditionCompare$ GE1
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBReveal
A:SP$ Reveal | RememberRevealed$ True | SubAbility$ DBChangeZone | SpellDescription$ Reveal a card in your hand, then put that card onto the battlefield if it has the same name as a permanent.
SVar:DBChangeZone:DB$ ChangeZone | Defined$ Remembered | Origin$ Hand | Destination$ Battlefield | ConditionDefined$ Remembered | ConditionPresent$ Card.sharesNameWith Battlefield | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
AI:RemoveDeck:All
AI:RemoveDeck:Random
Oracle:Reveal a card in your hand, then put that card onto the battlefield if it has the same name as a permanent.

View File

@@ -1,7 +1,7 @@
Name:Spelljack
ManaCost:3 U U U
Types:Instant
A:SP$ Counter | Cost$ 3 U U U | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | RememberCountered$ True | ForgetOtherTargets$ True | Destination$ Exile | SubAbility$ DBEffect | SpellDescription$ Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may play it without paying its mana cost for as long as it remains exiled. (If it has X in its mana cost, X is 0.)
A:SP$ Counter | Cost$ 3 U U U | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | RememberCountered$ True | Destination$ Exile | SubAbility$ DBEffect | SpellDescription$ Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may play it without paying its mana cost for as long as it remains exiled. (If it has X in its mana cost, X is 0.)
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ Play | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
SVar:Play:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play cards exiled with Spelljack.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True

View File

@@ -117,7 +117,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
cardSelectLocked = true;
ThreadUtil.invokeInGameThread(new Runnable() {
@Override public void run() {
final CardCollection hand = new CardCollection(c0.getController().getCardsIn(ZoneType.Hand));
final CardCollectionView hand = c0.getController().getCardsIn(ZoneType.Hand);
for (final Card c : hand) {
player.getGame().getAction().exile(c, null);
}

View File

@@ -282,7 +282,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
for (final Player p : players) {
final CardCollection enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
if (enoughType.size() < c) {
list.removeAll((CardCollectionView)enoughType);
list.removeAll(enoughType);
} else {
payableZone.add(p);
}