Nethroi (IKO)

This commit is contained in:
Tim Mocny
2021-02-14 00:57:22 +00:00
committed by Anthony Calosa
parent 47fcd88366
commit d7f0665bae
8 changed files with 116 additions and 2 deletions

View File

@@ -1229,6 +1229,14 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
}
// if max power exceeded, do not choose this card (but keep looking for other options)
if (sa.hasParam("MaxTotalTargetPower")) {
if (choice.getNetPower() > sa.getTargetRestrictions().getMaxTotalPower(choice, sa) -sa.getTargets().getTotalTargetedPower()) {
list.remove(choice);
continue;
}
}
// honor the Same Creature Type restriction
if (sa.getTargetRestrictions().isWithSameCreatureType()) {
Card firstTarget = sa.getTargetCard();

View File

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

View File

@@ -547,6 +547,21 @@ public final class CardUtil {
}
}
// Remove cards exceeding total power
if (ability.hasParam("MaxTotalTargetPower")) {
int totalPowerTargeted = 0;
for (final Card c : targeted) {
totalPowerTargeted += c.getNetPower();
}
final List<Card> choicesCopy = Lists.newArrayList(choices);
for (final Card c : choicesCopy) {
if (c.getNetPower() > tgt.getMaxTotalPower(c, ability) - totalPowerTargeted) {
choices.remove(c);
}
}
}
// If all cards (including subability targets) must have the same controller
if (tgt.isSameController() && !targetedObjects.isEmpty()) {
final List<Card> list = Lists.newArrayList();

View File

@@ -1227,6 +1227,19 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
}
}
if (hasParam("MaxTotalTargetPower") && entity instanceof Card) {
int soFar = Aggregates.sum(getTargets().getTargetCards(), CardPredicates.Accessors.fnGetNetPower);
// only add if it isn't already targeting
if (!isTargeting(entity)) {
final Card c = (Card) entity;
soFar += c.getNetPower();
}
if (soFar > tr.getMaxTotalPower(getHostCard(),this)) {
return false;
}
}
if (tr.isDifferentControllers()) {
Player newController;
if (entity instanceof Card) {

View File

@@ -58,6 +58,14 @@ public class TargetChoices extends ForwardingList<GameObject> implements Cloneab
}
@Override
public final int getTotalTargetedPower() {
int totalPower = 0;
for (Card c : Iterables.filter(targets, Card.class)) {
totalPower += c.getNetPower();
}
return totalPower;
}
public final boolean add(final GameObject o) {
if (o instanceof Player || o instanceof Card || o instanceof SpellAbility) {
return super.add(o);

View File

@@ -74,6 +74,9 @@ public class TargetRestrictions {
// What's the max total CMC of targets?
private String maxTotalCMC;
// What's the max total power of targets?
private String maxTotalPower;
// Not sure what's up with Mandatory? Why wouldn't targeting be mandatory?
private boolean bMandatory = false;
@@ -92,6 +95,7 @@ public class TargetRestrictions {
this.minTargets = target.getMinTargets();
this.maxTargets = target.getMaxTargets();
this.maxTotalCMC = target.getMaxTotalCMC();
this.maxTotalPower = target.getMaxTotalPower();
this.tgtZone = target.getZone();
this.saValidTargeting = target.getSAValidTargeting();
this.uniqueTargets = target.isUniqueTargets();
@@ -163,6 +167,29 @@ public class TargetRestrictions {
this.maxTotalCMC = cmc;
}
/**
* <p>
* setMaxTotalPower.
* </p>
*
* @param power
* a String.
*/
public final void setMaxTotalPower(final String power) {
this.maxTotalPower = power;
}
/**
* <p>
* doesTarget.
* </p>
*
* @return a boolean.
*/
public final boolean doesTarget() {
return this.tgtValid;
}
/**
* <p>
* getValidTgts.
@@ -216,6 +243,19 @@ public class TargetRestrictions {
return AbilityUtils.calculateAmount(c, this.maxTotalCMC, sa);
}
/**
* Gets the max targets.
*
* @return the max targets
*/
private final String getMaxTotalPower() {
return this.maxTotalPower;
}
public final int getMaxTotalPower(final Card c, final SpellAbility sa) {
return AbilityUtils.calculateAmount(c, this.maxTotalPower, sa);
}
/**
* <p>
* Getter for the field <code>minTargets</code>.

View File

@@ -0,0 +1,11 @@
Name:Nethroi, Apex of Death
ManaCost:2 W B G
Types:Legendary Creature Cat Nightmare Beast
PT:5/5
K:Mutate:4 GW B B
K:Deathtouch
K:Lifelink
T:Mode$ Mutates | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ Whenever this creature mutates, return any number of target creature cards with total power 10 or less from your graveyard to the battlefield.
SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | TargetMin$ 0 | TargetMax$ X | References$ X | ValidTgts$ Creature.YouOwn | MaxTotalTargetPower$ 10 | TgtPrompt$ Select any number of creature cards with total power 10 or less
SVar:X:Count$ValidGraveyard Creature.YouOwn
Oracle:Mutate {4}{G/W}{B}{B} (If you cast this spell for its mutate cost, put it over or under target non-Human creature you own. They mutate into the creature on top plus all abilities from under it.)\nDeathtouch, lifelink\nWhenever this creature mutates, return any number of target creature cards with total power 10 or less from your graveyard to the battlefield.

View File

@@ -212,6 +212,20 @@ public final class InputSelectTargets extends InputSyncronizedBase {
}
}
if (sa.hasParam("MaxTotalTargetPower")) {
int maxTotalPower = tgt.getMaxTotalPower(sa.getHostCard(), sa);
if (maxTotalPower > 0) {
int soFar = Aggregates.sum(sa.getTargets().getTargetCards(), CardPredicates.Accessors.fnGetNetPower);
if (!sa.isTargeting(card)) {
soFar += card.getNetPower();
}
if (soFar > maxTotalPower) {
showMessage(sa.getHostCard() + " - Cannot target this card (power limit exceeded)");
return false;
}
}
}
// If all cards must have different controllers
if (tgt.isDifferentControllers()) {
final List<Player> targetedControllers = new ArrayList<>();