forked from External/mage
Refactor Devour ability; [LTC] Implement Feasting Hobbit (#10708)
* [LTC] Implement Feasting Hobbit Refactor DevourEffect and its text generation, to be more permissive in the future. * change DevourAbility to have the constructor parameters of DevourEffect * only pluralize when there is more than 1 devoured permanent. * added more unit tests than there are cards with devour * public -> private filter of Caprichrome.
This commit is contained in:
parent
3d3358cd05
commit
40e508ac19
24 changed files with 535 additions and 132 deletions
|
|
@ -1,12 +1,10 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -17,6 +15,8 @@ import mage.game.events.EntersTheBattlefieldEvent;
|
|||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
|
|
@ -30,7 +30,7 @@ public final class BloodsporeThrinax extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// Devour 1
|
||||
this.addAbility(new DevourAbility(DevourEffect.DevourFactor.Devour1));
|
||||
this.addAbility(new DevourAbility(1));
|
||||
|
||||
// Each other creature you control enters the battlefield with an additional X +1/+1 counters on it, where X is the number of +1/+1 counters on Bloodspire Thrinax.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BloodsporeThrinaxEntersBattlefieldEffect()));
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.common.DamageAllEffect;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -13,6 +11,8 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -27,7 +27,7 @@ public final class CalderaHellion extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
// Devour 1 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour1));
|
||||
this.addAbility(new DevourAbility(1));
|
||||
|
||||
// When Caldera Hellion enters the battlefield, it deals 3 damage to each creature.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect(3, "it", new FilterCreaturePermanent())));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.FlashAbility;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
|
|
@ -9,6 +8,8 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterControlledArtifactPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -17,6 +18,8 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class Caprichrome extends CardImpl {
|
||||
|
||||
private static final FilterControlledPermanent filter = new FilterControlledArtifactPermanent("artifact");
|
||||
|
||||
public Caprichrome(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{W}");
|
||||
|
||||
|
|
@ -31,7 +34,7 @@ public final class Caprichrome extends CardImpl {
|
|||
this.addAbility(VigilanceAbility.getInstance());
|
||||
|
||||
// Devour artifact 1
|
||||
this.addAbility(new DevourAbility(DevourEffect.DevourFactor.DevourArtifact1));
|
||||
this.addAbility(new DevourAbility(1, filter));
|
||||
}
|
||||
|
||||
private Caprichrome(final Caprichrome card) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package mage.cards.f;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.keyword.ConvokeAbility;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
|
|
@ -31,7 +30,7 @@ public final class FeasterOfFools extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Devour 2
|
||||
this.addAbility(new DevourAbility(DevourEffect.DevourFactor.Devour2));
|
||||
this.addAbility(new DevourAbility(2));
|
||||
}
|
||||
|
||||
private FeasterOfFools(final FeasterOfFools card) {
|
||||
|
|
|
|||
45
Mage.Sets/src/mage/cards/f/FeastingHobbit.java
Normal file
45
Mage.Sets/src/mage/cards/f/FeastingHobbit.java
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package mage.cards.f;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesWithLessPowerEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class FeastingHobbit extends CardImpl {
|
||||
|
||||
public FeastingHobbit(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
|
||||
|
||||
this.subtype.add(SubType.HALFLING);
|
||||
this.subtype.add(SubType.CITIZEN);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// Devour Food 3
|
||||
this.addAbility(new DevourAbility(3, StaticFilters.FILTER_CONTROLLED_FOOD));
|
||||
|
||||
// Creatures with power less than Feasting Hobbit's power can't block it.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByCreaturesWithLessPowerEffect()));
|
||||
}
|
||||
|
||||
private FeastingHobbit(final FeastingHobbit card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeastingHobbit copy() {
|
||||
return new FeastingHobbit(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.FlashAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -11,6 +9,8 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -28,7 +28,7 @@ public final class GluttonousSlime extends CardImpl {
|
|||
this.addAbility(FlashAbility.getInstance());
|
||||
|
||||
// Devour 1 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour1));
|
||||
this.addAbility(new DevourAbility(1));
|
||||
}
|
||||
|
||||
private GluttonousSlime(final GluttonousSlime card) {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -25,7 +25,7 @@ public final class GorgerWurm extends CardImpl {
|
|||
this.toughness = new MageInt(5);
|
||||
|
||||
// Devour 1 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourEffect.DevourFactor.Devour1));
|
||||
this.addAbility(new DevourAbility(1));
|
||||
}
|
||||
|
||||
private GorgerWurm(final GorgerWurm card) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import mage.abilities.common.SimpleStaticAbility;
|
|||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.condition.common.DevouredCreaturesCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
|
|
@ -34,7 +33,7 @@ public final class HellkiteHatchling extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// Devour 1 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour1));
|
||||
this.addAbility(new DevourAbility(1));
|
||||
|
||||
// Hellkite Hatchling has flying and trample if it devoured a creature.
|
||||
Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.DevouredCreaturesCount;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -13,6 +11,8 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -30,7 +30,7 @@ public final class MarrowChomper extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
// Devour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourEffect.DevourFactor.Devour2));
|
||||
this.addAbility(new DevourAbility(2));
|
||||
|
||||
// When Marrow Chomper enters the battlefield, you gain 2 life for each creature it devoured.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(new DevouredCreaturesCount(2))));
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -16,6 +14,8 @@ import mage.constants.TargetController;
|
|||
import mage.counters.CounterType;
|
||||
import mage.game.permanent.token.SaprolingToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -30,7 +30,7 @@ public final class Mycoloth extends CardImpl {
|
|||
this.toughness = new MageInt(4);
|
||||
|
||||
// Devour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour2));
|
||||
this.addAbility(new DevourAbility(2));
|
||||
|
||||
// At the beginning of your upkeep, create a 1/1 green Saproling creature token for each +1/+1 counter on Mycoloth.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
|
||||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
|
|
@ -12,6 +10,8 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -30,7 +30,7 @@ public final class PredatorDragon extends CardImpl {
|
|||
this.addAbility(HasteAbility.getInstance());
|
||||
|
||||
// Devour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour2));
|
||||
this.addAbility(new DevourAbility(2));
|
||||
}
|
||||
|
||||
private PredatorDragon(final PredatorDragon card) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
|
||||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -17,6 +15,8 @@ import mage.constants.SubType;
|
|||
import mage.counters.CounterType;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -34,7 +34,7 @@ public final class PreyseizerDragon extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Devour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour2));
|
||||
this.addAbility(new DevourAbility(2));
|
||||
|
||||
// Whenever Preyseizer Dragon attacks, it deals damage to any target equal to the number of +1/+1 counters on Preyseizer Dragon.
|
||||
Ability ability = new AttacksTriggeredAbility(new DamageTargetEffect(new CountersSourceCount(CounterType.P1P1)), false);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DamageMultiEffect;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -37,7 +36,7 @@ public final class RavenousGigantotherium extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
// Devour 3
|
||||
this.addAbility(new DevourAbility(DevourEffect.DevourFactor.Devour3));
|
||||
this.addAbility(new DevourAbility(3));
|
||||
|
||||
// When Ravenous Gigantotherium enters the battlefield, it deals X damage divided as you choose among up to X target creatures, where X is its power. Each of those creatures deals damage equal to its power to Ravenous Gigantotherium.
|
||||
this.addAbility(new RavenousGigantotheriumAbility());
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.DevouredCreaturesCount;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -13,6 +11,8 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -27,7 +27,7 @@ public final class Skullmulcher extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
// Devour 1 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour1));
|
||||
this.addAbility(new DevourAbility(1));
|
||||
|
||||
// When Skullmulcher enters the battlefield, draw a card for each creature it devoured.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.DevouredCreaturesCount;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.effects.common.discard.DiscardTargetEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -15,6 +13,8 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.target.TargetPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -29,7 +29,7 @@ public final class TarFiend extends CardImpl {
|
|||
this.toughness = new MageInt(4);
|
||||
|
||||
// Devour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour2));
|
||||
this.addAbility(new DevourAbility(2));
|
||||
|
||||
// When Tar Fiend enters the battlefield, target player discards a card for each creature it devoured.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(new DevouredCreaturesCount()));
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -31,7 +31,7 @@ public final class ThornThrashViashino extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// Devour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour2));
|
||||
this.addAbility(new DevourAbility(2));
|
||||
|
||||
// {G}: Thorn-Thrash Viashino gains trample until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn),new ManaCostsImpl<>("{G}")));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -11,6 +9,8 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -18,7 +18,7 @@ import mage.constants.SuperType;
|
|||
public final class ThromokTheInsatiable extends CardImpl {
|
||||
|
||||
public ThromokTheInsatiable(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{G}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}");
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HELLION);
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ public final class ThromokTheInsatiable extends CardImpl {
|
|||
this.toughness = new MageInt(0);
|
||||
|
||||
// Devour X, where X is the number of creatures devoured this way (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with X +1/+1 counters on it for each of those creatures.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.DevourX));
|
||||
this.addAbility(DevourAbility.DevourX());
|
||||
}
|
||||
|
||||
private ThromokTheInsatiable(final ThromokTheInsatiable card) {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -25,7 +25,7 @@ public final class ThunderThrashElder extends CardImpl {
|
|||
this.toughness = new MageInt(1);
|
||||
|
||||
// Devour 3 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour3));
|
||||
this.addAbility(new DevourAbility(3));
|
||||
}
|
||||
|
||||
private ThunderThrashElder(final ThunderThrashElder card) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import mage.abilities.dynamicvalue.DynamicValue;
|
|||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -36,7 +35,7 @@ public final class VoraciousDragon extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Devour 1 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with that many +1/+1 counters on it.)
|
||||
this.addAbility(new DevourAbility(DevourFactor.Devour1));
|
||||
this.addAbility(new DevourAbility(1));
|
||||
|
||||
// When Voracious Dragon enters the battlefield, it deals damage to any target equal to twice the number of Goblins it devoured.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(TwiceDevouredGoblins.instance, "it"), false);
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Farmer Cotton", 55, Rarity.RARE, mage.cards.f.FarmerCotton.class));
|
||||
cards.add(new SetCardInfo("Farseek", 244, Rarity.COMMON, mage.cards.f.Farseek.class));
|
||||
cards.add(new SetCardInfo("Fealty to the Realm", 21, Rarity.RARE, mage.cards.f.FealtyToTheRealm.class));
|
||||
cards.add(new SetCardInfo("Feasting Hobbit", 37, Rarity.RARE, mage.cards.f.FeastingHobbit.class));
|
||||
cards.add(new SetCardInfo("Feed the Swarm", 200, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class));
|
||||
cards.add(new SetCardInfo("Fell the Mighty", 167, Rarity.RARE, mage.cards.f.FellTheMighty.class));
|
||||
cards.add(new SetCardInfo("Field of Ruin", 308, Rarity.UNCOMMON, mage.cards.f.FieldOfRuin.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,354 @@
|
|||
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* 702.82. Devour
|
||||
* <p>
|
||||
* 702.82a Devour is a static ability. “Devour N” means “As this object enters the battlefield, you may sacrifice any number of creatures. This permanent enters the battlefield with N +1/+1 counters on it for each creature sacrificed this way.”
|
||||
* <p>
|
||||
* 702.82b Some objects have abilities that refer to the number of creatures the permanent devoured. “It devoured” means “sacrificed as a result of its devour ability as it entered the battlefield.”
|
||||
* <p>
|
||||
* 702.82c Devour [quality] is a variant of devour. “Devour [quality] N” means “As this object enters the battlefield, you may sacrifice any number of [quality] permanents. This permanent enters the battlefield with N +1/+1 counters on it for each permanent sacrificed this way.”
|
||||
*
|
||||
* @author Susucr
|
||||
*/
|
||||
public class DevourTest extends CardTestPlayerBase {
|
||||
|
||||
private void expectedPossibleTest(
|
||||
String devourer,
|
||||
String devourTargets,
|
||||
int assertCounter,
|
||||
boolean assertLion,
|
||||
boolean assertMyr,
|
||||
boolean assertGinger,
|
||||
boolean assertRelic
|
||||
) {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
// Chromatic Orrery
|
||||
// {7}
|
||||
// Legendary Artifact
|
||||
//
|
||||
// You may spend mana as though it were mana of any color.
|
||||
//
|
||||
// {T}: Add {C}{C}{C}{C}{C}.
|
||||
//
|
||||
// {5}, {T}: Draw a card for each color among permanents you control.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Chromatic Orrery", 1);
|
||||
|
||||
addCard(Zone.HAND, playerA, devourer);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); // Creature
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Alpha Myr"); // Creature Artifact
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Gingerbrute"); // Artifact Creature — Food Golem
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Darksteel Relic"); // Artifact
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, devourer);
|
||||
if (devourTargets == "") {
|
||||
setChoice(playerA, false); // no to devour
|
||||
} else {
|
||||
setChoice(playerA, true); // yes to devour
|
||||
addTarget(playerA, devourTargets); // devour targets.
|
||||
}
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
if (devourer.equals(thromok) && assertCounter == 0) {
|
||||
// Thromok is a 0/0, devouring nothing, it just dies due to SBA.
|
||||
assertGraveyardCount(playerA, devourer, 1);
|
||||
} else {
|
||||
assertCounterCount(playerA, devourer, CounterType.P1P1, assertCounter);
|
||||
}
|
||||
|
||||
assertPermanentCount(playerA, "Silvercoat Lion", assertLion ? 1 : 0);
|
||||
assertGraveyardCount(playerA, "Silvercoat Lion", assertLion ? 0 : 1);
|
||||
assertPermanentCount(playerA, "Alpha Myr", assertMyr ? 1 : 0);
|
||||
assertGraveyardCount(playerA, "Alpha Myr", assertMyr ? 0 : 1);
|
||||
assertPermanentCount(playerA, "Gingerbrute", assertGinger ? 1 : 0);
|
||||
assertGraveyardCount(playerA, "Gingerbrute", assertGinger ? 0 : 1);
|
||||
assertPermanentCount(playerA, "Darksteel Relic", assertRelic ? 1 : 0);
|
||||
assertGraveyardCount(playerA, "Darksteel Relic", assertRelic ? 0 : 1);
|
||||
}
|
||||
|
||||
private void expectedIllegalTest(
|
||||
String devourer,
|
||||
String devourTargets
|
||||
) {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
// Chromatic Orrery
|
||||
// {7}
|
||||
// Legendary Artifact
|
||||
//
|
||||
// You may spend mana as though it were mana of any color.
|
||||
//
|
||||
// {T}: Add {C}{C}{C}{C}{C}.
|
||||
//
|
||||
// {5}, {T}: Draw a card for each color among permanents you control.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Chromatic Orrery", 1);
|
||||
|
||||
addCard(Zone.HAND, playerA, devourer);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); // Creature
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Alpha Myr"); // Creature Artifact
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Gingerbrute"); // Artifact Creature — Food Golem
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Darksteel Relic"); // Artifact
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, devourer);
|
||||
setChoice(playerA, true); // yes to devour
|
||||
addTarget(playerA, devourTargets); // devour targets.
|
||||
|
||||
boolean legal = true;
|
||||
try {
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
} catch (AssertionError e) {
|
||||
if (e.getMessage().startsWith("PlayerA - Targets list was setup by addTarget with [" + devourTargets + "], but not used")) {
|
||||
legal = false;
|
||||
}
|
||||
} finally {
|
||||
assert !legal;
|
||||
}
|
||||
}
|
||||
|
||||
// Gorger Wurm
|
||||
// {3}{R}{G}
|
||||
// Creature — Wurm
|
||||
//
|
||||
// Devour 1
|
||||
//
|
||||
// 5/5
|
||||
private static final String gorgerWurm = "Gorger Wurm";
|
||||
|
||||
@Test
|
||||
public void Wurm_NoDevour() {
|
||||
expectedPossibleTest(gorgerWurm, "",
|
||||
1 * 0, true, true, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Wurm_OneDevour() {
|
||||
expectedPossibleTest(gorgerWurm, "Alpha Myr",
|
||||
1 * 1, true, false, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Wurm_TwoDevour() {
|
||||
expectedPossibleTest(gorgerWurm, "Alpha Myr^Gingerbrute",
|
||||
1 * 2, true, false, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Wurm_ThreeDevour() {
|
||||
expectedPossibleTest(gorgerWurm, "Alpha Myr^Gingerbrute^Silvercoat Lion",
|
||||
1 * 3, false, false, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Wurm_IllegalDevour() {
|
||||
expectedIllegalTest(gorgerWurm, "Darksteel Relic");
|
||||
}
|
||||
|
||||
// Thromok the Insatiable
|
||||
// {3}{R}{G}
|
||||
// Legendary Creature — Hellion
|
||||
//
|
||||
// Devour X, where X is the number of creatures devoured this way
|
||||
//
|
||||
// 0/0
|
||||
private static final String thromok = "Thromok the Insatiable";
|
||||
|
||||
@Test
|
||||
public void Thromok_NoDevour() {
|
||||
expectedPossibleTest(thromok, "",
|
||||
0 * 0, true, true, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Thromok_OneDevour() {
|
||||
expectedPossibleTest(thromok, "Alpha Myr",
|
||||
1 * 1, true, false, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Thromok_TwoDevour() {
|
||||
expectedPossibleTest(thromok, "Alpha Myr^Gingerbrute",
|
||||
2 * 2, true, false, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Thromok_ThreeDevour() {
|
||||
expectedPossibleTest(thromok, "Alpha Myr^Gingerbrute^Silvercoat Lion",
|
||||
3 * 3, false, false, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Thromok_IllegalDevour() {
|
||||
expectedIllegalTest(thromok, "Darksteel Relic");
|
||||
}
|
||||
|
||||
// Feasting Hobbit
|
||||
// {1}{G}
|
||||
// Creature — Halfling Citizen
|
||||
//
|
||||
// Devour Food 3
|
||||
//
|
||||
// Creatures with power less than Feasting Hobbit’s power can’t block it.
|
||||
private static final String hobbit = "Feasting Hobbit";
|
||||
|
||||
@Test
|
||||
public void Hobbit_NoDevour() {
|
||||
expectedPossibleTest(hobbit, "",
|
||||
3 * 0, true, true, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Hobbit_OneDevour() {
|
||||
expectedPossibleTest(hobbit, "Gingerbrute",
|
||||
3 * 1, true, true, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Hobbit_IllegalDevour() {
|
||||
expectedIllegalTest(hobbit, "Alpha Myr");
|
||||
}
|
||||
|
||||
// Caprichrome
|
||||
// {3}{W}
|
||||
// Artifact Creature — Goat
|
||||
//
|
||||
// Flash
|
||||
//
|
||||
// Vigilance
|
||||
//
|
||||
// Devour artifact 1
|
||||
//
|
||||
// 2/2
|
||||
private static final String caprichrome = "Caprichrome";
|
||||
|
||||
@Test
|
||||
public void Caprichrome_NoDevour() {
|
||||
expectedPossibleTest(caprichrome, "",
|
||||
1 * 0, true, true, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Caprichrome_OneDevour() {
|
||||
expectedPossibleTest(caprichrome, "Alpha Myr",
|
||||
1 * 1, true, false, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Caprichrome_TwoDevour() {
|
||||
expectedPossibleTest(caprichrome, "Alpha Myr^Gingerbrute",
|
||||
1 * 2, true, false, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Caprichrome_ThreeDevour() {
|
||||
expectedPossibleTest(caprichrome, "Alpha Myr^Gingerbrute^Darksteel Relic",
|
||||
1 * 3, true, false, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Caprichrome_IllegalDevour() {
|
||||
expectedIllegalTest(caprichrome, "Silvercoat Lion");
|
||||
}
|
||||
|
||||
// Hellkite Hatchling
|
||||
// {2}{R}{G}
|
||||
// Creature — Dragon
|
||||
//
|
||||
// Devour 1
|
||||
//
|
||||
// Hellkite Hatchling has flying and trample if it devoured a creature.
|
||||
//
|
||||
// 2/2
|
||||
private static final String hatchling = "Hellkite Hatchling";
|
||||
|
||||
@Test
|
||||
public void Hatchling_NoDevour() {
|
||||
expectedPossibleTest(hatchling, "",
|
||||
1 * 0, true, true, true, true);
|
||||
assertAbility(playerA, hatchling, FlyingAbility.getInstance(), false);
|
||||
assertAbility(playerA, hatchling, TrampleAbility.getInstance(), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Hatchling_OneDevour() {
|
||||
expectedPossibleTest(hatchling, "Alpha Myr",
|
||||
1 * 1, true, false, true, true);
|
||||
assertAbility(playerA, hatchling, FlyingAbility.getInstance(), true);
|
||||
assertAbility(playerA, hatchling, TrampleAbility.getInstance(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Hatchling_TwoDevour() {
|
||||
expectedPossibleTest(hatchling, "Alpha Myr^Gingerbrute",
|
||||
1 * 2, true, false, false, true);
|
||||
assertAbility(playerA, hatchling, FlyingAbility.getInstance(), true);
|
||||
assertAbility(playerA, hatchling, TrampleAbility.getInstance(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Hatchling_ThreeDevour() {
|
||||
expectedPossibleTest(hatchling, "Alpha Myr^Gingerbrute^Silvercoat Lion",
|
||||
1 * 3, false, false, false, true);
|
||||
assertAbility(playerA, hatchling, FlyingAbility.getInstance(), true);
|
||||
assertAbility(playerA, hatchling, TrampleAbility.getInstance(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Hatchling_IllegalDevour() {
|
||||
expectedIllegalTest(hatchling, "Darksteel Relic");
|
||||
}
|
||||
|
||||
// Marrow Chomper
|
||||
// {3}{B}{G}
|
||||
// Creature — Zombie Lizard
|
||||
//
|
||||
// Devour 2
|
||||
//
|
||||
// When Marrow Chomper enters the battlefield, you gain 2 life for each creature it devoured.
|
||||
private static final String chomper = "Marrow Chomper";
|
||||
|
||||
@Test
|
||||
public void Chomper_NoDevour() {
|
||||
expectedPossibleTest(chomper, "",
|
||||
2 * 0, true, true, true, true);
|
||||
assertLife(playerA, 20 + 2 * 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Chomper_OneDevour() {
|
||||
expectedPossibleTest(chomper, "Alpha Myr",
|
||||
2 * 1, true, false, true, true);
|
||||
assertLife(playerA, 20 + 2 * 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Chomper_TwoDevour() {
|
||||
expectedPossibleTest(chomper, "Alpha Myr^Gingerbrute",
|
||||
2 * 2, true, false, false, true);
|
||||
assertLife(playerA, 20 + 2 * 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Chomper_ThreeDevour() {
|
||||
expectedPossibleTest(chomper, "Alpha Myr^Gingerbrute^Silvercoat Lion",
|
||||
2 * 3, false, false, false, true);
|
||||
assertLife(playerA, 20 + 2 * 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Chomper_IllegalDevour() {
|
||||
expectedIllegalTest(chomper, "Darksteel Relic");
|
||||
}
|
||||
}
|
||||
|
|
@ -3,11 +3,11 @@ package mage.abilities.effects.common;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.EntersTheBattlefieldEvent;
|
||||
|
|
@ -16,6 +16,7 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
|
@ -32,20 +33,30 @@ import java.util.UUID;
|
|||
* to the number of creatures the permanent devoured. "It devoured" means
|
||||
* "sacrificed as a result of its devour ability as it entered the battlefield."
|
||||
*
|
||||
* @author LevelX2
|
||||
* @author LevelX2, Susucr
|
||||
*/
|
||||
public class DevourEffect extends ReplacementEffectImpl {
|
||||
|
||||
private final DevourFactor devourFactor;
|
||||
// how many counters per devoured permanent.
|
||||
// Integer.MAX_VALUE is a special value that means "X, where X is the number of devoured permanent"
|
||||
private final int devourFactor;
|
||||
// For text generation, the filter's message is expected to be the singular
|
||||
// type word in the devour ability. e.g. "Food" "artifact" "creature".
|
||||
// "creature" is a special case as the rule will not mention it.
|
||||
//
|
||||
// 's' will be added to pluralize, so far so good with the current text generation.
|
||||
private final FilterControlledPermanent filterDevoured;
|
||||
|
||||
public DevourEffect(DevourFactor devourFactor) {
|
||||
public DevourEffect(int devourFactor, FilterControlledPermanent filterDevoured) {
|
||||
super(Duration.EndOfGame, Outcome.Detriment);
|
||||
this.devourFactor = devourFactor;
|
||||
this.filterDevoured = filterDevoured;
|
||||
}
|
||||
|
||||
public DevourEffect(final DevourEffect effect) {
|
||||
private DevourEffect(final DevourEffect effect) {
|
||||
super(effect);
|
||||
this.devourFactor = effect.devourFactor;
|
||||
this.filterDevoured = effect.filterDevoured;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -75,12 +86,19 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
if (creature == null || controller == null) {
|
||||
return false;
|
||||
}
|
||||
Target target = new TargetControlledPermanent(1, Integer.MAX_VALUE, devourFactor.getFilter(), true);
|
||||
|
||||
FilterControlledPermanent filter = new FilterControlledPermanent(filterDevoured.getMessage() + "s to devour");
|
||||
for (Predicate predicate : filterDevoured.getPredicates()) {
|
||||
filter.add(predicate);
|
||||
}
|
||||
filter.add(AnotherPredicate.instance);
|
||||
|
||||
Target target = new TargetControlledPermanent(1, Integer.MAX_VALUE, filter, true);
|
||||
target.setRequired(false);
|
||||
if (!target.canChoose(source.getControllerId(), source, game)) {
|
||||
return false;
|
||||
}
|
||||
if (!controller.chooseUse(Outcome.Detriment, "Devour " + devourFactor.getCardType().toString().toLowerCase() + "s?", source, game)) {
|
||||
if (!controller.chooseUse(Outcome.Detriment, "Devour " + filterDevoured.getMessage() + "s?", source, game)) {
|
||||
return false;
|
||||
}
|
||||
controller.chooseTarget(Outcome.Detriment, target, source, game);
|
||||
|
|
@ -96,16 +114,19 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
devouredCreatures++;
|
||||
}
|
||||
}
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(creature.getLogName() + " devours " + devouredCreatures + " " + devourFactor.getCardType().toString().toLowerCase() + "s");
|
||||
}
|
||||
|
||||
game.informPlayers(creature.getLogName()
|
||||
+ " devours " + devouredCreatures + " "
|
||||
+ filterDevoured.getMessage() + (devouredCreatures > 1 ? "s" : "")
|
||||
);
|
||||
|
||||
game.getState().processAction(game); // need for multistep effects
|
||||
|
||||
int amountCounters;
|
||||
if (devourFactor == DevourFactor.DevourX) {
|
||||
if (devourFactor == Integer.MAX_VALUE) {
|
||||
amountCounters = devouredCreatures * devouredCreatures;
|
||||
} else {
|
||||
amountCounters = devouredCreatures * devourFactor.getFactor();
|
||||
amountCounters = devouredCreatures * devourFactor;
|
||||
}
|
||||
creature.addCounters(CounterType.P1P1.createInstance(amountCounters), source.getControllerId(), source, game);
|
||||
game.getState().setValue(creature.getId().toString() + "devoured", creaturesDevoured);
|
||||
|
|
@ -114,13 +135,38 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
StringBuilder sb = new StringBuilder(devourFactor.toString());
|
||||
sb.append(" <i>(As this enters the battlefield, you may sacrifice any number of ");
|
||||
sb.append(devourFactor.getCardType());
|
||||
sb.append("s. This creature enters the battlefield with ");
|
||||
sb.append(devourFactor.getRuleText());
|
||||
sb.append(")</i>");
|
||||
return sb.toString();
|
||||
String text = "Devour ";
|
||||
|
||||
String filterMessage = filterDevoured.getMessage();
|
||||
if (!filterMessage.equals("creature")) {
|
||||
text += filterMessage + " ";
|
||||
}
|
||||
|
||||
if (devourFactor == Integer.MAX_VALUE) {
|
||||
text += "X, where X is the number of " + filterMessage + "s devoured this way";
|
||||
} else {
|
||||
text += devourFactor;
|
||||
}
|
||||
|
||||
text += " <i>(As this enters the battlefield, you may sacrifice any number of "
|
||||
+ filterMessage + "s. "
|
||||
+ "This creature enters the battlefield with ";
|
||||
|
||||
if (devourFactor == Integer.MAX_VALUE) {
|
||||
text += "X +1/+1 counters on it for each of those creatures";
|
||||
} else {
|
||||
if (devourFactor == 2) {
|
||||
text += "twice ";
|
||||
} else if (devourFactor > 2) {
|
||||
text += CardUtil.numberToText(devourFactor) + " times ";
|
||||
}
|
||||
|
||||
text += "that many +1/+1 counters on it";
|
||||
}
|
||||
|
||||
text += ".)</i>";
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public List<Permanent> getDevouredCreatures(Game game, UUID permanentId) {
|
||||
|
|
@ -143,59 +189,4 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
public DevourEffect copy() {
|
||||
return new DevourEffect(this);
|
||||
}
|
||||
|
||||
public enum DevourFactor {
|
||||
|
||||
Devour1("Devour 1", "that many +1/+1 counters on it", 1),
|
||||
Devour2("Devour 2", "twice that many +1/+1 counters on it", 2),
|
||||
Devour3("Devour 3", "three times that many +1/+1 counters on it", 3),
|
||||
DevourArtifact1("Devour artifact 1", "that many +1/+1 counters on it", 1, CardType.ARTIFACT),
|
||||
DevourX("Devour X, where X is the number of creatures devoured this way", "X +1/+1 counters on it for each of those creatures", Integer.MAX_VALUE);
|
||||
|
||||
private final String text;
|
||||
private final String ruleText;
|
||||
private final int factor;
|
||||
private final CardType cardType;
|
||||
private final FilterControlledPermanent filter;
|
||||
|
||||
DevourFactor(String text, String ruleText, int factor) {
|
||||
this(text, ruleText, factor, CardType.CREATURE);
|
||||
}
|
||||
|
||||
DevourFactor(String text, String ruleText, int factor, CardType cardType) {
|
||||
this.text = text;
|
||||
this.ruleText = ruleText;
|
||||
this.factor = factor;
|
||||
this.cardType = cardType;
|
||||
this.filter = makeFilter(cardType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getRuleText() {
|
||||
return ruleText;
|
||||
}
|
||||
|
||||
public int getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
public CardType getCardType() {
|
||||
return cardType;
|
||||
}
|
||||
|
||||
public FilterControlledPermanent getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
private static final FilterControlledPermanent makeFilter(CardType cardType) {
|
||||
FilterControlledPermanent filter = new FilterControlledPermanent(cardType.toString().toLowerCase() + "s to devour");
|
||||
filter.add(cardType.getPredicate());
|
||||
filter.add(AnotherPredicate.instance);
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package mage.abilities.keyword;
|
|||
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.effects.common.DevourEffect.DevourFactor;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
|
||||
/**
|
||||
* 502.82. Devour
|
||||
|
|
@ -40,15 +41,28 @@ import mage.constants.Zone;
|
|||
* can't sacrifice the same creature to satisfy multiple devour abilities.) All
|
||||
* creatures devoured this way are sacrificed at the same time.
|
||||
*
|
||||
* @author LevelX2
|
||||
* @author LevelX2, Susucr
|
||||
*/
|
||||
public class DevourAbility extends SimpleStaticAbility {
|
||||
|
||||
public DevourAbility(DevourFactor devourFactor) {
|
||||
super(Zone.ALL, new DevourEffect(devourFactor));
|
||||
private static final FilterControlledPermanent filterCreature = new FilterControlledCreaturePermanent("creature");
|
||||
|
||||
// Integer.MAX_VALUE is a special value
|
||||
// for "devour X, where X is the number of devored permanents"
|
||||
// see DevourEffect for the full details.
|
||||
public static DevourAbility DevourX() {
|
||||
return new DevourAbility(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public DevourAbility(final DevourAbility ability) {
|
||||
public DevourAbility(int devourFactor) {
|
||||
this(devourFactor, filterCreature);
|
||||
}
|
||||
|
||||
public DevourAbility(int devourFactor, FilterControlledPermanent filterDevoured) {
|
||||
super(Zone.ALL, new DevourEffect(devourFactor, filterDevoured));
|
||||
}
|
||||
|
||||
private DevourAbility(final DevourAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package mage.game.permanent.token;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.effects.common.DevourEffect;
|
||||
import mage.abilities.keyword.DevourAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.constants.CardType;
|
||||
|
|
@ -21,7 +20,7 @@ public final class DragonBroodmotherDragonToken extends TokenImpl {
|
|||
power = new MageInt(1);
|
||||
toughness = new MageInt(1);
|
||||
addAbility(FlyingAbility.getInstance());
|
||||
addAbility(new DevourAbility(DevourEffect.DevourFactor.Devour2));
|
||||
addAbility(new DevourAbility(2));
|
||||
}
|
||||
|
||||
public DragonBroodmotherDragonToken(final DragonBroodmotherDragonToken token) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue