mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 13:19:18 -08:00
TargetAmount refactors (#13128)
* Add minimum and maximum target counts as parameters for TargetAmount and its subclasses; update/add several rules comments (and one actual text) for clarity; remove unused imports * Get amount+description from target instead of parameters for DistributeCountersEffect and DamageMultiEffect; additions to TargetImpl.getDescription to accommodate * Create separate method to check if "any number" phrasing should be used, override it in TargetAmount * Check instanceof TargetAmount before casting * Add new constructors to chain off of for TargetCreaturePermanentAmount & TargetCreatureOrPlaneswalkerAmount * Fix text for Storm the Seedcore * Use Integer.MAX_VALUE instead of 0 to represent no maximum targets * Add comment about getUseAnyNumber() * Use amount-only constructors in some TargetAmount subclasses, add clarifying documentation * Fix a few calls * Require more specific filters
This commit is contained in:
parent
960c26a291
commit
73b63d14ad
123 changed files with 444 additions and 365 deletions
|
|
@ -4,13 +4,13 @@ import mage.MageObjectReference;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetAmount;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -19,32 +19,21 @@ import java.util.*;
|
|||
*/
|
||||
public class DamageMultiEffect extends OneShotEffect {
|
||||
|
||||
protected DynamicValue amount;
|
||||
private String sourceName = "{this}";
|
||||
private final Set<MageObjectReference> damagedSet = new HashSet<>();
|
||||
|
||||
public DamageMultiEffect(int amount) {
|
||||
this(StaticValue.get(amount));
|
||||
}
|
||||
|
||||
public DamageMultiEffect(int amount, String whoDealDamageName) {
|
||||
this(StaticValue.get(amount), whoDealDamageName);
|
||||
}
|
||||
|
||||
public DamageMultiEffect(DynamicValue amount, String whoDealDamageName) {
|
||||
this(amount);
|
||||
this.sourceName = whoDealDamageName;
|
||||
}
|
||||
|
||||
public DamageMultiEffect(DynamicValue amount) {
|
||||
public DamageMultiEffect() {
|
||||
super(Outcome.Damage);
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public DamageMultiEffect(String whoDealDamageName) {
|
||||
super(Outcome.Damage);
|
||||
this.sourceName = whoDealDamageName;
|
||||
}
|
||||
|
||||
protected DamageMultiEffect(final DamageMultiEffect effect) {
|
||||
super(effect);
|
||||
this.damagedSet.addAll(effect.damagedSet);
|
||||
this.amount = effect.amount;
|
||||
this.sourceName = effect.sourceName;
|
||||
}
|
||||
|
||||
|
|
@ -84,16 +73,16 @@ public class DamageMultiEffect extends OneShotEffect {
|
|||
StringBuilder sb = new StringBuilder(sourceName);
|
||||
sb.append(" deals ");
|
||||
|
||||
String amountString = amount.toString();
|
||||
sb.append(amountString);
|
||||
sb.append(" damage divided as you choose among ");
|
||||
sb.append(amountString.equals("2") ? "one or two " : amountString.equals("3") ? "one, two, or three " : "any number of ");
|
||||
|
||||
String targetName = mode.getTargets().get(0).getTargetName();
|
||||
if (!targetName.contains("target")) {
|
||||
sb.append("target ");
|
||||
Target target = mode.getTargets().get(0);
|
||||
if (!(target instanceof TargetAmount)) {
|
||||
throw new IllegalStateException("Must use TargetAmount");
|
||||
}
|
||||
sb.append(targetName);
|
||||
TargetAmount targetAmount = (TargetAmount) target;
|
||||
|
||||
DynamicValue amount = targetAmount.getAmount();
|
||||
sb.append(amount.toString());
|
||||
sb.append(" damage divided as you choose among ");
|
||||
sb.append(targetAmount.getDescription());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import mage.counters.CounterType;
|
|||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetAmount;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -22,34 +23,24 @@ import java.util.UUID;
|
|||
public class DistributeCountersEffect extends OneShotEffect {
|
||||
|
||||
private final CounterType counterType;
|
||||
private final DynamicValue amount;
|
||||
private boolean removeAtEndOfTurn = false;
|
||||
private final String targetDescription;
|
||||
|
||||
/**
|
||||
* Distribute +1/+1 counters among targets
|
||||
*/
|
||||
public DistributeCountersEffect(int amount, String targetDescription) {
|
||||
this(CounterType.P1P1, StaticValue.get(amount), targetDescription);
|
||||
public DistributeCountersEffect() {
|
||||
this(CounterType.P1P1);
|
||||
}
|
||||
|
||||
public DistributeCountersEffect(CounterType counterType, int amount, String targetDescription) {
|
||||
this(counterType, StaticValue.get(amount), targetDescription);
|
||||
}
|
||||
|
||||
public DistributeCountersEffect(CounterType counterType, DynamicValue amount, String targetDescription) {
|
||||
public DistributeCountersEffect(CounterType counterType) {
|
||||
super(Outcome.BoostCreature);
|
||||
this.counterType = counterType;
|
||||
this.amount = amount;
|
||||
this.targetDescription = targetDescription;
|
||||
}
|
||||
|
||||
protected DistributeCountersEffect(final DistributeCountersEffect effect) {
|
||||
super(effect);
|
||||
this.counterType = effect.counterType;
|
||||
this.amount = effect.amount;
|
||||
this.removeAtEndOfTurn = effect.removeAtEndOfTurn;
|
||||
this.targetDescription = effect.targetDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -90,9 +81,16 @@ public class DistributeCountersEffect extends OneShotEffect {
|
|||
if (staticText != null && !staticText.isEmpty()) {
|
||||
return staticText;
|
||||
}
|
||||
Target target = mode.getTargets().get(0);
|
||||
if (!(target instanceof TargetAmount)) {
|
||||
throw new IllegalStateException("Must use TargetAmount");
|
||||
}
|
||||
TargetAmount targetAmount = (TargetAmount) target;
|
||||
DynamicValue amount = targetAmount.getAmount();
|
||||
|
||||
String name = counterType.getName();
|
||||
String number = (amount instanceof StaticValue) ? CardUtil.numberToText(((StaticValue) amount).getValue()) : amount.toString();
|
||||
String text = "distribute " + number + ' ' + name + " counters among " + targetDescription;
|
||||
String text = "distribute " + number + ' ' + name + " counters among " + targetAmount.getDescription();
|
||||
if (removeAtEndOfTurn) {
|
||||
text += ". For each " + name + " counter you put on a creature this way, remove a "
|
||||
+ name + " counter from that creature at the beginning of the next cleanup step.";
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package mage.target;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
|
@ -18,8 +19,10 @@ public abstract class TargetAmount extends TargetImpl {
|
|||
DynamicValue amount;
|
||||
int remainingAmount;
|
||||
|
||||
protected TargetAmount(DynamicValue amount) {
|
||||
protected TargetAmount(DynamicValue amount, int minNumberOfTargets, int maxNumberOfTargets) {
|
||||
this.amount = amount;
|
||||
setMinNumberOfTargets(minNumberOfTargets);
|
||||
setMaxNumberOfTargets(maxNumberOfTargets);
|
||||
}
|
||||
|
||||
protected TargetAmount(final TargetAmount target) {
|
||||
|
|
@ -65,6 +68,10 @@ public abstract class TargetAmount extends TargetImpl {
|
|||
amountWasSet = true;
|
||||
}
|
||||
|
||||
public DynamicValue getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int getAmountTotal(Game game, Ability source) {
|
||||
return amount.calculate(game, source, null);
|
||||
}
|
||||
|
|
@ -176,4 +183,24 @@ public abstract class TargetAmount extends TargetImpl {
|
|||
remainingAmount -= (amount - this.getTargetAmount(targetId));
|
||||
this.setTargetAmount(targetId, amount, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getUseAnyNumber() {
|
||||
int min = getMinNumberOfTargets();
|
||||
int max = getMaxNumberOfTargets();
|
||||
if (min != 0) {
|
||||
return false;
|
||||
}
|
||||
if (max == Integer.MAX_VALUE) {
|
||||
return true;
|
||||
}
|
||||
// For a TargetAmount with a min of 0:
|
||||
// A max that equals the amount, when the amount is a StaticValue,
|
||||
// usually represents "any number of target __s", since you can't target more than the amount.
|
||||
//
|
||||
// 601.2d. If the spell requires the player to divide or distribute an effect
|
||||
// (such as damage or counters) among one or more targets, the player announces the division.
|
||||
// Each of these targets must receive at least one of whatever is being divided.
|
||||
return amount instanceof StaticValue && max == ((StaticValue) amount).getValue();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,17 +109,22 @@ public abstract class TargetImpl implements Target {
|
|||
sb.append(" or more ");
|
||||
} else if (!targetName.startsWith("X ") && (min != 1 || max != 1)) {
|
||||
targetName = targetName.replace("another", "other"); //If non-singular, use "other" instead of "another"
|
||||
if (min < max && max != Integer.MAX_VALUE) {
|
||||
if (min == 1 && max == 2) {
|
||||
sb.append("one or ");
|
||||
} else if (min == 1 && max == 3) {
|
||||
sb.append("one, two, or ");
|
||||
} else {
|
||||
sb.append("up to ");
|
||||
|
||||
if (getUseAnyNumber()) {
|
||||
sb.append(("any number of "));
|
||||
} else {
|
||||
if (min < max && max != Integer.MAX_VALUE) {
|
||||
if (min == 1 && max == 2) {
|
||||
sb.append("one or ");
|
||||
} else if (min == 1 && max == 3) {
|
||||
sb.append("one, two, or ");
|
||||
} else {
|
||||
sb.append("up to ");
|
||||
}
|
||||
}
|
||||
sb.append(CardUtil.numberToText(max));
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(CardUtil.numberToText(max));
|
||||
sb.append(' ');
|
||||
}
|
||||
boolean addTargetWord = false;
|
||||
if (!isNotTarget()) {
|
||||
|
|
@ -127,7 +132,8 @@ public abstract class TargetImpl implements Target {
|
|||
if (targetName.contains("target ")) {
|
||||
addTargetWord = false;
|
||||
} else if (targetName.endsWith("any target")
|
||||
|| targetName.endsWith("any other target")) {
|
||||
|| targetName.endsWith("any other target")
|
||||
|| targetName.endsWith("targets")) {
|
||||
addTargetWord = false;
|
||||
}
|
||||
// endsWith needs to be specific.
|
||||
|
|
@ -144,6 +150,15 @@ public abstract class TargetImpl implements Target {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for generating text description. Needed so that subclasses may override.
|
||||
*/
|
||||
protected boolean getUseAnyNumber() {
|
||||
int min = getMinNumberOfTargets();
|
||||
int max = getMaxNumberOfTargets();
|
||||
return min == 0 && max == Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage(Game game) {
|
||||
// UI choose message
|
||||
|
|
|
|||
|
|
@ -14,25 +14,45 @@ public class TargetAnyTargetAmount extends TargetPermanentOrPlayerAmount {
|
|||
private static final FilterPermanentOrPlayer defaultFilter
|
||||
= new FilterAnyTarget("targets");
|
||||
|
||||
/**
|
||||
* <b>IMPORTANT</b>: Use more specific constructor if {@code amount} is not always the same number!<br>
|
||||
* {@code minNumberOfTargets} defaults to zero for {@code amount} > 3, otherwise to one, in line with typical templating.<br>
|
||||
* {@code maxNumberOfTargets} defaults to {@code amount}.
|
||||
*
|
||||
* @see TargetAnyTargetAmount#TargetAnyTargetAmount(int, int, int)
|
||||
*/
|
||||
public TargetAnyTargetAmount(int amount) {
|
||||
this(amount, 0);
|
||||
this(amount, amount > 3 ? 0 : 1, amount);
|
||||
}
|
||||
|
||||
public TargetAnyTargetAmount(int amount, int maxNumberOfTargets) {
|
||||
// 107.1c If a rule or ability instructs a player to choose “any number,” that player may choose
|
||||
// any positive number or zero, unless something (such as damage or counters) is being divided
|
||||
// or distributed among “any number” of players and/or objects. In that case, a nonzero number
|
||||
// of players and/or objects must be chosen if possible.
|
||||
this(StaticValue.get(amount), maxNumberOfTargets);
|
||||
this.minNumberOfTargets = 1;
|
||||
/**
|
||||
* @param amount Amount of stuff (e.g. damage) to distribute.
|
||||
* @param minNumberOfTargets Minimum number of targets.
|
||||
* @param maxNumberOfTargets Maximum number of targets. Should be set to {@code amount} if no lower max is needed.
|
||||
*/
|
||||
public TargetAnyTargetAmount(int amount, int minNumberOfTargets, int maxNumberOfTargets) {
|
||||
this(StaticValue.get(amount), minNumberOfTargets, maxNumberOfTargets);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code minNumberOfTargets} defaults to zero.<br>
|
||||
* {@code maxNumberOfTargets} defaults to Integer.MAX_VALUE.
|
||||
*
|
||||
* @see TargetAnyTargetAmount#TargetAnyTargetAmount(DynamicValue, int, int)
|
||||
*/
|
||||
public TargetAnyTargetAmount(DynamicValue amount) {
|
||||
this(amount, 0);
|
||||
this(amount, 0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public TargetAnyTargetAmount(DynamicValue amount, int maxNumberOfTargets) {
|
||||
super(amount, maxNumberOfTargets);
|
||||
/**
|
||||
* @param amount Amount of stuff (e.g. damage) to distribute.
|
||||
* @param minNumberOfTargets Minimum number of targets.
|
||||
* @param maxNumberOfTargets Maximum number of targets. Since {@code amount} is dynamic,
|
||||
* should be set to Integer.MAX_VALUE if no lower max is needed.
|
||||
* (Game will always prevent choosing more than {@code amount} targets.)
|
||||
*/
|
||||
public TargetAnyTargetAmount(DynamicValue amount, int minNumberOfTargets, int maxNumberOfTargets) {
|
||||
super(amount, minNumberOfTargets, maxNumberOfTargets);
|
||||
this.zone = Zone.ALL;
|
||||
this.filter = defaultFilter;
|
||||
this.targetName = filter.getMessage();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.target.common;
|
||||
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreatureOrPlaneswalkerPermanent;
|
||||
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
|
||||
|
||||
/**
|
||||
|
|
@ -11,12 +11,62 @@ public class TargetCreatureOrPlaneswalkerAmount extends TargetPermanentAmount {
|
|||
private static final FilterCreatureOrPlaneswalkerPermanent defaultFilter
|
||||
= new FilterCreatureOrPlaneswalkerPermanent("target creatures and/or planeswalkers");
|
||||
|
||||
/**
|
||||
* <b>IMPORTANT</b>: Use more specific constructor if {@code amount} is not always the same number!<br>
|
||||
* {@code minNumberOfTargets} defaults to zero for {@code amount} > 3, otherwise to one, in line with typical templating.<br>
|
||||
* {@code maxNumberOfTargets} defaults to {@code amount}.<br>
|
||||
* {@code filter} defaults to all creature and planeswalker permanents. ("target creatures and/or planeswalkers")
|
||||
*
|
||||
* @see TargetCreatureOrPlaneswalkerAmount#TargetCreatureOrPlaneswalkerAmount(int, int, int, FilterCreatureOrPlaneswalkerPermanent)
|
||||
*/
|
||||
public TargetCreatureOrPlaneswalkerAmount(int amount) {
|
||||
super(amount, defaultFilter);
|
||||
this(amount, defaultFilter);
|
||||
}
|
||||
|
||||
public TargetCreatureOrPlaneswalkerAmount(int amount, FilterPermanent filter) {
|
||||
super(amount, filter);
|
||||
/**
|
||||
* <b>IMPORTANT</b>: Use more specific constructor if {@code amount} is not always the same number!<br>
|
||||
* {@code minNumberOfTargets} defaults to zero for {@code amount} > 3, otherwise to one, in line with typical templating.<br>
|
||||
* {@code maxNumberOfTargets} defaults to {@code amount}.
|
||||
*
|
||||
* @see TargetCreatureOrPlaneswalkerAmount#TargetCreatureOrPlaneswalkerAmount(int, int, int, FilterCreatureOrPlaneswalkerPermanent)
|
||||
*/
|
||||
public TargetCreatureOrPlaneswalkerAmount(int amount, FilterCreatureOrPlaneswalkerPermanent filter) {
|
||||
this(amount, amount > 3 ? 0 : 1, amount, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code filter} defaults to all creature and planeswalker permanents. ("target creatures and/or planeswalkers")
|
||||
*
|
||||
* @see TargetCreatureOrPlaneswalkerAmount#TargetCreatureOrPlaneswalkerAmount(int, int, int, FilterCreatureOrPlaneswalkerPermanent)
|
||||
*/
|
||||
public TargetCreatureOrPlaneswalkerAmount(int amount, int minNumberOfTargets, int maxNumberOfTargets) {
|
||||
this(amount, minNumberOfTargets, maxNumberOfTargets, defaultFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param amount Amount of stuff (e.g. damage, counters) to distribute.
|
||||
* @param minNumberOfTargets Minimum number of targets.
|
||||
* @param maxNumberOfTargets Maximum number of targets. If no lower max is needed, set to {@code amount}.
|
||||
* @param filter Filter for creatures and/or planeswalkers that something will be distributed amongst.
|
||||
*/
|
||||
public TargetCreatureOrPlaneswalkerAmount(int amount, int minNumberOfTargets, int maxNumberOfTargets, FilterCreatureOrPlaneswalkerPermanent filter) {
|
||||
super(amount, minNumberOfTargets, maxNumberOfTargets, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>IMPORTANT</b>: Use more specific constructor if {@code amount} is not always the same number!
|
||||
*
|
||||
* @see TargetCreatureOrPlaneswalkerAmount#TargetCreatureOrPlaneswalkerAmount(int, FilterCreatureOrPlaneswalkerPermanent)
|
||||
*/
|
||||
public TargetCreatureOrPlaneswalkerAmount(int amount, FilterControlledCreatureOrPlaneswalkerPermanent filter) {
|
||||
this(amount, amount > 3 ? 0 : 1, amount, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TargetCreatureOrPlaneswalkerAmount#TargetCreatureOrPlaneswalkerAmount(int, int, int, FilterCreatureOrPlaneswalkerPermanent)
|
||||
*/
|
||||
public TargetCreatureOrPlaneswalkerAmount(int amount, int minNumberOfTargets, int maxNumberOfTargets, FilterControlledCreatureOrPlaneswalkerPermanent filter) {
|
||||
super(amount, minNumberOfTargets, maxNumberOfTargets, filter);
|
||||
}
|
||||
|
||||
private TargetCreatureOrPlaneswalkerAmount(final TargetCreatureOrPlaneswalkerAmount target) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package mage.target.common;
|
||||
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
|
||||
/**
|
||||
|
|
@ -11,20 +11,88 @@ public class TargetCreaturePermanentAmount extends TargetPermanentAmount {
|
|||
|
||||
private static final FilterCreaturePermanent defaultFilter = new FilterCreaturePermanent("target creatures");
|
||||
|
||||
/**
|
||||
* <b>IMPORTANT</b>: Use more specific constructor if {@code amount} is not always the same number!<br>
|
||||
* {@code minNumberOfTargets} defaults to zero for {@code amount} > 3, otherwise to one, in line with typical templating.<br>
|
||||
* {@code maxNumberOfTargets} defaults to {@code amount}.<br>
|
||||
* {@code filter} defaults to all creature permanents. ("target creatures")
|
||||
*
|
||||
* @see TargetCreaturePermanentAmount#TargetCreaturePermanentAmount(int, int, int, FilterCreaturePermanent)
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(int amount) {
|
||||
super(amount, defaultFilter);
|
||||
this(amount, defaultFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>IMPORTANT</b>: Use more specific constructor if {@code amount} is not always the same number!<br>
|
||||
* {@code minNumberOfTargets} defaults to zero for {@code amount} > 3, otherwise to one, in line with typical templating.<br>
|
||||
* {@code maxNumberOfTargets} defaults to {@code amount}.
|
||||
*
|
||||
* @see TargetCreaturePermanentAmount#TargetCreaturePermanentAmount(int, int, int, FilterCreaturePermanent)
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(int amount, FilterCreaturePermanent filter) {
|
||||
this(amount, amount > 3 ? 0 : 1, amount, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code filter} defaults to all creature permanents. ("target creatures")
|
||||
*
|
||||
* @see TargetCreaturePermanentAmount#TargetCreaturePermanentAmount(int, int, int, FilterCreaturePermanent)
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(int amount, int minNumberOfTargets, int maxNumberOfTargets) {
|
||||
this(amount, minNumberOfTargets, maxNumberOfTargets, defaultFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param amount Amount of stuff (e.g. damage, counters) to distribute.
|
||||
* @param minNumberOfTargets Minimum number of targets.
|
||||
* @param maxNumberOfTargets Maximum number of targets. If no lower max is needed, set to {@code amount}.
|
||||
* @param filter Filter for creatures that something will be distributed amongst.
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(int amount, int minNumberOfTargets, int maxNumberOfTargets, FilterCreaturePermanent filter) {
|
||||
super(amount, minNumberOfTargets, maxNumberOfTargets, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code filter} defaults to all creature permanents. ("target creatures")
|
||||
*
|
||||
* @see TargetCreaturePermanentAmount#TargetCreaturePermanentAmount(DynamicValue, FilterCreaturePermanent)
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(DynamicValue amount) {
|
||||
this(amount, defaultFilter);
|
||||
}
|
||||
|
||||
public TargetCreaturePermanentAmount(int amount, FilterPermanent filter) {
|
||||
super(amount, filter);
|
||||
/**
|
||||
* Minimum number of targets will be zero, and max will be set to Integer.MAX_VALUE.
|
||||
*
|
||||
* @param amount Amount of stuff (e.g. damage, counters) to distribute.
|
||||
* @param filter Filter for creatures that something will be distributed amongst.
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(DynamicValue amount, FilterCreaturePermanent filter) {
|
||||
super(amount, 0, filter);
|
||||
}
|
||||
|
||||
public TargetCreaturePermanentAmount(DynamicValue amount, FilterPermanent filter) {
|
||||
super(amount, filter);
|
||||
/**
|
||||
* <b>IMPORTANT</b>: Use more specific constructor if {@code amount} is not always the same number!
|
||||
*
|
||||
* @see TargetCreaturePermanentAmount#TargetCreaturePermanentAmount(int, FilterCreaturePermanent)
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(int amount, FilterControlledCreaturePermanent filter) {
|
||||
this(amount, amount > 3 ? 0 : 1, amount, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TargetCreaturePermanentAmount#TargetCreaturePermanentAmount(int, int, int, FilterCreaturePermanent)
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(int amount, int minNumberOfTargets, int maxNumberOfTargets, FilterControlledCreaturePermanent filter) {
|
||||
super(amount, minNumberOfTargets, maxNumberOfTargets, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TargetCreaturePermanentAmount#TargetCreaturePermanentAmount(DynamicValue, FilterCreaturePermanent)
|
||||
*/
|
||||
public TargetCreaturePermanentAmount(DynamicValue amount, FilterControlledCreaturePermanent filter) {
|
||||
super(amount, 0, filter);
|
||||
}
|
||||
|
||||
private TargetCreaturePermanentAmount(final TargetCreaturePermanentAmount target) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
|
@ -23,16 +22,41 @@ public class TargetPermanentAmount extends TargetAmount {
|
|||
|
||||
protected final FilterPermanent filter;
|
||||
|
||||
public TargetPermanentAmount(int amount, FilterPermanent filter) {
|
||||
// 107.1c If a rule or ability instructs a player to choose “any number,” that player may choose
|
||||
// any positive number or zero, unless something (such as damage or counters) is being divided
|
||||
// or distributed among “any number” of players and/or objects. In that case, a nonzero number
|
||||
// of players and/or objects must be chosen if possible.
|
||||
this(StaticValue.get(amount), filter);
|
||||
/**
|
||||
* {@code maxNumberOfTargets} defaults to {@code amount}.
|
||||
*
|
||||
* @see TargetPermanentAmount#TargetPermanentAmount(DynamicValue, int, int, FilterPermanent)
|
||||
*/
|
||||
public TargetPermanentAmount(int amount, int minNumberOfTargets, FilterPermanent filter) {
|
||||
this(amount, minNumberOfTargets, amount, filter);
|
||||
}
|
||||
|
||||
public TargetPermanentAmount(DynamicValue amount, FilterPermanent filter) {
|
||||
super(amount);
|
||||
/**
|
||||
* {@code maxNumberOfTargets} defaults to Integer.MAX_VALUE.
|
||||
*
|
||||
* @see TargetPermanentAmount#TargetPermanentAmount(DynamicValue, int, int, FilterPermanent)
|
||||
*/
|
||||
public TargetPermanentAmount(DynamicValue amount, int minNumberOfTargets, FilterPermanent filter) {
|
||||
this(amount, minNumberOfTargets, Integer.MAX_VALUE, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TargetPermanentAmount#TargetPermanentAmount(DynamicValue, int, int, FilterPermanent)
|
||||
*/
|
||||
public TargetPermanentAmount(int amount, int minNumberOfTargets, int maxNumberOfTargets, FilterPermanent filter) {
|
||||
this(StaticValue.get(amount), minNumberOfTargets, maxNumberOfTargets, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param amount Amount of stuff (e.g. damage, counters) to distribute.
|
||||
* @param minNumberOfTargets Minimum number of targets.
|
||||
* @param maxNumberOfTargets Maximum number of targets. If no lower max is needed:
|
||||
* set to {@code amount} if amount is static; otherwise, set to Integer.MAX_VALUE.
|
||||
* (Game will always prevent distributing among more than {@code amount} permanents.)
|
||||
* @param filter Filter for permanents that something will be distributed amongst.
|
||||
*/
|
||||
public TargetPermanentAmount(DynamicValue amount, int minNumberOfTargets, int maxNumberOfTargets, FilterPermanent filter) {
|
||||
super(amount, minNumberOfTargets, maxNumberOfTargets);
|
||||
this.zone = Zone.ALL;
|
||||
this.filter = filter;
|
||||
this.targetName = filter.getMessage();
|
||||
|
|
@ -49,7 +73,7 @@ public class TargetPermanentAmount extends TargetAmount {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
public FilterPermanent getFilter() {
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,8 @@ public abstract class TargetPermanentOrPlayerAmount extends TargetAmount {
|
|||
|
||||
protected FilterPermanentOrPlayer filter;
|
||||
|
||||
TargetPermanentOrPlayerAmount(DynamicValue amount, int maxNumberOfTargets) {
|
||||
super(amount);
|
||||
this.maxNumberOfTargets = maxNumberOfTargets;
|
||||
TargetPermanentOrPlayerAmount(DynamicValue amount, int minNumberOfTargets, int maxNumberOfTargets) {
|
||||
super(amount, minNumberOfTargets, maxNumberOfTargets);
|
||||
}
|
||||
|
||||
TargetPermanentOrPlayerAmount(final TargetPermanentOrPlayerAmount target) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue