- Added code support for cards dependent on the maximum total CMC of targets (e.g. March from the Tomb). Basic AI support also added (but can most likely be made smarter, feel free to improve).

- Note that the relevant SA parameter has been renamed to "MaxTotalTargetCMC" (from "WithTotalCMC") to avoid confusion with the ChangeZone parameter "WithTotalCMC" that means "the total CMC of a single card".
This commit is contained in:
Agetian
2015-09-21 16:34:53 +00:00
parent ab39fb4668
commit 723a607c9f
6 changed files with 69 additions and 0 deletions

View File

@@ -1021,6 +1021,14 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
}
// if max CMC exceeded, stop choosing
if (sa.hasParam("MaxTotalTargetCMC")) {
if (choice.getCMC() > sa.getTargetRestrictions().getMaxTotalCMC(choice, sa) - sa.getTargets().getTotalTargetedCMC()) {
list.remove(choice);
continue;
}
}
list.remove(choice);
sa.getTargets().add(choice);
}

View File

@@ -230,6 +230,11 @@ public final class AbilityFactory {
abTgt.setZone(ZoneType.listValueOf(mapParams.get("TgtZone")));
}
if (mapParams.containsKey("MaxTotalTargetCMC")) {
// only target cards up to a certain total max CMC
abTgt.setMaxTotalCMC(mapParams.get("MaxTotalTargetCMC"));
}
// TargetValidTargeting most for Counter: e.g. target spell that
// targets X.
if (mapParams.containsKey("TargetValidTargeting")) {

View File

@@ -464,6 +464,24 @@ public final class CardUtil {
}
}
// Remove cards exceeding total CMC
if (ability.hasParam("MaxTotalTargetCMC")) {
int totalCMCTargeted = 0;
for (final Card c : targeted) {
totalCMCTargeted += c.getCMC();
}
final List<Card> choicesCopy = Lists.newArrayList(choices);
for (final Card c : choicesCopy) {
if (c.getCMC() > tgt.getMaxTotalCMC(c, ability)) {
choices.remove(c);
}
if (c.getCMC() > tgt.getMaxTotalCMC(c, ability) - totalCMCTargeted) {
choices.remove(c);
}
}
}
// If all cards (including subability targets) must have the same controller
if (tgt.isSameController() && !targetedObjects.isEmpty()) {
final List<Card> list = new ArrayList<Card>();

View File

@@ -48,6 +48,14 @@ public class TargetChoices implements Cloneable {
return numTargeted;
}
public final int getTotalTargetedCMC() {
int totalCMC = 0;
for (Card c : targetCards) {
totalCMC += c.getCMC();
}
return totalCMC;
}
public final boolean add(final GameObject o) {
if (o instanceof Player) {
return addTarget((Player) o);

View File

@@ -70,6 +70,9 @@ public class TargetRestrictions {
private String minTargets;
private String maxTargets;
// What's the max CMC of targeted?
private String maxTotalCMC;
// For "Divided" cards. Is this better in TargetChoices?
private boolean dividedAsYouChoose = false;
private HashMap<Object, Integer> dividedMap = new HashMap<Object, Integer>();
@@ -93,6 +96,7 @@ public class TargetRestrictions {
this.validTgts = this.originalValidTgts.clone();
this.minTargets = target.getMinTargets();
this.maxTargets = target.getMaxTargets();
this.maxTotalCMC = target.getMaxTotalCMC();
this.tgtZone = target.getZone();
this.saValidTargeting = target.getSAValidTargeting();
this.dividedAsYouChoose = target.isDividedAsYouChoose();
@@ -153,6 +157,18 @@ public class TargetRestrictions {
this.bMandatory = m;
}
/**
* <p>
* setMaxTotalCMC.
* </p>
*
* @param cmc
* a String.
*/
public final void setMaxTotalCMC(final String cmc) {
this.maxTotalCMC = cmc;
}
/**
* <p>
* doesTarget.
@@ -204,6 +220,19 @@ public class TargetRestrictions {
return this.maxTargets;
}
/**
* Gets the max targets.
*
* @return the max targets
*/
private final String getMaxTotalCMC() {
return this.maxTotalCMC;
}
public final int getMaxTotalCMC(final Card c, final SpellAbility sa) {
return AbilityUtils.calculateAmount(c, this.maxTotalCMC, sa);
}
/**
* <p>
* Getter for the field <code>minTargets</code>.

View File

@@ -71,6 +71,7 @@ public class TargetSelection {
// Number of targets is explicitly set only if spell is being redirected (ex. Swerve or Redirect)
final int minTargets = numTargets != null ? numTargets.intValue() : tgt.getMinTargets(ability.getHostCard(), ability);
final int maxTargets = numTargets != null ? numTargets.intValue() : tgt.getMaxTargets(ability.getHostCard(), ability);
final int maxTotalCMC = tgt.getMaxTotalCMC(ability.getHostCard(), ability);
final int numTargeted = ability.getTargets().getNumTargeted();
final boolean hasEnoughTargets = minTargets == 0 || numTargeted >= minTargets;