- Fixed Soul Strings. DoUnlessAnyPlayerPays now supports X costs.

This commit is contained in:
Jeff 2018-11-20 09:46:36 -06:00
parent 9916dbdad7
commit 1bac7fc04c
5 changed files with 62 additions and 16 deletions

View file

@ -861,6 +861,19 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
return target.isChosen(); return target.isChosen();
} }
if (target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) {
List<Card> cards = new ArrayList<>();
for (Player player : game.getPlayers().values()) {
cards.addAll(player.getGraveyard().getCards(game));
cards.addAll(game.getBattlefield().getAllActivePermanents(new FilterPermanent(), player.getId(), game));
}
Card card = pickTarget(cards, outcome, target, source, game);
if (card != null) {
target.addTarget(card.getId(), source, game);
return true;
}
}
throw new IllegalStateException("Target wasn't handled. class:" + target.getClass().toString()); throw new IllegalStateException("Target wasn't handled. class:" + target.getClass().toString());
} //end of chooseTarget method } //end of chooseTarget method

View file

@ -1,6 +1,5 @@
package mage.cards.s; package mage.cards.s;
import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect; import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
@ -11,6 +10,7 @@ import mage.filter.common.FilterCreatureCard;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID; import java.util.UUID;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
/** /**
* @author jmharmon * @author jmharmon
@ -23,8 +23,7 @@ public final class SoulStrings extends CardImpl {
// Return two target creature cards from your graveyard to your hand unless any player pays {X}. // Return two target creature cards from your graveyard to your hand unless any player pays {X}.
Effect effect = new DoUnlessAnyPlayerPaysEffect( Effect effect = new DoUnlessAnyPlayerPaysEffect(
new ReturnFromGraveyardToHandTargetEffect(), new VariableManaCost() new ReturnFromGraveyardToHandTargetEffect(), new ManacostVariableValue());
);
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(2, new FilterCreatureCard("creature cards from your graveyard"))); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(2, new FilterCreatureCard("creature cards from your graveyard")));
} }

View file

@ -79,7 +79,9 @@ class ViashinoBeyEffect extends OneShotEffect {
} else { } else {
targetDefender.add(game.getOpponents(controller.getId()).iterator().next(), game); targetDefender.add(game.getOpponents(controller.getId()).iterator().next(), game);
} }
controller.declareAttacker(permanent.getId(), targetDefender.getFirstTarget(), game, false); if (permanent.canAttack(targetDefender.getFirstTarget(), game)) {
controller.declareAttacker(permanent.getId(), targetDefender.getFirstTarget(), game, false);
}
}); });
} }
return false; return false;

View file

@ -1,4 +1,3 @@
package mage.cards.w; package mage.cards.w;
import java.util.UUID; import java.util.UUID;
@ -103,7 +102,9 @@ class WarsTollEffect extends OneShotEffect {
filterOpponentCreatures.add(new ControllerIdPredicate(opponent.getId())); filterOpponentCreatures.add(new ControllerIdPredicate(opponent.getId()));
game.getBattlefield().getAllActivePermanents(CardType.CREATURE).stream().filter((permanent) -> (filterOpponentCreatures.match(permanent, source.getSourceId(), source.getControllerId(), game))).forEachOrdered((permanent) -> { game.getBattlefield().getAllActivePermanents(CardType.CREATURE).stream().filter((permanent) -> (filterOpponentCreatures.match(permanent, source.getSourceId(), source.getControllerId(), game))).forEachOrdered((permanent) -> {
//TODO: allow the player to choose between a planeswalker and player //TODO: allow the player to choose between a planeswalker and player
opponent.declareAttacker(permanent.getId(), source.getControllerId(), game, false); if (permanent.canAttack(source.getControllerId(), game)) {
opponent.declareAttacker(permanent.getId(), source.getControllerId(), game, false);
}
}); });
return true; return true;
} }

View file

@ -1,4 +1,3 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import java.util.UUID; import java.util.UUID;
@ -6,6 +5,8 @@ import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
@ -22,15 +23,22 @@ import mage.util.CardUtil;
public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect { public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
protected Effects executingEffects = new Effects(); protected Effects executingEffects = new Effects();
private final Cost cost; protected Cost cost;
private String chooseUseText; private String chooseUseText;
protected DynamicValue genericMana;
public DoUnlessAnyPlayerPaysEffect(Effect effect, DynamicValue genericMana) {
super(Outcome.Detriment);
this.genericMana = genericMana;
this.executingEffects.add(effect);
}
public DoUnlessAnyPlayerPaysEffect(Effect effect, Cost cost) { public DoUnlessAnyPlayerPaysEffect(Effect effect, Cost cost) {
this(effect, cost, null); this(effect, cost, null);
} }
public DoUnlessAnyPlayerPaysEffect(Effect effect, Cost cost, String chooseUseText) { public DoUnlessAnyPlayerPaysEffect(Effect effect, Cost cost, String chooseUseText) {
super(Outcome.Benefit); super(Outcome.Neutral);
this.executingEffects.add(effect); this.executingEffects.add(effect);
this.cost = cost; this.cost = cost;
this.chooseUseText = chooseUseText; this.chooseUseText = chooseUseText;
@ -38,8 +46,13 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
public DoUnlessAnyPlayerPaysEffect(final DoUnlessAnyPlayerPaysEffect effect) { public DoUnlessAnyPlayerPaysEffect(final DoUnlessAnyPlayerPaysEffect effect) {
super(effect); super(effect);
if (effect.cost != null) {
this.cost = effect.cost.copy();
}
if (effect.genericMana != null) {
this.genericMana = effect.genericMana.copy();
}
this.executingEffects = effect.executingEffects.copy(); this.executingEffects = effect.executingEffects.copy();
this.cost = effect.cost.copy();
this.chooseUseText = effect.chooseUseText; this.chooseUseText = effect.chooseUseText;
} }
@ -51,11 +64,18 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId()); MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null && sourceObject != null) { Cost costToPay;
if (controller != null
&& sourceObject != null) {
if (cost != null) {
costToPay = cost.copy();
} else {
costToPay = new GenericManaCost(genericMana.calculate(game, source, this));
}
String message; String message;
if (chooseUseText == null) { if (chooseUseText == null) {
String effectText = executingEffects.getText(source.getModes().getMode()); String effectText = executingEffects.getText(source.getModes().getMode());
message = "Pay " + cost.getText() + " to prevent (" + effectText.substring(0, effectText.length() - 1) + ")?"; message = "Pay " + costToPay.getText() + " to prevent (" + effectText.substring(0, effectText.length() - 1) + ")?";
} else { } else {
message = chooseUseText; message = chooseUseText;
} }
@ -65,9 +85,10 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
// check if any player is willing to pay // check if any player is willing to pay
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) { if (player != null
cost.clearPaid(); && costToPay.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) {
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) { costToPay.clearPaid();
if (costToPay.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
if (!game.isSimulation()) { if (!game.isSimulation()) {
game.informPlayers(player.getLogName() + " pays the cost to prevent the effect"); game.informPlayers(player.getLogName() + " pays the cost to prevent the effect");
} }
@ -100,8 +121,18 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
if (!staticText.isEmpty()) { if (!staticText.isEmpty()) {
return staticText; return staticText;
} }
StringBuilder sb = new StringBuilder();
if (cost != null) {
sb.append(cost.getText());
} else {
sb.append("{X}");
}
if (genericMana != null && !genericMana.getMessage().isEmpty()) {
sb.append(", where X is ");
sb.append(genericMana.getMessage());
}
String effectsText = executingEffects.getText(mode); String effectsText = executingEffects.getText(mode);
return effectsText.substring(0, effectsText.length() - 1) + " unless any player pays " + cost.getText(); return effectsText.substring(0, effectsText.length() - 1) + " unless any player pays " + sb.toString();
} }
@Override @Override