forked from External/mage
[CMM] Implement Nyxborn Behemoth (#10670)
* [CMM] Implement Nyxborn Behemoth Regroup the different dynamic values for "total mana value of [FILTER]" under a shared class. * refactor hints inside TotalPermanentsManaValue * apply review on TotalPermanentsManaValue->copy
This commit is contained in:
parent
9eb7e2870e
commit
c4f13be87f
8 changed files with 197 additions and 152 deletions
|
|
@ -1,24 +1,20 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.dynamicvalue.common.TotalPermanentsManaValue;
|
||||
import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Backfir3
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class AncientOoze extends CardImpl {
|
||||
|
||||
|
|
@ -30,9 +26,12 @@ public final class AncientOoze extends CardImpl {
|
|||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(0);
|
||||
|
||||
// Ancient Ooze's power and toughness are each equal to the total converted mana cost of other creatures you control.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(new AncientOozePowerToughnessValue())
|
||||
.setText("{this}'s power and toughness are each equal to the total mana value of other creatures you control.")
|
||||
// Ancient Ooze's power and toughness are each equal to the total mana value of other creatures you control.
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL,
|
||||
new SetBasePowerToughnessSourceEffect(
|
||||
new TotalPermanentsManaValue(StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES)
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -44,33 +43,4 @@ public final class AncientOoze extends CardImpl {
|
|||
public AncientOoze copy() {
|
||||
return new AncientOoze(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AncientOozePowerToughnessValue implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
int value = 0;
|
||||
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), sourceAbility.getControllerId(), game)) {
|
||||
if (creature != null && !sourceAbility.getSourceId().equals(creature.getId())) {
|
||||
value += creature.getManaValue();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AncientOozePowerToughnessValue copy() {
|
||||
return new AncientOozePowerToughnessValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "total mana value of other creatures you control";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.dynamicvalue.common.TotalPermanentsManaValue;
|
||||
import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
|
||||
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.abilities.hint.ValueHint;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -23,7 +19,6 @@ import mage.constants.Zone;
|
|||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -32,9 +27,10 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class EarthquakeDragon extends CardImpl {
|
||||
|
||||
private static final Hint hint = new ValueHint(
|
||||
"Total mana value of Dragons you control", EarthquakeDragonValue.instance
|
||||
);
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.DRAGON);
|
||||
|
||||
private static final TotalPermanentsManaValue xValue = new TotalPermanentsManaValue(filter);
|
||||
|
||||
public EarthquakeDragon(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{14}{G}");
|
||||
|
|
@ -46,8 +42,10 @@ public final class EarthquakeDragon extends CardImpl {
|
|||
|
||||
// This spell costs {X} less to cast, where X is the total mana value of Dragons you control.
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL, new SpellCostReductionSourceEffect(EarthquakeDragonValue.instance)
|
||||
).addHint(hint).setRuleAtTheTop(true));
|
||||
Zone.ALL,
|
||||
new SpellCostReductionSourceEffect(xValue)
|
||||
).addHint(xValue.getHint()).setRuleAtTheTop(true)
|
||||
);
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
|
@ -71,34 +69,4 @@ public final class EarthquakeDragon extends CardImpl {
|
|||
public EarthquakeDragon copy() {
|
||||
return new EarthquakeDragon(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum EarthquakeDragonValue implements DynamicValue {
|
||||
instance;
|
||||
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.DRAGON);
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
return game
|
||||
.getBattlefield()
|
||||
.getActivePermanents(filter, sourceAbility.getControllerId(), sourceAbility, game)
|
||||
.stream()
|
||||
.mapToInt(MageObject::getManaValue)
|
||||
.sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EarthquakeDragonValue copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "the total mana value of Dragons you control";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +1,40 @@
|
|||
package mage.cards.m;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.dynamicvalue.common.TotalPermanentsManaValue;
|
||||
import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
|
||||
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
|
||||
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
|
||||
import mage.abilities.hint.ValueHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledArtifactPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.util.CardUtil;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author emerald000
|
||||
* @author emerald000, Susucr
|
||||
*/
|
||||
public final class MetalworkColossus extends CardImpl {
|
||||
|
||||
private static final String message = "Total mana value of noncreature artifacts you control";
|
||||
private static final FilterControlledPermanent filter = new FilterControlledArtifactPermanent("artifacts");
|
||||
|
||||
private static final FilterPermanent filterCostReduction = new FilterControlledArtifactPermanent("noncreature artifacts you control");
|
||||
|
||||
static {
|
||||
filterCostReduction.add(Predicates.not(CardType.CREATURE.getPredicate()));
|
||||
}
|
||||
|
||||
private static final TotalPermanentsManaValue xValue = new TotalPermanentsManaValue(filterCostReduction);
|
||||
|
||||
public MetalworkColossus(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{11}");
|
||||
this.subtype.add(SubType.CONSTRUCT);
|
||||
|
|
@ -44,11 +42,10 @@ public final class MetalworkColossus extends CardImpl {
|
|||
this.toughness = new MageInt(10);
|
||||
|
||||
// This spell costs {X} less to cast, where X is the total mana value of noncreature artifacts you control.
|
||||
DynamicValue xValue = new totalNonCreatureArtifactManaValue();
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL,
|
||||
new SpellCostReductionSourceEffect(xValue)
|
||||
).addHint(new ValueHint(message, xValue))
|
||||
Zone.ALL,
|
||||
new SpellCostReductionSourceEffect(xValue)
|
||||
).addHint(xValue.getHint()).setRuleAtTheTop(true)
|
||||
);
|
||||
|
||||
// Sacrifice two artifacts: Return Metalwork Colossus from your graveyard to your hand.
|
||||
|
|
@ -63,51 +60,4 @@ public final class MetalworkColossus extends CardImpl {
|
|||
public MetalworkColossus copy() {
|
||||
return new MetalworkColossus(this);
|
||||
}
|
||||
}
|
||||
|
||||
class totalNonCreatureArtifactManaValue implements DynamicValue {
|
||||
|
||||
private static final String message = "the total mana value of noncreature artifacts you control";
|
||||
private static final FilterPermanent filter = new FilterControlledArtifactPermanent("noncreature artifacts you control");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
|
||||
}
|
||||
|
||||
totalNonCreatureArtifactManaValue() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
private totalNonCreatureArtifactManaValue(final totalNonCreatureArtifactManaValue dynamicValue) {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
return new totalNonCreatureArtifactManaValue(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
int totalCMC = 0;
|
||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(
|
||||
filter,
|
||||
sourceAbility.getControllerId(),
|
||||
sourceAbility,
|
||||
game);
|
||||
for (Permanent permanent : permanents) {
|
||||
totalCMC += permanent.getManaValue();
|
||||
}
|
||||
return totalCMC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
}
|
||||
}
|
||||
76
Mage.Sets/src/mage/cards/n/NyxbornBehemoth.java
Normal file
76
Mage.Sets/src/mage/cards/n/NyxbornBehemoth.java
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
package mage.cards.n;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.ActivatedAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.dynamicvalue.common.TotalPermanentsManaValue;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledEnchantmentPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class NyxbornBehemoth extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledEnchantmentPermanent("noncreature enchantments you control");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
|
||||
}
|
||||
|
||||
private static final TotalPermanentsManaValue xValue = new TotalPermanentsManaValue(filter);
|
||||
|
||||
public NyxbornBehemoth(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{10}{G}{G}");
|
||||
|
||||
this.subtype.add(SubType.BEAST);
|
||||
this.power = new MageInt(10);
|
||||
this.toughness = new MageInt(10);
|
||||
|
||||
// This spell costs {X} less to cast, where X is the total mana value of noncreature enchantments you control.
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL,
|
||||
new SpellCostReductionSourceEffect(xValue)
|
||||
).addHint(xValue.getHint()).setRuleAtTheTop(true)
|
||||
);
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// {1}{G}, Sacrifice another enchantment: Nyxborn Behemoth gains indestructible until end of turn.
|
||||
ActivatedAbility ability = new SimpleActivatedAbility(
|
||||
Zone.BATTLEFIELD,
|
||||
new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn),
|
||||
new ManaCostsImpl<>("{1}{G}")
|
||||
);
|
||||
ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_ENCHANTMENT_SHORT_TEXT));
|
||||
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private NyxbornBehemoth(final NyxbornBehemoth card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NyxbornBehemoth copy() {
|
||||
return new NyxbornBehemoth(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -431,6 +431,7 @@ public final class CommanderMasters extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Norn's Annex", 829, Rarity.RARE, mage.cards.n.NornsAnnex.class));
|
||||
cards.add(new SetCardInfo("Not of This World", 807, Rarity.UNCOMMON, mage.cards.n.NotOfThisWorld.class));
|
||||
cards.add(new SetCardInfo("Nyx Weaver", 933, Rarity.UNCOMMON, mage.cards.n.NyxWeaver.class));
|
||||
cards.add(new SetCardInfo("Nyxborn Behemoth", 742, Rarity.RARE, mage.cards.n.NyxbornBehemoth.class));
|
||||
cards.add(new SetCardInfo("Oath of Gideon", 830, Rarity.RARE, mage.cards.o.OathOfGideon.class));
|
||||
cards.add(new SetCardInfo("Oath of Jace", 854, Rarity.RARE, mage.cards.o.OathOfJace.class));
|
||||
cards.add(new SetCardInfo("Oath of Teferi", 934, Rarity.RARE, mage.cards.o.OathOfTeferi.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
package mage.abilities.dynamicvalue.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.abilities.hint.ValueHint;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TotalPermanentsManaValue implements DynamicValue {
|
||||
|
||||
private final String message;
|
||||
private final ValueHint hint;
|
||||
private final FilterPermanent filter;
|
||||
|
||||
public TotalPermanentsManaValue(FilterPermanent filter) {
|
||||
this.filter = filter.copy();
|
||||
this.message = "the total mana value of " + filter.getMessage();
|
||||
this.hint = new ValueHint("Total mana value of " + filter.getMessage(), this);
|
||||
}
|
||||
|
||||
private TotalPermanentsManaValue(final TotalPermanentsManaValue value) {
|
||||
this.filter = value.filter.copy();
|
||||
this.message = value.message;
|
||||
this.hint = value.hint.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TotalPermanentsManaValue copy() {
|
||||
return new TotalPermanentsManaValue(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
int totalCMC = 0;
|
||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(
|
||||
filter,
|
||||
sourceAbility.getControllerId(),
|
||||
sourceAbility,
|
||||
game);
|
||||
for (Permanent permanent : permanents) {
|
||||
totalCMC += permanent.getManaValue();
|
||||
}
|
||||
return totalCMC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
public Hint getHint() {
|
||||
return hint;
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ public class ValueHint implements Hint {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Hint copy() {
|
||||
public ValueHint copy() {
|
||||
return new ValueHint(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -483,6 +483,14 @@ public final class StaticFilters {
|
|||
FILTER_CONTROLLED_PERMANENT_ENCHANTMENT.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterControlledPermanent FILTER_CONTROLLED_ANOTHER_ENCHANTMENT_SHORT_TEXT = new FilterControlledPermanent("another enchantment");
|
||||
|
||||
static {
|
||||
FILTER_CONTROLLED_ANOTHER_ENCHANTMENT_SHORT_TEXT.add(AnotherPredicate.instance);
|
||||
FILTER_CONTROLLED_ANOTHER_ENCHANTMENT_SHORT_TEXT.add(CardType.ENCHANTMENT.getPredicate());
|
||||
FILTER_CONTROLLED_ANOTHER_ENCHANTMENT_SHORT_TEXT.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_LAND = new FilterControlledLandPermanent();
|
||||
|
||||
static {
|
||||
|
|
@ -625,6 +633,14 @@ public final class StaticFilters {
|
|||
FILTER_CONTROLLED_CREATURES.setLockedFilter(true);
|
||||
}
|
||||
|
||||
|
||||
public static final FilterControlledCreaturePermanent FILTER_OTHER_CONTROLLED_CREATURES = new FilterControlledCreaturePermanent("other creatures you control");
|
||||
|
||||
static {
|
||||
FILTER_OTHER_CONTROLLED_CREATURES.add(AnotherPredicate.instance);
|
||||
FILTER_OTHER_CONTROLLED_CREATURES.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterControlledCreaturePermanent FILTER_CONTROLLED_A_CREATURE = new FilterControlledCreaturePermanent("a creature you control");
|
||||
|
||||
static {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue