- 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();
}
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());
} //end of chooseTarget method

View file

@ -1,6 +1,5 @@
package mage.cards.s;
import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
@ -11,6 +10,7 @@ import mage.filter.common.FilterCreatureCard;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
/**
* @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}.
Effect effect = new DoUnlessAnyPlayerPaysEffect(
new ReturnFromGraveyardToHandTargetEffect(), new VariableManaCost()
);
new ReturnFromGraveyardToHandTargetEffect(), new ManacostVariableValue());
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(2, new FilterCreatureCard("creature cards from your graveyard")));
}

View file

@ -79,7 +79,9 @@ class ViashinoBeyEffect extends OneShotEffect {
} else {
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;

View file

@ -1,4 +1,3 @@
package mage.cards.w;
import java.util.UUID;
@ -103,7 +102,9 @@ class WarsTollEffect extends OneShotEffect {
filterOpponentCreatures.add(new ControllerIdPredicate(opponent.getId()));
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
opponent.declareAttacker(permanent.getId(), source.getControllerId(), game, false);
if (permanent.canAttack(source.getControllerId(), game)) {
opponent.declareAttacker(permanent.getId(), source.getControllerId(), game, false);
}
});
return true;
}

View file

@ -1,4 +1,3 @@
package mage.abilities.effects.common;
import java.util.UUID;
@ -6,6 +5,8 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
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.Effect;
import mage.abilities.effects.Effects;
@ -22,15 +23,22 @@ import mage.util.CardUtil;
public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
protected Effects executingEffects = new Effects();
private final Cost cost;
protected Cost cost;
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) {
this(effect, cost, null);
}
public DoUnlessAnyPlayerPaysEffect(Effect effect, Cost cost, String chooseUseText) {
super(Outcome.Benefit);
super(Outcome.Neutral);
this.executingEffects.add(effect);
this.cost = cost;
this.chooseUseText = chooseUseText;
@ -38,8 +46,13 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
public DoUnlessAnyPlayerPaysEffect(final DoUnlessAnyPlayerPaysEffect 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.cost = effect.cost.copy();
this.chooseUseText = effect.chooseUseText;
}
@ -51,11 +64,18 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
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;
if (chooseUseText == null) {
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 {
message = chooseUseText;
}
@ -65,9 +85,10 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
// check if any player is willing to pay
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) {
cost.clearPaid();
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
if (player != null
&& costToPay.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) {
costToPay.clearPaid();
if (costToPay.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
if (!game.isSimulation()) {
game.informPlayers(player.getLogName() + " pays the cost to prevent the effect");
}
@ -100,8 +121,18 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect {
if (!staticText.isEmpty()) {
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);
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