mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
implement [MH3] Nethergoyf, refactor targets usages by game param (#12267)
This commit is contained in:
parent
88b6f4036f
commit
754b382e78
62 changed files with 592 additions and 285 deletions
|
|
@ -1147,7 +1147,7 @@ public class CardView extends SimpleCardView {
|
|||
|
||||
// from normal targets
|
||||
for (Target target : targets) {
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
newTargets.addAll(target.getTargets());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import mage.target.Targets;
|
|||
import mage.util.RandomUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -392,7 +391,7 @@ public class ComputerPlayer6 extends ComputerPlayer {
|
|||
if (effect != null
|
||||
&& stackObject.getControllerId().equals(playerId)) {
|
||||
Target target = effect.getTarget();
|
||||
if (!target.doneChoosing()) {
|
||||
if (!target.doneChoosing(game)) {
|
||||
for (UUID targetId : target.possibleTargets(stackObject.getControllerId(), stackObject.getStackAbility(), game)) {
|
||||
Game sim = game.createSimulationForAI();
|
||||
StackAbility newAbility = (StackAbility) stackObject.copy();
|
||||
|
|
@ -740,10 +739,10 @@ public class ComputerPlayer6 extends ComputerPlayer {
|
|||
if (targets.isEmpty()) {
|
||||
return super.chooseTarget(outcome, cards, target, source, game);
|
||||
}
|
||||
if (!target.doneChoosing()) {
|
||||
if (!target.doneChoosing(game)) {
|
||||
for (UUID targetId : targets) {
|
||||
target.addTarget(targetId, source, game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
targets.clear();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -758,10 +757,10 @@ public class ComputerPlayer6 extends ComputerPlayer {
|
|||
if (targets.isEmpty()) {
|
||||
return super.choose(outcome, cards, target, source, game);
|
||||
}
|
||||
if (!target.doneChoosing()) {
|
||||
if (!target.doneChoosing(game)) {
|
||||
for (UUID targetId : targets) {
|
||||
target.add(targetId, game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
targets.clear();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import mage.abilities.costs.mana.ManaCost;
|
|||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.cards.Card;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.Combat;
|
||||
import mage.game.events.GameEvent;
|
||||
|
|
@ -149,7 +148,7 @@ public final class SimulatedPlayer2 extends ComputerPlayer {
|
|||
}
|
||||
newAbility.adjustTargets(game);
|
||||
// add the different possible target option for the specific X value
|
||||
if (!newAbility.getTargets().getUnchosen().isEmpty()) {
|
||||
if (!newAbility.getTargets().getUnchosen(game).isEmpty()) {
|
||||
addTargetOptions(options, newAbility, targetNum, game);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
for (int i = unplayable.size() - 1; i >= 0; i--) {
|
||||
if (target.canTarget(abilityControllerId, unplayable.values().toArray(new Card[0])[i].getId(), null, game)) {
|
||||
target.add(unplayable.values().toArray(new Card[0])[i].getId(), game);
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -184,7 +184,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
for (int i = 0; i < hand.size(); i++) {
|
||||
if (target.canTarget(abilityControllerId, hand.toArray(new UUID[0])[i], null, game)) {
|
||||
target.add(hand.toArray(new UUID[0])[i], game);
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -252,12 +252,12 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
}
|
||||
// add the target
|
||||
target.add(permanent.getId(), game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInHand
|
||||
|
|
@ -269,7 +269,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
cards.add(card);
|
||||
}
|
||||
}
|
||||
while ((outcome.isGood() ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen())
|
||||
while ((outcome.isGood() ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen(game))
|
||||
&& !cards.isEmpty()) {
|
||||
Card pick = pickTarget(abilityControllerId, cards, outcome, target, null, game);
|
||||
if (pick != null) {
|
||||
|
|
@ -277,7 +277,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
cards.remove(pick);
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetAnyTarget) {
|
||||
|
|
@ -410,7 +410,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
|
||||
// exile cost workaround: exile is bad, but exile from graveyard in most cases is good (more exiled -- more good things you get, e.g. delve's pay)
|
||||
boolean isRealGood = outcome.isGood() || outcome == Outcome.Exile;
|
||||
while ((isRealGood ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen())
|
||||
while ((isRealGood ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen(game))
|
||||
&& !cards.isEmpty()) {
|
||||
Card pick = pickTarget(abilityControllerId, cards, outcome, target, null, game);
|
||||
if (pick != null) {
|
||||
|
|
@ -421,7 +421,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
}
|
||||
}
|
||||
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInGraveyard
|
||||
|
|
@ -437,7 +437,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
|
||||
// exile cost workaround: exile is bad, but exile from graveyard in most cases is good (more exiled -- more good things you get, e.g. delve's pay)
|
||||
boolean isRealGood = outcome.isGood() || outcome == Outcome.Exile;
|
||||
while ((isRealGood ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen())
|
||||
while ((isRealGood ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen(game))
|
||||
&& !cards.isEmpty()) {
|
||||
Card pick = pickTarget(abilityControllerId, cards, outcome, target, null, game);
|
||||
if (pick != null) {
|
||||
|
|
@ -448,7 +448,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
}
|
||||
}
|
||||
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInYourGraveyard
|
||||
|
|
@ -460,7 +460,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
Card card = pickTarget(abilityControllerId, cards, outcome, target, null, game);
|
||||
if (card != null && alreadyTargeted != null && !alreadyTargeted.contains(card.getId())) {
|
||||
target.add(card.getId(), game);
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -485,7 +485,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
Card card = pickTarget(abilityControllerId, cards, outcome, target, null, game);
|
||||
if (card != null && alreadyTargeted != null && !alreadyTargeted.contains(card.getId())) {
|
||||
target.add(card.getId(), game);
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -517,14 +517,14 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
if (target.getOriginalTarget() instanceof TargetPermanentOrSuspendedCard) {
|
||||
Cards cards = new CardsImpl(possibleTargets);
|
||||
List<Card> possibleCards = new ArrayList<>(cards.getCards(game));
|
||||
while (!target.isChosen() && !possibleCards.isEmpty()) {
|
||||
while (!target.isChosen(game) && !possibleCards.isEmpty()) {
|
||||
Card pick = pickTarget(abilityControllerId, possibleCards, outcome, target, null, game);
|
||||
if (pick != null) {
|
||||
target.addTarget(pick.getId(), null, game);
|
||||
possibleCards.remove(pick);
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCard
|
||||
|
|
@ -537,14 +537,14 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
while (!target.isChosen() && !cardsInCommandZone.isEmpty()) {
|
||||
while (!target.isChosen(game) && !cardsInCommandZone.isEmpty()) {
|
||||
Card pick = pickTarget(abilityControllerId, cardsInCommandZone, outcome, target, null, game);
|
||||
if (pick != null) {
|
||||
target.addTarget(pick.getId(), null, game);
|
||||
cardsInCommandZone.remove(pick);
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Target wasn't handled in computer's choose method: " + target.getClass().getCanonicalName());
|
||||
|
|
@ -641,7 +641,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetDiscard
|
||||
|
|
@ -650,7 +650,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
// good
|
||||
Cards cards = new CardsImpl(possibleTargets);
|
||||
List<Card> cardsInHand = new ArrayList<>(cards.getCards(game));
|
||||
while (!target.isChosen()
|
||||
while (!target.isChosen(game)
|
||||
&& !cardsInHand.isEmpty()
|
||||
&& target.getMaxNumberOfTargets() > target.getTargets().size()) {
|
||||
Card card = pickBestCard(cardsInHand, null, target, source, game);
|
||||
|
|
@ -658,7 +658,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
if (target.canTarget(abilityControllerId, card.getId(), source, game)) {
|
||||
target.addTarget(card.getId(), source, game);
|
||||
cardsInHand.remove(card);
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -671,7 +671,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
if (possibleTargets.contains(card.getId())
|
||||
&& target.canTarget(abilityControllerId, card.getId(), source, game)) {
|
||||
target.addTarget(card.getId(), source, game);
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -681,7 +681,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
if (possibleTargets.contains(card.getId())
|
||||
&& target.canTarget(abilityControllerId, card.getId(), source, game)) {
|
||||
target.addTarget(card.getId(), source, game);
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -707,7 +707,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -749,7 +749,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
target.addTarget(permanent.getId(), source, game);
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCreatureOrPlayer) {
|
||||
|
|
@ -956,14 +956,14 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInYourGraveyard) {
|
||||
List<Card> cards = new ArrayList<>(game.getPlayer(abilityControllerId).getGraveyard().getCards((FilterCard) target.getFilter(), game));
|
||||
while (!target.isChosen() && !cards.isEmpty()) {
|
||||
while (!target.isChosen(game) && !cards.isEmpty()) {
|
||||
Card card = pickTarget(abilityControllerId, cards, outcome, target, source, game);
|
||||
if (card != null) {
|
||||
target.addTarget(card.getId(), source, game);
|
||||
cards.remove(card); // pickTarget don't remove cards (only on second+ tries)
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetSpell
|
||||
|
|
@ -1034,7 +1034,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
if (target.getOriginalTarget() instanceof TargetDefender) {
|
||||
UUID randomDefender = RandomUtil.randomFromCollection(possibleTargets);
|
||||
target.addTarget(randomDefender, source, game);
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInASingleGraveyard) {
|
||||
|
|
@ -1042,14 +1042,14 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
for (Player player : game.getPlayers().values()) {
|
||||
cards.addAll(player.getGraveyard().getCards(game));
|
||||
}
|
||||
while (!target.isChosen() && !cards.isEmpty()) {
|
||||
while (!target.isChosen(game) && !cards.isEmpty()) {
|
||||
Card pick = pickTarget(abilityControllerId, cards, outcome, target, source, game);
|
||||
if (pick != null) {
|
||||
target.addTarget(pick.getId(), source, game);
|
||||
cards.remove(pick); // pickTarget don't remove cards (only on second+ tries)
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInExile) {
|
||||
|
|
@ -1070,14 +1070,14 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
cards.add(card);
|
||||
}
|
||||
}
|
||||
while (!target.isChosen() && !cards.isEmpty()) {
|
||||
while (!target.isChosen(game) && !cards.isEmpty()) {
|
||||
Card pick = pickTarget(abilityControllerId, cards, outcome, target, source, game);
|
||||
if (pick != null) {
|
||||
target.addTarget(pick.getId(), source, game);
|
||||
cards.remove(pick); // pickTarget don't remove cards (only on second+ tries)
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetActivatedAbility) {
|
||||
|
|
@ -1088,22 +1088,22 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
stackObjects.add(stackObject);
|
||||
}
|
||||
}
|
||||
while (!target.isChosen() && !stackObjects.isEmpty()) {
|
||||
while (!target.isChosen(game) && !stackObjects.isEmpty()) {
|
||||
StackObject pick = stackObjects.get(0);
|
||||
if (pick != null) {
|
||||
target.addTarget(pick.getId(), source, game);
|
||||
stackObjects.remove(0);
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetActivatedOrTriggeredAbility) {
|
||||
Iterator<UUID> iterator = target.possibleTargets(source.getControllerId(), source, game).iterator();
|
||||
while (!target.isChosen() && iterator.hasNext()) {
|
||||
while (!target.isChosen(game) && iterator.hasNext()) {
|
||||
target.addTarget(iterator.next(), source, game);
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInGraveyardBattlefieldOrStack) {
|
||||
|
|
@ -1121,14 +1121,14 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
if (target.getOriginalTarget() instanceof TargetPermanentOrSuspendedCard) {
|
||||
Cards cards = new CardsImpl(possibleTargets);
|
||||
List<Card> possibleCards = new ArrayList<>(cards.getCards(game));
|
||||
while (!target.isChosen() && !possibleCards.isEmpty()) {
|
||||
while (!target.isChosen(game) && !possibleCards.isEmpty()) {
|
||||
Card pick = pickTarget(abilityControllerId, possibleCards, outcome, target, source, game);
|
||||
if (pick != null) {
|
||||
target.addTarget(pick.getId(), source, game);
|
||||
possibleCards.remove(pick);
|
||||
}
|
||||
}
|
||||
return target.isChosen();
|
||||
return target.isChosen(game);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Target wasn't handled in computer's chooseTarget method: " + target.getClass().getCanonicalName());
|
||||
|
|
@ -2063,7 +2063,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
|
||||
// we still use playerId when getting cards even if they don't control the search
|
||||
List<Card> cardChoices = new ArrayList<>(cards.getCards(target.getFilter(), playerId, source, game));
|
||||
while (!target.doneChoosing()) {
|
||||
while (!target.doneChoosing(game)) {
|
||||
Card card = pickTarget(abilityControllerId, cardChoices, outcome, target, source, game);
|
||||
if (card != null) {
|
||||
target.addTarget(card.getId(), source, game);
|
||||
|
|
@ -2094,7 +2094,7 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
}
|
||||
|
||||
List<Card> cardChoices = new ArrayList<>(cards.getCards(target.getFilter(), abilityControllerId, source, game));
|
||||
while (!target.doneChoosing()) {
|
||||
while (!target.doneChoosing(game)) {
|
||||
Card card = pickTarget(abilityControllerId, cardChoices, outcome, target, source, game);
|
||||
if (card != null) {
|
||||
target.add(card.getId(), game);
|
||||
|
|
|
|||
|
|
@ -674,7 +674,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), possibleTargetIds, required, getOptions(target, options));
|
||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(game), getRelatedObjectName(source, game)), possibleTargetIds, required, getOptions(target, options));
|
||||
}
|
||||
waitForResponse(game);
|
||||
responseId = getFixedResponseUUID(game);
|
||||
|
|
@ -696,7 +696,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
if (target instanceof TargetPermanent) {
|
||||
if (((TargetPermanent) target).canTarget(abilityControllerId, responseId, source, game, false)) {
|
||||
target.add(responseId, game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -708,7 +708,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
target.remove(responseId);
|
||||
} else {
|
||||
target.addTarget(responseId, (Ability) object, game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -718,7 +718,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
target.remove(responseId);
|
||||
} else {
|
||||
target.addTarget(responseId, null, game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -775,7 +775,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)),
|
||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(game), getRelatedObjectName(source, game)),
|
||||
possibleTargetIds, required, getOptions(target, options));
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
|
@ -792,7 +792,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
if (possibleTargetIds.contains(responseId)) {
|
||||
if (target.canTarget(abilityControllerId, responseId, source, game)) {
|
||||
target.addTarget(responseId, source, game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -873,7 +873,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage()), cards, required, options);
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(game)), cards, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
|
|
@ -886,7 +886,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
} else {
|
||||
if (target.canTarget(abilityControllerId, responseId, source, cards, game)) {
|
||||
target.add(responseId, game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -956,7 +956,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), cards, required, options);
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(game), getRelatedObjectName(source, game)), cards, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
|
|
@ -968,7 +968,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
target.remove(responseId);
|
||||
} else if (target.canTarget(abilityControllerId, responseId, source, cards, game)) {
|
||||
target.addTarget(responseId, source, game);
|
||||
if (target.doneChoosing()) {
|
||||
if (target.doneChoosing(game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1051,7 +1051,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
String multiType = multiAmountType == MultiAmountType.DAMAGE ? " to divide %d damage" : " to distribute %d counters";
|
||||
String message = target.getMessage() + String.format(multiType, amountTotal);
|
||||
String message = target.getMessage(game) + String.format(multiType, amountTotal);
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(message, getRelatedObjectName(source, game)), possibleTargetIds, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
|
|||
TargetPermanent target = new TargetPermanent(filter);
|
||||
target.withNotTarget(true);
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DamageAllEffect;
|
||||
|
|
@ -17,14 +16,15 @@ import mage.target.Target;
|
|||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Plopman
|
||||
*/
|
||||
public final class BurningOfXinye extends CardImpl {
|
||||
|
||||
public BurningOfXinye(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{R}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
|
||||
|
||||
|
||||
// You destroy four lands you control, then target opponent destroys four lands they control. Then Burning of Xinye deals 4 damage to each creature.
|
||||
|
|
@ -44,7 +44,7 @@ public final class BurningOfXinye extends CardImpl {
|
|||
}
|
||||
|
||||
|
||||
class BurningOfXinyeEffect extends OneShotEffect{
|
||||
class BurningOfXinyeEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent();
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ class BurningOfXinyeEffect extends OneShotEffect{
|
|||
staticText = "You destroy four lands you control, then target opponent destroys four lands they control";
|
||||
}
|
||||
|
||||
public BurningOfXinyeEffect ( BurningOfXinyeEffect effect ) {
|
||||
private BurningOfXinyeEffect(final BurningOfXinyeEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ class BurningOfXinyeEffect extends OneShotEffect{
|
|||
return abilityApplied;
|
||||
}
|
||||
|
||||
private boolean playerDestroys(Game game, Ability source, Player player){
|
||||
private boolean playerDestroys(Game game, Ability source, Player player) {
|
||||
boolean abilityApplied = false;
|
||||
|
||||
int realCount = game.getBattlefield().countAll(filter, player.getId(), game);
|
||||
|
|
@ -82,7 +82,7 @@ class BurningOfXinyeEffect extends OneShotEffect{
|
|||
|
||||
Target target = new TargetControlledPermanent(amount, amount, filter, true);
|
||||
if (amount > 0 && target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
player.choose(Outcome.DestroyPermanent, target, source, game);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -17,11 +16,7 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceCreatureType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
|
@ -30,8 +25,9 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
import mage.target.common.TargetOpponent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class CallousOppressor extends CardImpl {
|
||||
|
|
@ -118,7 +114,7 @@ class CallousOppressorChooseCreatureTypeEffect extends OneShotEffect {
|
|||
if (controller != null) {
|
||||
TargetOpponent target = new TargetOpponent(true);
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -21,14 +18,17 @@ import mage.players.Player;
|
|||
import mage.target.Target;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class Cataclysm extends CardImpl {
|
||||
|
||||
public Cataclysm(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}{W}");
|
||||
|
||||
// Each player chooses from the permanents they control an artifact, a creature, an enchantment, and a land, then sacrifices the rest.
|
||||
this.getSpellAbility().addEffect(new CataclysmEffect());
|
||||
|
|
@ -68,7 +68,7 @@ class CataclysmEffect extends OneShotEffect {
|
|||
Target target4 = new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent(), true);
|
||||
|
||||
if (target1.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target1.isChosen() && target1.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target1.isChosen(game) && target1.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target1, source, game);
|
||||
}
|
||||
Permanent artifact = game.getPermanent(target1.getFirstTarget());
|
||||
|
|
@ -79,7 +79,7 @@ class CataclysmEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target2.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target2.isChosen() && target2.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target2.isChosen(game) && target2.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target2, source, game);
|
||||
}
|
||||
Permanent creature = game.getPermanent(target2.getFirstTarget());
|
||||
|
|
@ -90,7 +90,7 @@ class CataclysmEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target3.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target3.isChosen() && target3.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target3.isChosen(game) && target3.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target3, source, game);
|
||||
}
|
||||
Permanent enchantment = game.getPermanent(target3.getFirstTarget());
|
||||
|
|
@ -101,7 +101,7 @@ class CataclysmEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target4.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target4.isChosen() && target4.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target4.isChosen(game) && target4.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target4, source, game);
|
||||
}
|
||||
Permanent land = game.getPermanent(target4.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
|
|||
Target target4 = new TargetControlledPermanent(1, 1, filterPlaneswalker, true);
|
||||
|
||||
if (target1.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target1.isChosen() && target1.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target1.isChosen(game) && target1.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target1, source, game);
|
||||
}
|
||||
Permanent artifact = game.getPermanent(target1.getFirstTarget());
|
||||
|
|
@ -112,7 +112,7 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target2.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target2.isChosen() && target2.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target2.isChosen(game) && target2.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target2, source, game);
|
||||
}
|
||||
Permanent creature = game.getPermanent(target2.getFirstTarget());
|
||||
|
|
@ -123,7 +123,7 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target3.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target3.isChosen() && target3.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target3.isChosen(game) && target3.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target3, source, game);
|
||||
}
|
||||
Permanent enchantment = game.getPermanent(target3.getFirstTarget());
|
||||
|
|
@ -134,7 +134,7 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target4.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target4.isChosen() && target4.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target4.isChosen(game) && target4.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target4, source, game);
|
||||
}
|
||||
Permanent planeswalker = game.getPermanent(target4.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -26,6 +23,10 @@ import mage.target.Target;
|
|||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class CatchRelease extends SplitCard {
|
||||
|
||||
public CatchRelease(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
|
@ -87,7 +88,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
|
|||
Target target5 = new TargetControlledPermanent(1, 1, new FilterControlledPlaneswalkerPermanent(), true);
|
||||
|
||||
if (target1.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target1.isChosen() && target1.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target1.isChosen(game) && target1.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target1, source, game);
|
||||
}
|
||||
Permanent artifact = game.getPermanent(target1.getFirstTarget());
|
||||
|
|
@ -98,7 +99,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target2.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target2.isChosen() && target2.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target2.isChosen(game) && target2.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target2, source, game);
|
||||
}
|
||||
Permanent creature = game.getPermanent(target2.getFirstTarget());
|
||||
|
|
@ -109,7 +110,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target3.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target3.isChosen() && target3.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target3.isChosen(game) && target3.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target3, source, game);
|
||||
}
|
||||
Permanent enchantment = game.getPermanent(target3.getFirstTarget());
|
||||
|
|
@ -120,7 +121,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target4.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target4.isChosen() && target4.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target4.isChosen(game) && target4.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target4, source, game);
|
||||
}
|
||||
Permanent land = game.getPermanent(target4.getFirstTarget());
|
||||
|
|
@ -131,7 +132,7 @@ class ReleaseSacrificeEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (target5.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target5.isChosen() && target5.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target5.isChosen(game) && target5.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target5, source, game);
|
||||
}
|
||||
Permanent planeswalker = game.getPermanent(target5.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility;
|
||||
|
|
@ -10,7 +9,10 @@ import mage.abilities.effects.OneShotEffect;
|
|||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
|
|
@ -20,8 +22,9 @@ import mage.target.Target;
|
|||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class Clambassadors extends CardImpl {
|
||||
|
|
@ -82,7 +85,7 @@ class ClambassadorsEffect extends OneShotEffect {
|
|||
if (controller != null) {
|
||||
Target target = new TargetControlledPermanent(1, 1, filter, true);
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,16 @@ import mage.constants.TargetController;
|
|||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author anonymous
|
||||
*/
|
||||
public final class CurseOfTheCabal extends CardImpl {
|
||||
|
|
@ -87,7 +84,7 @@ class CurseOfTheCabalSacrificeEffect extends OneShotEffect {
|
|||
}
|
||||
Target target = new TargetSacrifice(amount, StaticFilters.FILTER_CONTROLLED_PERMANENT);
|
||||
if (target.canChoose(targetPlayer.getId(), source, game)) {
|
||||
while (!target.isChosen()
|
||||
while (!target.isChosen(game)
|
||||
&& target.canChoose(targetPlayer.getId(), source, game) && targetPlayer.canRespond()) {
|
||||
targetPlayer.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import mage.target.common.TargetSacrifice;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class DevourFlesh extends CardImpl {
|
||||
|
|
@ -65,7 +64,7 @@ class DevourFleshSacrificeEffect extends OneShotEffect {
|
|||
}
|
||||
if (game.getBattlefield().count(TargetSacrifice.makeFilter(StaticFilters.FILTER_PERMANENT_CREATURE), player.getId(), source, game) > 0) {
|
||||
Target target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE);
|
||||
while (player.canRespond() && !target.isChosen() && target.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target.isChosen(game) && target.canChoose(player.getId(), source, game)) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -22,6 +18,10 @@ import mage.players.Player;
|
|||
import mage.target.Target;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
|
|
@ -68,7 +68,7 @@ class DivineReckoningEffect extends OneShotEffect {
|
|||
if (player != null) {
|
||||
Target target = new TargetControlledPermanent(1, 1, new FilterControlledCreaturePermanent(), true);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target.isChosen() && target.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target.isChosen(game) && target.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.Benefit, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class DrainPowerEffect extends OneShotEffect {
|
|||
FilterLandPermanent filter2 = new FilterLandPermanent("land you control to tap for mana (remaining: " + permList.size() + ')');
|
||||
filter2.add(new PermanentReferenceInCollectionPredicate(permList, game));
|
||||
target = new TargetPermanent(1, 1, filter2, true);
|
||||
while (!target.isChosen() && target.canChoose(targetPlayer.getId(), source, game) && targetPlayer.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(targetPlayer.getId(), source, game) && targetPlayer.canRespond()) {
|
||||
targetPlayer.chooseTarget(Outcome.Neutral, target, source, game);
|
||||
}
|
||||
permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import mage.target.common.TargetSacrifice;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public final class EntrapmentManeuver extends CardImpl {
|
||||
|
|
@ -67,7 +66,7 @@ class EntrapmentManeuverSacrificeEffect extends OneShotEffect {
|
|||
}
|
||||
if (game.getBattlefield().count(TargetSacrifice.makeFilter(StaticFilters.FILTER_ATTACKING_CREATURE), player.getId(), source, game) > 0) {
|
||||
Target target = new TargetSacrifice(StaticFilters.FILTER_ATTACKING_CREATURE);
|
||||
while (player.canRespond() && !target.isChosen() && target.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target.isChosen(game) && target.canChoose(player.getId(), source, game)) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class EunuchsIntriguesEffect extends OneShotEffect {
|
|||
filter.add(new ControllerIdPredicate(player.getId()));
|
||||
Target target = new TargetPermanent(1, 1, filter, true);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
player.chooseTarget(Outcome.DestroyPermanent, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import java.util.Objects;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author notgreat
|
||||
*/
|
||||
public final class FabricationFoundry extends CardImpl {
|
||||
|
|
@ -96,6 +95,7 @@ enum ArtifactSpellOrActivatedAbilityCondition implements Condition {
|
|||
return object != null && object.isArtifact(game) && !source.isActivated();
|
||||
}
|
||||
}
|
||||
|
||||
//Cost based on Kozilek, The Great Distortion and CrewAbility
|
||||
class ExileTargetsTotalManaValueCost extends CostImpl {
|
||||
private static final FilterPermanent filter = new FilterControlledArtifactPermanent("one or more other artifacts you control with total mana value X");
|
||||
|
|
@ -103,6 +103,7 @@ class ExileTargetsTotalManaValueCost extends CostImpl {
|
|||
static {
|
||||
filter.add(AnotherPredicate.instance);
|
||||
}
|
||||
|
||||
public ExileTargetsTotalManaValueCost() {
|
||||
this.text = "Exile one or more other artifacts you control with total mana value X";
|
||||
}
|
||||
|
|
@ -123,9 +124,9 @@ class ExileTargetsTotalManaValueCost extends CostImpl {
|
|||
}
|
||||
int minX = abilityTarget.getManaValue();
|
||||
int sum = 0;
|
||||
Target target = new TargetPermanent(1, Integer.MAX_VALUE, filter, true){
|
||||
Target target = new TargetPermanent(1, Integer.MAX_VALUE, filter, true) {
|
||||
@Override
|
||||
public String getMessage() {
|
||||
public String getMessage(Game game) {
|
||||
// shows selected mana value
|
||||
int selectedPower = this.targets.keySet().stream()
|
||||
.map(game::getPermanent)
|
||||
|
|
@ -136,10 +137,10 @@ class ExileTargetsTotalManaValueCost extends CostImpl {
|
|||
if (selectedPower >= minX) {
|
||||
extraInfo = HintUtils.prepareText(extraInfo, Color.GREEN);
|
||||
}
|
||||
return super.getMessage() + " " + extraInfo;
|
||||
return super.getMessage(game) + " " + extraInfo;
|
||||
}
|
||||
};
|
||||
if (!target.choose(Outcome.Exile, controllerId, source.getSourceId(), source, game)){
|
||||
if (!target.choose(Outcome.Exile, controllerId, source.getSourceId(), source, game)) {
|
||||
return paid;
|
||||
}
|
||||
Cards cards = new CardsImpl();
|
||||
|
|
@ -152,7 +153,7 @@ class ExileTargetsTotalManaValueCost extends CostImpl {
|
|||
}
|
||||
paid = (sum >= minX);
|
||||
if (paid) {
|
||||
player.moveCardsToExile(cards.getCards(game), source, game, false,null,null);
|
||||
player.moveCardsToExile(cards.getCards(game), source, game, false, null, null);
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
|
@ -161,12 +162,12 @@ class ExileTargetsTotalManaValueCost extends CostImpl {
|
|||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||
int totalExileMV = 0;
|
||||
boolean anyExileFound = false;
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, controllerId, source, game)){
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, controllerId, source, game)) {
|
||||
totalExileMV += permanent.getManaValue();
|
||||
anyExileFound = true;
|
||||
}
|
||||
int minTargetMV = Integer.MAX_VALUE;
|
||||
for (Card card : game.getPlayer(controllerId).getGraveyard().getCards(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD, game)){
|
||||
for (Card card : game.getPlayer(controllerId).getGraveyard().getCards(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD, game)) {
|
||||
minTargetMV = Integer.min(minTargetMV, card.getManaValue());
|
||||
}
|
||||
return anyExileFound && totalExileMV >= minTargetMV;
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class FalseOrdersUnblockEffect extends OneShotEffect {
|
|||
TargetPermanent target = new TargetPermanent(filter);
|
||||
target.withNotTarget(true);
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -143,9 +143,9 @@ class FireballTargetCreatureOrPlayer extends TargetAnyTarget {
|
|||
chosen = true;
|
||||
}
|
||||
|
||||
if (!target.isChosen()) {
|
||||
if (!target.isChosen(game)) {
|
||||
Iterator<UUID> it2 = possibleTargets.iterator();
|
||||
while (it2.hasNext() && !target.isChosen()) {
|
||||
while (it2.hasNext() && !target.isChosen(game)) {
|
||||
UUID nextTargetId = it2.next();
|
||||
target.addTarget(nextTargetId, source, game, true);
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ class FireballTargetCreatureOrPlayer extends TargetAnyTarget {
|
|||
|
||||
}
|
||||
}
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
options.add(target);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
|
|
@ -21,14 +19,15 @@ import mage.target.common.TargetAnyTarget;
|
|||
import mage.target.common.TargetOpponent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class GoblinFestival extends CardImpl {
|
||||
|
||||
public GoblinFestival(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
|
||||
|
||||
// {2}: Goblin Festival deals 1 damage to any target. Flip a coin. If you lose the flip, choose one of your opponents. That player gains control of Goblin Festival.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl<>("{2}"));
|
||||
|
|
@ -72,7 +71,7 @@ class GoblinFestivalChangeControlEffect extends OneShotEffect {
|
|||
if (sourcePermanent != null) {
|
||||
Target target = new TargetOpponent(true);
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class GoblinWarCryEffect extends OneShotEffect {
|
|||
filter.add(new ControllerIdPredicate(player.getId()));
|
||||
Target target = new TargetPermanent(1, 1, filter, true);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
player.chooseTarget(Outcome.DestroyPermanent, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.i;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -17,8 +16,9 @@ import mage.target.Target;
|
|||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class ImperialEdict extends CardImpl {
|
||||
|
|
@ -67,7 +67,7 @@ class ImperialEdictEffect extends OneShotEffect {
|
|||
filter.add(new ControllerIdPredicate(player.getId()));
|
||||
Target target = new TargetPermanent(1, 1, filter, true);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
player.chooseTarget(Outcome.DestroyPermanent, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
|
||||
package mage.cards.j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
|
|
@ -15,11 +11,7 @@ import mage.cards.Card;
|
|||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
import mage.game.Game;
|
||||
|
|
@ -31,14 +23,18 @@ import mage.target.TargetPermanent;
|
|||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class JalumGrifter extends CardImpl {
|
||||
|
||||
public JalumGrifter(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.DEVIL);
|
||||
this.power = new MageInt(3);
|
||||
|
|
@ -95,12 +91,12 @@ class JalumGrifterEffect extends OneShotEffect {
|
|||
|
||||
Target target = new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent(), true);
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
}
|
||||
|
||||
for (UUID cardId: target.getTargets()) {
|
||||
for (UUID cardId : target.getTargets()) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
card = card.copy();
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class LegateLaniusCaesarsAceSacrificeEffect extends OneShotEffect {
|
|||
continue;
|
||||
}
|
||||
TargetSacrifice target = new TargetSacrifice(numTargets, filter);
|
||||
while (!target.isChosen() && target.canChoose(playerId, source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(playerId, source, game) && player.canRespond()) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
perms.addAll(target.getTargets());
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
package mage.cards.l;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
|
|
@ -11,11 +8,7 @@ import mage.abilities.effects.OneShotEffect;
|
|||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPlayer;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.other.PlayerIdPredicate;
|
||||
|
|
@ -25,14 +18,17 @@ import mage.players.Player;
|
|||
import mage.target.TargetPlayer;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class LoxodonPeacekeeper extends CardImpl {
|
||||
|
||||
public LoxodonPeacekeeper(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
|
||||
this.subtype.add(SubType.ELEPHANT);
|
||||
this.subtype.add(SubType.SOLDIER);
|
||||
this.power = new MageInt(4);
|
||||
|
|
@ -105,7 +101,7 @@ class LoxodonPeacekeeperEffect extends OneShotEffect {
|
|||
}
|
||||
TargetPlayer target = new TargetPlayer(1, 1, true, filter);
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public final class LunarHatchling extends CardImpl {
|
|||
// Escape-{4}{G}{U}, Exile a land you control, Exile five other cards from your graveyard.
|
||||
CostsImpl<Cost> additionalCost = new CostsImpl();
|
||||
additionalCost.add(new ExileTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_A_LAND)));
|
||||
this.addAbility(new EscapeAbility(this, "{4}{G}{U}", 5, additionalCost));
|
||||
this.addAbility(new EscapeAbility(this, "{4}{G}{U}", additionalCost, 5));
|
||||
}
|
||||
|
||||
private LunarHatchling(final LunarHatchling card) {
|
||||
|
|
|
|||
128
Mage.Sets/src/mage/cards/n/Nethergoyf.java
Normal file
128
Mage.Sets/src/mage/cards/n/Nethergoyf.java
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
package mage.cards.n;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostsImpl;
|
||||
import mage.abilities.costs.common.ExileFromGraveCost;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount;
|
||||
import mage.abilities.effects.common.continuous.SetBasePowerToughnessPlusOneSourceEffect;
|
||||
import mage.abilities.hint.HintUtils;
|
||||
import mage.abilities.keyword.EscapeAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class Nethergoyf extends CardImpl {
|
||||
|
||||
private static final DynamicValue powerValue = CardTypesInGraveyardCount.YOU;
|
||||
|
||||
public Nethergoyf(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
|
||||
|
||||
this.subtype.add(SubType.LHURGOYF);
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// Nethergoyf's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue)));
|
||||
|
||||
// Escape--{2}{B}, Exile any number of other cards from your graveyard with four or more card types among them.
|
||||
CostsImpl<Cost> additionalCost = new CostsImpl();
|
||||
additionalCost.add(new ExileFromGraveCost(
|
||||
new NethergoyfTarget(),
|
||||
"exile any number of other cards from your graveyard with four or more card types among them")
|
||||
);
|
||||
this.addAbility(new EscapeAbility(this, "{2}{B}", additionalCost));
|
||||
}
|
||||
|
||||
private Nethergoyf(final Nethergoyf card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nethergoyf copy() {
|
||||
return new Nethergoyf(this);
|
||||
}
|
||||
}
|
||||
|
||||
class NethergoyfTarget extends TargetCardInYourGraveyard {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("other cards from your graveyard with four or more card types among them");
|
||||
|
||||
static {
|
||||
filter.add(AnotherPredicate.instance);
|
||||
}
|
||||
|
||||
NethergoyfTarget() {
|
||||
super(1, Integer.MAX_VALUE, filter, true);
|
||||
}
|
||||
|
||||
private NethergoyfTarget(final NethergoyfTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NethergoyfTarget copy() {
|
||||
return new NethergoyfTarget(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChosen(Game game) {
|
||||
return super.isChosen(game) && metCondition(this.getTargets(), game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage(Game game) {
|
||||
String text = "Select " + CardUtil.addArticle(targetName);
|
||||
Set<CardType> types = typesAmongSelection(this.getTargets(), game);
|
||||
text += " (selected " + this.getTargets().size() + " cards; card types: ";
|
||||
text += HintUtils.prepareText(
|
||||
types.size() + " of 4",
|
||||
types.size() >= 4 ? Color.GREEN : Color.RED
|
||||
);
|
||||
text += " [" + types.stream().map(CardType::toString).collect(Collectors.joining(", ")) + "])";
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChoose(UUID sourceControllerId, Ability source, Game game) {
|
||||
if (!super.canChoose(sourceControllerId, source, game)) {
|
||||
return false;
|
||||
}
|
||||
// Check that exiling all the possible cards would have >= 4 different card types
|
||||
return metCondition(this.possibleTargets(sourceControllerId, source, game), game);
|
||||
}
|
||||
|
||||
private static Set<CardType> typesAmongSelection(Collection<UUID> cardsIds, Game game) {
|
||||
return cardsIds
|
||||
.stream()
|
||||
.map(game::getCard)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(c -> c.getCardType(game).stream())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static boolean metCondition(Collection<UUID> cardsIds, Game game) {
|
||||
return typesAmongSelection(cardsIds, game).size() >= 4;
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ enum NotOfThisWorldCondition implements Condition {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
StackObject sourceSpell = game.getStack().getStackObject(source.getSourceId());
|
||||
if (sourceSpell == null || !sourceSpell.getStackAbility().getTargets().isChosen()) {
|
||||
if (sourceSpell == null || !sourceSpell.getStackAbility().getTargets().isChosen(game)) {
|
||||
return false;
|
||||
}
|
||||
StackObject objectToCounter = game.getStack().getStackObject(sourceSpell.getStackAbility().getTargets().getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -12,12 +12,9 @@ import mage.constants.CardType;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
|
|
@ -88,7 +85,7 @@ class PlaguecrafterEffect extends OneShotEffect {
|
|||
}
|
||||
TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_PERMANENT_CREATURE_OR_PLANESWALKER);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && player.canRespond()) {
|
||||
while (!target.isChosen(game) && player.canRespond()) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
perms.addAll(target.getTargets());
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
|
||||
package mage.cards.r;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -18,8 +15,11 @@ import mage.players.Player;
|
|||
import mage.target.Target;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public final class RaziasPurification extends CardImpl {
|
||||
|
|
@ -63,7 +63,7 @@ class RaziasPurificationEffect extends OneShotEffect {
|
|||
|
||||
if (player != null && target1.canChoose(player.getId(), source, game)) {
|
||||
int chosenPermanents = 0;
|
||||
while (player.canRespond() && !target1.isChosen() && target1.canChoose(player.getId(), source, game) && chosenPermanents < 3) {
|
||||
while (player.canRespond() && !target1.isChosen(game) && target1.canChoose(player.getId(), source, game) && chosenPermanents < 3) {
|
||||
player.chooseTarget(Outcome.Benefit, target1, source, game);
|
||||
for (UUID targetId : target1.getTargets()) {
|
||||
Permanent p = game.getPermanent(targetId);
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class ReignOfThePitEffect extends OneShotEffect {
|
|||
if (player != null) {
|
||||
TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && player.canRespond()) {
|
||||
while (!target.isChosen(game) && player.canRespond()) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
perms.addAll(target.getTargets());
|
||||
|
|
|
|||
|
|
@ -147,14 +147,14 @@ class RiskyMoveFlipCoinEffect extends OneShotEffect {
|
|||
Target target2 = new TargetOpponent(true);
|
||||
|
||||
if (target1.canChoose(controller.getId(), source, game)) {
|
||||
while (!target1.isChosen()
|
||||
while (!target1.isChosen(game)
|
||||
&& target1.canChoose(controller.getId(), source, game)
|
||||
&& controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target1, source, game);
|
||||
}
|
||||
}
|
||||
if (target2.canChoose(controller.getId(), source, game)) {
|
||||
while (!target2.isChosen()
|
||||
while (!target2.isChosen(game)
|
||||
&& target2.canChoose(controller.getId(), source, game)
|
||||
&& controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target2, source, game);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.r;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DamageEverythingEffect;
|
||||
|
|
@ -11,24 +10,23 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.AbilityPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class Rupture extends CardImpl {
|
||||
|
||||
public Rupture(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
|
||||
|
||||
// Sacrifice a creature. Rupture deals damage equal to that creature's power to each creature without flying and each player.
|
||||
this.getSpellAbility().addEffect(new RuptureEffect());
|
||||
|
|
@ -68,7 +66,7 @@ class RuptureEffect extends OneShotEffect {
|
|||
int power = 0;
|
||||
TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -13,16 +12,14 @@ import mage.constants.Outcome;
|
|||
import mage.constants.TargetController;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class Smokestack extends CardImpl {
|
||||
|
|
@ -75,7 +72,7 @@ class SmokestackEffect extends OneShotEffect {
|
|||
//A spell or ability could have removed the only legal target this player
|
||||
//had, if thats the case this ability should fizzle.
|
||||
if (target.canChoose(activePlayer.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(activePlayer.getId(), source, game) && activePlayer.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(activePlayer.getId(), source, game) && activePlayer.canRespond()) {
|
||||
activePlayer.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -22,8 +21,9 @@ import mage.players.Player;
|
|||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class SpyNetwork extends CardImpl {
|
||||
|
|
@ -109,7 +109,7 @@ class SpyNetworkFaceDownEffect extends OneShotEffect {
|
|||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (controller.chooseUse(outcome, "Look at a face down creature controlled by " + player.getLogName() + "?", source, game)) {
|
||||
target.clearChosen();
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
Permanent faceDownCreature = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -16,8 +15,9 @@ import mage.players.Player;
|
|||
import mage.target.Target;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class SunkenHope extends CardImpl {
|
||||
|
|
@ -66,7 +66,7 @@ class SunkenHopeReturnToHandEffect extends OneShotEffect {
|
|||
|
||||
Target target = new TargetControlledCreaturePermanent().withNotTarget(true);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (player.canRespond() && !target.isChosen()
|
||||
while (player.canRespond() && !target.isChosen(game)
|
||||
&& target.canChoose(player.getId(), source, game)) {
|
||||
player.chooseTarget(Outcome.ReturnToHand, target, source, game);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,19 @@
|
|||
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SagaAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.abilities.effects.common.DamageAllEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.constants.SubType;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SagaChapter;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
|
|
@ -24,11 +23,11 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TheFirstEruption extends CardImpl {
|
||||
|
|
@ -101,7 +100,7 @@ class TheFirstEruptionEffect extends OneShotEffect {
|
|||
Target target = new TargetSacrifice(filter);
|
||||
boolean sacrificed = false;
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (controller.canRespond() && !target.isChosen() && target.canChoose(controller.getId(), source, game)) {
|
||||
while (controller.canRespond() && !target.isChosen(game) && target.canChoose(controller.getId(), source, game)) {
|
||||
controller.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ class UrzaAcademyHeadmasterRandomEffect extends OneShotEffect {
|
|||
}
|
||||
source.addTarget(target);
|
||||
}
|
||||
if (target == null || target.isChosen()) {
|
||||
if (target == null || target.isChosen(game)) {
|
||||
for (Effect effect : effects) {
|
||||
if (effect instanceof ContinuousEffect) {
|
||||
game.addEffect((ContinuousEffect) effect, source);
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ class VodalianWarMachineWatcher extends Watcher {
|
|||
for (Cost cost : ability.getCosts()) {
|
||||
if (cost instanceof TapTargetCost && cost.isPaid()) {
|
||||
TapTargetCost tapCost = (TapTargetCost) cost;
|
||||
if (tapCost.getTarget().isChosen()) {
|
||||
if (tapCost.getTarget().isChosen(game)) {
|
||||
MageObjectReference mor = new MageObjectReference(sourcePermanent.getId(), sourcePermanent.getZoneChangeCounter(game), game);
|
||||
Set<MageObjectReference> toAdd;
|
||||
if (tappedMerfolkIds.get(mor) == null) {
|
||||
|
|
|
|||
|
|
@ -10,15 +10,12 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.FoodToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -26,7 +23,6 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class VoraciousFellBeast extends CardImpl {
|
||||
|
|
@ -91,7 +87,7 @@ class VoraciousFellBeastEffect extends OneShotEffect {
|
|||
|
||||
TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && player.canRespond()) {
|
||||
while (!target.isChosen(game) && player.canRespond()) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
perms.addAll(target.getTargets());
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
|
||||
package mage.cards.w;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.game.Game;
|
||||
|
|
@ -20,8 +19,9 @@ import mage.target.Target;
|
|||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class WeiAssassins extends CardImpl {
|
||||
|
|
@ -77,7 +77,7 @@ class WeiAssassinsEffect extends OneShotEffect {
|
|||
filter.add(new ControllerIdPredicate(player.getId()));
|
||||
Target target = new TargetPermanent(1, 1, filter, true);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
player.chooseTarget(Outcome.DestroyPermanent, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ import mage.filter.common.FilterControlledPermanent;
|
|||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
|
||||
import java.util.*;
|
||||
|
|
@ -119,7 +117,7 @@ class WorldQuellerEffect extends OneShotEffect {
|
|||
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||
Player player2 = game.getPlayer(playerId);
|
||||
if (player2 != null && target.canChoose(playerId, source, game)) {
|
||||
while (player2.canRespond() && !target.isChosen() && target.canChoose(playerId, source, game)) {
|
||||
while (player2.canRespond() && !target.isChosen(game) && target.canChoose(playerId, source, game)) {
|
||||
player2.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public final class ModernHorizons3 extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Laelia, the Blade Reforged", 281, Rarity.RARE, mage.cards.l.LaeliaTheBladeReforged.class));
|
||||
cards.add(new SetCardInfo("Meltdown", 282, Rarity.UNCOMMON, mage.cards.m.Meltdown.class));
|
||||
cards.add(new SetCardInfo("Mountain", 307, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nethergoyf", 103, Rarity.MYTHIC, mage.cards.n.Nethergoyf.class));
|
||||
cards.add(new SetCardInfo("Null Elemental Blast", 12, Rarity.UNCOMMON, mage.cards.n.NullElementalBlast.class));
|
||||
cards.add(new SetCardInfo("Nulldrifter", 13, Rarity.RARE, mage.cards.n.Nulldrifter.class));
|
||||
cards.add(new SetCardInfo("Orim's Chant", 265, Rarity.RARE, mage.cards.o.OrimsChant.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,193 @@
|
|||
package org.mage.test.cards.single.mh3;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public class NethergoyfTest extends CardTestPlayerBaseWithAIHelps {
|
||||
|
||||
/**
|
||||
* {@link mage.cards.n.Nethergoyf Nethergoyf} {B}
|
||||
* Creature — Lhurgoyf
|
||||
* Nethergoyf’s power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1.
|
||||
* Escape—{2}{B}, Exile any number of other cards from your graveyard with four or more card types among them. (You may cast this card from your graveyard for its escape cost.)
|
||||
* * / 1+*
|
||||
*/
|
||||
private static final String nethergoyf = "Nethergoyf";
|
||||
|
||||
@Test
|
||||
public void test_Escape_Two_DualTypes() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, nethergoyf);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Memnite"); // Creature Artifact
|
||||
addCard(Zone.GRAVEYARD, playerA, "Bitterblossom"); // Tribal Enchantment
|
||||
|
||||
checkPlayableAbility("can escape", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nethergoyf + " with Escape", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nethergoyf + " with Escape");
|
||||
setChoice(playerA, "Memnite^Bitterblossom"); // cards exiled for escape cost
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, nethergoyf, 1);
|
||||
assertPowerToughness(playerA, nethergoyf, 0, 1);
|
||||
assertExileCount(playerA, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_AI_Escape_Two_DualTypes() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, nethergoyf);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Memnite"); // Creature Artifact
|
||||
addCard(Zone.GRAVEYARD, playerA, "Bitterblossom"); // Tribal Enchantment
|
||||
|
||||
checkPlayableAbility("can escape", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nethergoyf + " with Escape", true);
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, nethergoyf, 1);
|
||||
assertPowerToughness(playerA, nethergoyf, 0, 1);
|
||||
assertExileCount(playerA, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Escape_MoreCardsThanNeeded() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, nethergoyf);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Memnite", 5); // Creature Artifact
|
||||
addCard(Zone.GRAVEYARD, playerA, "Bitterblossom"); // Tribal Enchantment
|
||||
|
||||
checkPlayableAbility("can escape", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nethergoyf + " with Escape", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nethergoyf + " with Escape");
|
||||
setChoice(playerA, "Memnite^Memnite^Memnite^Memnite^Bitterblossom"); // cards exiled for escape cost: Exile all the Memnite but one.
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, nethergoyf, 1);
|
||||
assertPowerToughness(playerA, nethergoyf, 2, 3); // 1 Memnite in graveyard
|
||||
assertExileCount(playerA, 5);
|
||||
assertGraveyardCount(playerA, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_AI_Escape_MoreCardsThanNeeded() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, nethergoyf);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Bitterblossom"); // Tribal Enchantment
|
||||
addCard(Zone.GRAVEYARD, playerA, "Memnite", 5); // Creature Artifact
|
||||
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, nethergoyf, 1);
|
||||
assertPowerToughness(playerA, nethergoyf, 0, 1);
|
||||
assertExileCount(playerA, 6); // It is weird, but AI likes to choose all to be exiled, even though the Outcome is Exile (so detriment)
|
||||
assertGraveyardCount(playerA, 0);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test_CantEscape_Without4TypesInGraveyard() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, nethergoyf);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Taiga"); // Land
|
||||
addCard(Zone.GRAVEYARD, playerA, "Bitterblossom"); // Tribal Enchantment
|
||||
|
||||
checkPlayableAbility("can't escape", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nethergoyf + " with Escape", false);
|
||||
// 3 types from other cards in graveyard, Nethergoyf can't escape
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_AI_CantEscape_Without4TypesInGraveyard() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, nethergoyf);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Taiga"); // Land
|
||||
addCard(Zone.GRAVEYARD, playerA, "Bitterblossom"); // Tribal Enchantment
|
||||
|
||||
checkPlayableAbility("can't escape", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nethergoyf + " with Escape", false);
|
||||
// 3 types from other cards in graveyard, Nethergoyf can't escape
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_DynamicGameType() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, nethergoyf);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Underground Sea", 7);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Taiga"); // Land
|
||||
addCard(Zone.GRAVEYARD, playerA, "Grist, the Hunger Tide"); // Planeswalker, is a Creature if not in play
|
||||
// Nonland permanents you control are artifacts in addition to their other types.
|
||||
// The same is true for permanent spells you control and nonland permanent cards you own that aren’t on the battlefield.
|
||||
addCard(Zone.HAND, playerA, "Encroaching Mycosynth");
|
||||
|
||||
checkPlayableAbility("1: can't escape", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nethergoyf + " with Escape", false);
|
||||
// 3 types from other cards in graveyard, Nethergoyf can't escape
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Encroaching Mycosynth", true);
|
||||
// After Mycosynth in play, Grist is now an Artifact in addition to its other types
|
||||
checkPlayableAbility("2: can", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nethergoyf + " with Escape", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nethergoyf + " with Escape");
|
||||
setChoice(playerA, "Taiga^Grist, the Hunger Tide"); // cards exiled for escape cost
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, nethergoyf, 1);
|
||||
assertPowerToughness(playerA, nethergoyf, 0, 1);
|
||||
assertExileCount(playerA, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_AI_DynamicGameType() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, nethergoyf);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Underground Sea", 7);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Taiga"); // Land
|
||||
addCard(Zone.GRAVEYARD, playerA, "Grist, the Hunger Tide"); // Planeswalker, is a Creature if not in play
|
||||
|
||||
// Nonland permanents you control are artifacts in addition to their other types.
|
||||
// The same is true for permanent spells you control and nonland permanent cards you own that aren’t on the battlefield.
|
||||
addCard(Zone.HAND, playerA, "Encroaching Mycosynth");
|
||||
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, nethergoyf, 1);
|
||||
assertPowerToughness(playerA, nethergoyf, 0, 1);
|
||||
assertExileCount(playerA, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -2001,8 +2001,8 @@ public class TestPlayer implements Player {
|
|||
return "Ability: null";
|
||||
}
|
||||
|
||||
private String getInfo(Target o) {
|
||||
return "Target: " + (o != null ? o.getClass().getSimpleName() + ": " + o.getMessage() : "null");
|
||||
private String getInfo(Target o, Game game) {
|
||||
return "Target: " + (o != null ? o.getClass().getSimpleName() + ": " + o.getMessage(game) : "null");
|
||||
}
|
||||
|
||||
private void assertAliasSupportInChoices(boolean methodSupportAliases) {
|
||||
|
|
@ -2167,7 +2167,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
// ignore player select
|
||||
if (target.getMessage().equals("Select a starting player")) {
|
||||
if (target.getMessage(game).equals("Select a starting player")) {
|
||||
return computerPlayer.choose(outcome, target, source, game, options);
|
||||
}
|
||||
|
||||
|
|
@ -2317,7 +2317,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
// apply only on ALL targets or revert
|
||||
if (usedChoices.size() > 0) {
|
||||
if (target.isChosen()) {
|
||||
if (target.isChosen(game)) {
|
||||
// remove all used choices
|
||||
for (int i = choices.size(); i >= 0; i--) {
|
||||
if (usedChoices.contains(i)) {
|
||||
|
|
@ -2369,7 +2369,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
this.chooseStrictModeFailed("choice", game, getInfo(source, game) + "\n" + getInfo(target));
|
||||
this.chooseStrictModeFailed("choice", game, getInfo(source, game) + "\n" + getInfo(target, game));
|
||||
return computerPlayer.choose(outcome, target, source, game, options);
|
||||
}
|
||||
|
||||
|
|
@ -2690,19 +2690,19 @@ public class TestPlayer implements Player {
|
|||
message = this.getName() + " - Targets list was setup by addTarget with " + targets + ", but not used"
|
||||
+ "\nCard: " + source.getSourceObject(game)
|
||||
+ "\nAbility: " + source.getClass().getSimpleName() + " (" + source.getRule() + ")"
|
||||
+ "\nTarget: " + target.getClass().getSimpleName() + " (" + target.getMessage() + ")"
|
||||
+ "\nTarget: " + target.getClass().getSimpleName() + " (" + target.getMessage(game) + ")"
|
||||
+ "\nYou must implement target class support in TestPlayer, \"filter instanceof\", or setup good targets";
|
||||
} else {
|
||||
message = this.getName() + " - Targets list was setup by addTarget with " + targets + ", but not used"
|
||||
+ "\nCard: unknown source"
|
||||
+ "\nAbility: unknown source"
|
||||
+ "\nTarget: " + target.getClass().getSimpleName() + " (" + target.getMessage() + ")"
|
||||
+ "\nTarget: " + target.getClass().getSimpleName() + " (" + target.getMessage(game) + ")"
|
||||
+ "\nYou must implement target class support in TestPlayer, \"filter instanceof\", or setup good targets";
|
||||
}
|
||||
Assert.fail(message);
|
||||
}
|
||||
|
||||
this.chooseStrictModeFailed("target", game, getInfo(source, game) + "\n" + getInfo(target));
|
||||
this.chooseStrictModeFailed("target", game, getInfo(source, game) + "\n" + getInfo(target, game));
|
||||
return computerPlayer.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
|
||||
|
|
@ -2748,7 +2748,7 @@ public class TestPlayer implements Player {
|
|||
LOGGER.warn("Wrong target");
|
||||
}
|
||||
|
||||
this.chooseStrictModeFailed("target", game, getInfo(source, game) + "\n" + getInfo(target));
|
||||
this.chooseStrictModeFailed("target", game, getInfo(source, game) + "\n" + getInfo(target, game));
|
||||
return computerPlayer.chooseTarget(outcome, cards, target, source, game);
|
||||
}
|
||||
|
||||
|
|
@ -4134,7 +4134,7 @@ public class TestPlayer implements Player {
|
|||
assertWrongChoiceUsage(choices.size() > 0 ? choices.get(0) : "empty list");
|
||||
}
|
||||
|
||||
this.chooseStrictModeFailed("choice", game, getInfo(source, game) + "\n" + getInfo(target));
|
||||
this.chooseStrictModeFailed("choice", game, getInfo(source, game) + "\n" + getInfo(target, game));
|
||||
return computerPlayer.choose(outcome, cards, target, source, game);
|
||||
}
|
||||
|
||||
|
|
@ -4207,7 +4207,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
this.chooseStrictModeFailed("target", game, getInfo(source, game) + "\n" + getInfo(target));
|
||||
this.chooseStrictModeFailed("target", game, getInfo(source, game) + "\n" + getInfo(target, game));
|
||||
return computerPlayer.chooseTargetAmount(outcome, target, source, game);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public class CollectEvidenceCost extends CostImpl {
|
|||
// TODO: require target to have minimum selected total mana value (requires refactor)
|
||||
Target target = new TargetCardInYourGraveyard(1, Integer.MAX_VALUE) {
|
||||
@Override
|
||||
public String getMessage() {
|
||||
public String getMessage(Game game) {
|
||||
// shows selected mana value
|
||||
int totalMV = this
|
||||
.getTargets()
|
||||
|
|
@ -76,7 +76,7 @@ public class CollectEvidenceCost extends CostImpl {
|
|||
.filter(Objects::nonNull)
|
||||
.mapToInt(MageObject::getManaValue)
|
||||
.sum();
|
||||
return super.getMessage() + HintUtils.prepareText(
|
||||
return super.getMessage(game) + HintUtils.prepareText(
|
||||
" (selected mana value " + totalMV + " of " + amount + ")",
|
||||
totalMV >= amount ? Color.GREEN : Color.RED
|
||||
);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class ExileTargetCost extends CostImpl {
|
|||
this.text = "exile " + target.getDescription();
|
||||
}
|
||||
|
||||
public ExileTargetCost(ExileTargetCost cost) {
|
||||
protected ExileTargetCost(ExileTargetCost cost) {
|
||||
super(cost);
|
||||
for (Permanent permanent : cost.permanents) {
|
||||
this.permanents.add(permanent.copy());
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public class RollPlanarDieEffect extends OneShotEffect {
|
|||
}
|
||||
boolean done = false;
|
||||
while (controller.canRespond() && effect != null && !done) {
|
||||
if (target != null && !target.isChosen() && target.canChoose(controller.getId(), source, game)) {
|
||||
if (target != null && !target.isChosen(game) && target.canChoose(controller.getId(), source, game)) {
|
||||
controller.chooseTarget(Outcome.Benefit, target, source, game);
|
||||
source.addTarget(target);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public class SacrificeAllEffect extends OneShotEffect {
|
|||
|
||||
/**
|
||||
* Each player sacrifices a permanent
|
||||
*
|
||||
* @param filter can be generic, will automatically add article and necessary sacrifice predicates
|
||||
*/
|
||||
public SacrificeAllEffect(FilterPermanent filter) {
|
||||
|
|
@ -35,6 +36,7 @@ public class SacrificeAllEffect extends OneShotEffect {
|
|||
|
||||
/**
|
||||
* Each player sacrifices N permanents
|
||||
*
|
||||
* @param filter can be generic, will automatically add necessary sacrifice predicates
|
||||
*/
|
||||
public SacrificeAllEffect(int amount, FilterPermanent filter) {
|
||||
|
|
@ -43,6 +45,7 @@ public class SacrificeAllEffect extends OneShotEffect {
|
|||
|
||||
/**
|
||||
* Each player sacrifices X permanents
|
||||
*
|
||||
* @param filter can be generic, will automatically add necessary sacrifice predicates
|
||||
*/
|
||||
public SacrificeAllEffect(DynamicValue amount, FilterPermanent filter) {
|
||||
|
|
@ -91,7 +94,7 @@ public class SacrificeAllEffect extends OneShotEffect {
|
|||
continue;
|
||||
}
|
||||
TargetSacrifice target = new TargetSacrifice(numTargets, filter);
|
||||
while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
perms.addAll(target.getTargets());
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public class SacrificeEffect extends OneShotEffect {
|
|||
continue;
|
||||
}
|
||||
TargetSacrifice target = new TargetSacrifice(amount, filter);
|
||||
while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
while (!target.isChosen(game) && target.canChoose(player.getId(), source, game) && player.canRespond()) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
}
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ class CrewCost extends CostImpl {
|
|||
}
|
||||
Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true) {
|
||||
@Override
|
||||
public String getMessage() {
|
||||
public String getMessage(Game game) {
|
||||
// shows selected power
|
||||
int selectedPower = this.targets.keySet().stream()
|
||||
.map(game::getPermanent)
|
||||
|
|
@ -162,7 +162,7 @@ class CrewCost extends CostImpl {
|
|||
if (selectedPower >= value) {
|
||||
extraInfo = HintUtils.prepareText(extraInfo, Color.GREEN);
|
||||
}
|
||||
return super.getMessage() + " " + extraInfo;
|
||||
return super.getMessage(game) + " " + extraInfo;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -32,10 +32,14 @@ public class EscapeAbility extends SpellAbility {
|
|||
private final String staticText;
|
||||
|
||||
public EscapeAbility(Card card, String manaCost, int exileCount) {
|
||||
this(card, manaCost, exileCount, new CostsImpl<>());
|
||||
this(card, manaCost, new CostsImpl<>(), exileCount);
|
||||
}
|
||||
|
||||
public EscapeAbility(Card card, String manaCost, int exileCount, Costs<Cost> additionalCosts) {
|
||||
public EscapeAbility(Card card, String manaCost, Costs<Cost> additionalCost) {
|
||||
this(card, manaCost, additionalCost, 0);
|
||||
}
|
||||
|
||||
public EscapeAbility(Card card, String manaCost, Costs<Cost> additionalCosts, int exileCount) {
|
||||
super(card.getSpellAbility());
|
||||
this.newId();
|
||||
this.setCardName(card.getName() + " with Escape");
|
||||
|
|
@ -45,17 +49,22 @@ public class EscapeAbility extends SpellAbility {
|
|||
this.clearManaCosts();
|
||||
this.clearManaCostsToPay();
|
||||
|
||||
String text = "Escape—" + manaCost;
|
||||
this.addCost(new ManaCostsImpl<>(manaCost));
|
||||
for (Cost cost : additionalCosts) {
|
||||
text += ", " + CardUtil.getTextWithFirstCharUpperCase(cost.getText());
|
||||
this.addCost(cost.copy().setText("")); // hide additional cost text from rules
|
||||
}
|
||||
|
||||
text += ", Exile " + CardUtil.numberToText(exileCount) + " other cards from your graveyard."
|
||||
+ " <i>(You may cast this card from your graveyard for its escape cost.)</i>";
|
||||
if (exileCount > 0) {
|
||||
this.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(exileCount, filter), "")); // hide additional cost text from rules
|
||||
}
|
||||
|
||||
String text = "Escape—" + manaCost;
|
||||
for (Cost cost : additionalCosts) {
|
||||
text += ", " + CardUtil.getTextWithFirstCharUpperCase(cost.getText());
|
||||
}
|
||||
if (exileCount > 0) {
|
||||
text += ", Exile " + CardUtil.numberToText(exileCount) + " other cards from your graveyard";
|
||||
}
|
||||
text += ". <i>(You may cast this card from your graveyard for its escape cost.)</i>";
|
||||
this.staticText = text;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl {
|
|||
&& player.chooseUse(Outcome.Benefit, "Offer a " + filter.getMessage() + " to cast " + spellToCast.getName() + '?', source, game)) {
|
||||
Target target = new TargetSacrifice(filter);
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
if (!target.isChosen()) {
|
||||
if (!target.isChosen(game)) {
|
||||
return false;
|
||||
}
|
||||
game.getState().setValue("offering_" + card.getId(), true);
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class SaddleCost extends CostImpl {
|
|||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true) {
|
||||
@Override
|
||||
public String getMessage() {
|
||||
public String getMessage(Game game) {
|
||||
// shows selected power
|
||||
int selectedPower = this.targets.keySet().stream()
|
||||
.map(game::getPermanent)
|
||||
|
|
@ -125,7 +125,7 @@ class SaddleCost extends CostImpl {
|
|||
if (selectedPower >= value) {
|
||||
extraInfo = HintUtils.prepareText(extraInfo, Color.GREEN);
|
||||
}
|
||||
return super.getMessage() + " " + extraInfo;
|
||||
return super.getMessage(game) + " " + extraInfo;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4349,14 +4349,14 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
List<Ability> options = new ArrayList<>();
|
||||
if (ability.isModal()) {
|
||||
addModeOptions(options, ability, game);
|
||||
} else if (!ability.getTargets().getUnchosen().isEmpty()) {
|
||||
} else if (!ability.getTargets().getUnchosen(game).isEmpty()) {
|
||||
// TODO: Handle other variable costs than mana costs
|
||||
if (!ability.getManaCosts().getVariableCosts().isEmpty()) {
|
||||
addVariableXOptions(options, ability, 0, game);
|
||||
} else {
|
||||
addTargetOptions(options, ability, 0, game);
|
||||
}
|
||||
} else if (!ability.getCosts().getTargets().getUnchosen().isEmpty()) {
|
||||
} else if (!ability.getCosts().getTargets().getUnchosen(game).isEmpty()) {
|
||||
addCostTargetOptions(options, ability, 0, game);
|
||||
}
|
||||
|
||||
|
|
@ -4371,13 +4371,13 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
newOption.getModes().clearSelectedModes();
|
||||
newOption.getModes().addSelectedMode(mode.getId());
|
||||
newOption.getModes().setActiveMode(mode);
|
||||
if (!newOption.getTargets().getUnchosen().isEmpty()) {
|
||||
if (!newOption.getTargets().getUnchosen(game).isEmpty()) {
|
||||
if (!newOption.getManaCosts().getVariableCosts().isEmpty()) {
|
||||
addVariableXOptions(options, newOption, 0, game);
|
||||
} else {
|
||||
addTargetOptions(options, newOption, 0, game);
|
||||
}
|
||||
} else if (!newOption.getCosts().getTargets().getUnchosen().isEmpty()) {
|
||||
} else if (!newOption.getCosts().getTargets().getUnchosen(game).isEmpty()) {
|
||||
addCostTargetOptions(options, newOption, 0, game);
|
||||
} else {
|
||||
options.add(newOption);
|
||||
|
|
@ -4390,7 +4390,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
|
||||
protected void addTargetOptions(List<Ability> options, Ability option, int targetNum, Game game) {
|
||||
for (Target target : option.getTargets().getUnchosen().get(targetNum).getTargetOptions(option, game)) {
|
||||
for (Target target : option.getTargets().getUnchosen(game).get(targetNum).getTargetOptions(option, game)) {
|
||||
Ability newOption = option.copy();
|
||||
if (target instanceof TargetAmount) {
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ import java.util.UUID;
|
|||
*/
|
||||
public interface Target extends Serializable {
|
||||
|
||||
boolean isChosen();
|
||||
boolean isChosen(Game game);
|
||||
|
||||
boolean doneChoosing();
|
||||
boolean doneChoosing(Game game);
|
||||
|
||||
void clearChosen();
|
||||
|
||||
|
|
@ -98,7 +98,10 @@ public interface Target extends Serializable {
|
|||
*/
|
||||
String getDescription();
|
||||
|
||||
String getMessage();
|
||||
/**
|
||||
* @return message displayed on choosing targets (can be dynamically changed on more target selected)
|
||||
*/
|
||||
String getMessage(Game game);
|
||||
|
||||
/**
|
||||
* @return single target name
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ public abstract class TargetAmount extends TargetImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isChosen() {
|
||||
return doneChoosing();
|
||||
public boolean isChosen(Game game) {
|
||||
return doneChoosing(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doneChoosing() {
|
||||
public boolean doneChoosing(Game game) {
|
||||
return amountWasSet
|
||||
&& (remainingAmount == 0
|
||||
|| (getMinNumberOfTargets() < getMaxNumberOfTargets()
|
||||
|
|
@ -104,7 +104,7 @@ public abstract class TargetAmount extends TargetImpl {
|
|||
if (!amountWasSet) {
|
||||
setAmount(source, game);
|
||||
}
|
||||
chosen = isChosen();
|
||||
chosen = isChosen(game);
|
||||
while (remainingAmount > 0) {
|
||||
if (!player.canRespond()) {
|
||||
return chosen;
|
||||
|
|
@ -112,7 +112,7 @@ public abstract class TargetAmount extends TargetImpl {
|
|||
if (!getTargetController(game, playerId).chooseTargetAmount(outcome, this, source, game)) {
|
||||
return chosen;
|
||||
}
|
||||
chosen = isChosen();
|
||||
chosen = isChosen(game);
|
||||
}
|
||||
return chosen;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ public abstract class TargetImpl implements Target {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
public String getMessage(Game game) {
|
||||
// UI choose message
|
||||
String suffix = "";
|
||||
if (this.chooseHint != null) {
|
||||
|
|
@ -215,7 +215,7 @@ public abstract class TargetImpl implements Target {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isChosen() {
|
||||
public boolean isChosen(Game game) {
|
||||
if (getMaxNumberOfTargets() == 0 && getNumberOfTargets() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ public abstract class TargetImpl implements Target {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean doneChoosing() {
|
||||
public boolean doneChoosing(Game game) {
|
||||
return getMaxNumberOfTargets() != 0 && targets.size() == getMaxNumberOfTargets();
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +332,7 @@ public abstract class TargetImpl implements Target {
|
|||
return chosen;
|
||||
}
|
||||
chosen = targets.size() >= getNumberOfTargets();
|
||||
} while (!isChosen() && !doneChoosing());
|
||||
} while (!isChosen(game) && !doneChoosing(game));
|
||||
return chosen;
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +375,7 @@ public abstract class TargetImpl implements Target {
|
|||
}
|
||||
}
|
||||
chosen = targets.size() >= getNumberOfTargets();
|
||||
} while (!isChosen() && !doneChoosing());
|
||||
} while (!isChosen(game) && !doneChoosing(game));
|
||||
|
||||
return chosen;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ public class Targets extends ArrayList<Target> implements Copyable<Targets> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public List<Target> getUnchosen() {
|
||||
return stream().filter(target -> !target.isChosen()).collect(Collectors.toList());
|
||||
public List<Target> getUnchosen(Game game) {
|
||||
return stream().filter(target -> !target.isChosen(game)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void clearChosen() {
|
||||
|
|
@ -47,8 +47,8 @@ public class Targets extends ArrayList<Target> implements Copyable<Targets> {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isChosen() {
|
||||
return stream().allMatch(Target::isChosen);
|
||||
public boolean isChosen(Game game) {
|
||||
return stream().allMatch(t -> t.isChosen(game));
|
||||
}
|
||||
|
||||
public boolean choose(Outcome outcome, UUID playerId, UUID sourceId, Ability source, Game game) {
|
||||
|
|
@ -56,8 +56,8 @@ public class Targets extends ArrayList<Target> implements Copyable<Targets> {
|
|||
if (!canChoose(playerId, source, game)) {
|
||||
return false;
|
||||
}
|
||||
while (!isChosen()) {
|
||||
Target target = this.getUnchosen().get(0);
|
||||
while (!isChosen(game)) {
|
||||
Target target = this.getUnchosen(game).get(0);
|
||||
if (!target.choose(outcome, playerId, sourceId, source, game)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -73,8 +73,8 @@ public class Targets extends ArrayList<Target> implements Copyable<Targets> {
|
|||
}
|
||||
|
||||
//int state = game.bookmarkState();
|
||||
while (!isChosen()) {
|
||||
Target target = this.getUnchosen().get(0);
|
||||
while (!isChosen(game)) {
|
||||
Target target = this.getUnchosen(game).get(0);
|
||||
UUID targetController = playerId;
|
||||
|
||||
// some targets can have controller different than ability controller
|
||||
|
|
@ -97,7 +97,7 @@ public class Targets extends ArrayList<Target> implements Copyable<Targets> {
|
|||
return false;
|
||||
}
|
||||
// Check if there are some rules for targets are violated, if so reset the targets and start again
|
||||
if (this.getUnchosen().isEmpty()
|
||||
if (this.getUnchosen(game).isEmpty()
|
||||
&& game.replaceEvent(new GameEvent(GameEvent.EventType.TARGETS_VALID, source.getSourceId(), source, source.getControllerId()), source)) {
|
||||
//game.restoreState(state, "Targets");
|
||||
clearChosen();
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public class TargetCardInLibrary extends TargetCard {
|
|||
return chosen;
|
||||
}
|
||||
chosen = targets.size() >= getMinNumberOfTargets();
|
||||
} while (!isChosen() && !doneChoosing());
|
||||
} while (!isChosen(game) && !doneChoosing(game));
|
||||
return chosen;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue