forked from External/mage
[MH3] Implement Fangs of Kalonia, The Hunger Tide Rises, Wastescape Battlemage (#12383)
This commit is contained in:
parent
fd8cb28fc2
commit
53a5f53f78
10 changed files with 494 additions and 4 deletions
118
Mage.Sets/src/mage/cards/f/FangsOfKalonia.java
Normal file
118
Mage.Sets/src/mage/cards/f/FangsOfKalonia.java
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
package mage.cards.f;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.OverloadAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author notgreat
|
||||
*/
|
||||
public final class FangsOfKalonia extends CardImpl {
|
||||
|
||||
public FangsOfKalonia(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
|
||||
|
||||
// Put a +1/+1 counter on target creature you control, then double the number of +1/+1 counters on each creature that had a +1/+1 counter put on it this way.
|
||||
this.getSpellAbility().addEffect(new FangsOfKaloniaEffect());
|
||||
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
|
||||
|
||||
// Overload {4}{G}{G}
|
||||
this.addAbility(new OverloadAbility(
|
||||
this, new FangsOfKaloniaOverloadEffect(),
|
||||
new ManaCostsImpl<>("{4}{G}{G}")
|
||||
));
|
||||
}
|
||||
|
||||
private FangsOfKalonia(final FangsOfKalonia card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FangsOfKalonia copy() {
|
||||
return new FangsOfKalonia(this);
|
||||
}
|
||||
}
|
||||
|
||||
//Based on Spectacular Showdown
|
||||
class FangsOfKaloniaEffect extends OneShotEffect {
|
||||
|
||||
FangsOfKaloniaEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "put a +1/+1 counter on target creature you control, " +
|
||||
"then double the number of +1/+1 counters on each creature that had a +1/+1 counter put on it this way";
|
||||
}
|
||||
|
||||
private FangsOfKaloniaEffect(final FangsOfKaloniaEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FangsOfKaloniaEffect copy() {
|
||||
return new FangsOfKaloniaEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (permanent == null || !permanent.addCounters(CounterType.P1P1.createInstance(), source, game)) {
|
||||
return false;
|
||||
}
|
||||
return permanent.addCounters(CounterType.P1P1.createInstance(
|
||||
permanent.getCounters(game).getCount(CounterType.P1P1)), source.getControllerId(), source, game);
|
||||
}
|
||||
}
|
||||
|
||||
class FangsOfKaloniaOverloadEffect extends OneShotEffect {
|
||||
|
||||
FangsOfKaloniaOverloadEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "put a +1/+1 counter on each creature you control, " +
|
||||
"then double the number of +1/+1 counters on each creature that had a +1/+1 counter put on it this way";
|
||||
}
|
||||
|
||||
private FangsOfKaloniaOverloadEffect(final FangsOfKaloniaOverloadEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FangsOfKaloniaOverloadEffect copy() {
|
||||
return new FangsOfKaloniaOverloadEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
List<Permanent> permanents = game
|
||||
.getBattlefield()
|
||||
.getActivePermanents(
|
||||
StaticFilters.FILTER_CONTROLLED_CREATURE,
|
||||
source.getControllerId(), source, game
|
||||
)
|
||||
.stream()
|
||||
.filter(permanent -> permanent.addCounters(
|
||||
CounterType.P1P1.createInstance(), source, game
|
||||
))
|
||||
.collect(Collectors.toList());
|
||||
if (permanents.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (Permanent permanent : permanents){
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(
|
||||
permanent.getCounters(game).getCount(CounterType.P1P1)), source.getControllerId(), source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ class GodEternalBontuEffect extends OneShotEffect {
|
|||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Target target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true);
|
||||
Target target = new TargetSacrifice(0, Integer.MAX_VALUE, filter);
|
||||
if (!player.choose(outcome, target, source, game)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ class SpectacularShowdownOverloadEffect extends OneShotEffect {
|
|||
|
||||
SpectacularShowdownOverloadEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "put a double strike counter on each creature, " +
|
||||
"then goad each creature that had a double strike counter put on it this way";
|
||||
}
|
||||
|
||||
private SpectacularShowdownOverloadEffect(final SpectacularShowdownOverloadEffect effect) {
|
||||
|
|
|
|||
104
Mage.Sets/src/mage/cards/t/TheHungerTideRises.java
Normal file
104
Mage.Sets/src/mage/cards/t/TheHungerTideRises.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SagaAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.search.SearchLibraryGraveyardPutOntoBattlefieldEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.IzoniInsectToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetSacrifice;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author notgreat
|
||||
*/
|
||||
public final class TheHungerTideRises extends CardImpl {
|
||||
|
||||
public TheHungerTideRises(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
|
||||
|
||||
this.subtype.add(SubType.SAGA);
|
||||
|
||||
// (As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.)
|
||||
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_IV);
|
||||
|
||||
// I, II, III -- Create a 1/1 black and green Insect creature token.
|
||||
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_III, new CreateTokenEffect(new IzoniInsectToken()));
|
||||
|
||||
// IV -- Sacrifice any number of creatures. Search your library and/or graveyard for a creature card with mana value less than or equal to the number of creatures sacrificed this way and put it onto the battlefield. If you search your library this way, shuffle.
|
||||
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_IV, new HungerTideSacrificeSearchEffect());
|
||||
this.addAbility(sagaAbility);
|
||||
}
|
||||
|
||||
private TheHungerTideRises(final TheHungerTideRises card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheHungerTideRises copy() {
|
||||
return new TheHungerTideRises(this);
|
||||
}
|
||||
}
|
||||
|
||||
//Based on Scapeshift
|
||||
class HungerTideSacrificeSearchEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledPermanent("other permanents you control");
|
||||
|
||||
static {
|
||||
filter.add(AnotherPredicate.instance);
|
||||
}
|
||||
|
||||
HungerTideSacrificeSearchEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "Sacrifice any number of creatures. Search your library and/or graveyard for a creature card "
|
||||
+ "with mana value less than or equal to the number of creatures sacrificed this way "
|
||||
+ "and put it onto the battlefield. If you search your library this way, shuffle.";
|
||||
}
|
||||
|
||||
private HungerTideSacrificeSearchEffect(final HungerTideSacrificeSearchEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HungerTideSacrificeSearchEffect copy() {
|
||||
return new HungerTideSacrificeSearchEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
int amount = 0;
|
||||
TargetSacrifice sacrifices = new TargetSacrifice(0, Integer.MAX_VALUE, StaticFilters.FILTER_PERMANENT_CREATURES);
|
||||
if (controller.choose(Outcome.Sacrifice, sacrifices, source, game)) {
|
||||
for (UUID uuid : sacrifices.getTargets()) {
|
||||
Permanent creature = game.getPermanent(uuid);
|
||||
if (creature != null) {
|
||||
creature.sacrifice(source, game);
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
FilterCard filter = new FilterCreatureCard();
|
||||
filter.add(new ManaValuePredicate(ComparisonType.OR_LESS, amount));
|
||||
OneShotEffect searchEffect = new SearchLibraryGraveyardPutOntoBattlefieldEffect(filter);
|
||||
return searchEffect.apply(game, source);
|
||||
}
|
||||
}
|
||||
70
Mage.Sets/src/mage/cards/w/WastescapeBattlemage.java
Normal file
70
Mage.Sets/src/mage/cards/w/WastescapeBattlemage.java
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package mage.cards.w;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.condition.common.KickedCostCondition;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.CastSourceTriggeredAbility;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||
import mage.abilities.keyword.KickerAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author notgreat
|
||||
*/
|
||||
public final class WastescapeBattlemage extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter
|
||||
= new FilterArtifactOrEnchantmentPermanent("artifact or enchantment an opponent controls");
|
||||
|
||||
static {
|
||||
filter.add(TargetController.OPPONENT.getControllerPredicate());
|
||||
}
|
||||
|
||||
public WastescapeBattlemage(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{C}");
|
||||
|
||||
this.subtype.add(SubType.ELDRAZI);
|
||||
this.subtype.add(SubType.WIZARD);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// Kicker {G} and/or kicker {1}{U}
|
||||
KickerAbility kickerAbility = new KickerAbility("{G}");
|
||||
kickerAbility.addKickerCost("{1}{U}");
|
||||
this.addAbility(kickerAbility);
|
||||
|
||||
// When you cast this spell, if it was kicked with its {G} kicker, exile target artifact or enchantment an opponent controls.
|
||||
TriggeredAbility ability = new CastSourceTriggeredAbility(new ExileTargetEffect());
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new KickedCostCondition("{G}"),
|
||||
"When you cast this spell, if it was kicked with its {G} kicker, exile target artifact or enchantment an opponent controls."));
|
||||
|
||||
// When you cast this spell, if it was kicked with its {1}{U} kicker, return target creature an opponent controls to its owner's hand.
|
||||
TriggeredAbility ability2 = new CastSourceTriggeredAbility(new ReturnToHandTargetEffect());
|
||||
ability2.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability2, new KickedCostCondition("{1}{U}"),
|
||||
"When you cast this spell, if it was kicked with its {1}{U} kicker, return target creature an opponent controls to its owner's hand."));
|
||||
}
|
||||
|
||||
private WastescapeBattlemage(final WastescapeBattlemage card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WastescapeBattlemage copy() {
|
||||
return new WastescapeBattlemage(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -103,6 +103,7 @@ public final class ModernHorizons3 extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Faithful Watchdog", 185, Rarity.COMMON, mage.cards.f.FaithfulWatchdog.class));
|
||||
cards.add(new SetCardInfo("Fanatic of Rhonas", 152, Rarity.RARE, mage.cards.f.FanaticOfRhonas.class));
|
||||
cards.add(new SetCardInfo("Fanged Flames", 118, Rarity.COMMON, mage.cards.f.FangedFlames.class));
|
||||
cards.add(new SetCardInfo("Fangs of Kalonia", 153, Rarity.UNCOMMON, mage.cards.f.FangsOfKalonia.class));
|
||||
cards.add(new SetCardInfo("Fell the Profane", 244, Rarity.UNCOMMON, mage.cards.f.FellTheProfane.class));
|
||||
cards.add(new SetCardInfo("Fetid Gargantua", 94, Rarity.COMMON, mage.cards.f.FetidGargantua.class));
|
||||
cards.add(new SetCardInfo("Flare of Cultivation", 154, Rarity.RARE, mage.cards.f.FlareOfCultivation.class));
|
||||
|
|
@ -265,6 +266,7 @@ public final class ModernHorizons3 extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Temperamental Oozewagg", 172, Rarity.COMMON, mage.cards.t.TemperamentalOozewagg.class));
|
||||
cards.add(new SetCardInfo("Tempest Harvester", 73, Rarity.COMMON, mage.cards.t.TempestHarvester.class));
|
||||
cards.add(new SetCardInfo("Territory Culler", 173, Rarity.UNCOMMON, mage.cards.t.TerritoryCuller.class));
|
||||
cards.add(new SetCardInfo("The Hunger Tide Rises", 158, Rarity.UNCOMMON, mage.cards.t.TheHungerTideRises.class));
|
||||
cards.add(new SetCardInfo("The Necrobloom", 194, Rarity.RARE, mage.cards.t.TheNecrobloom.class));
|
||||
cards.add(new SetCardInfo("Thraben Charm", 45, Rarity.COMMON, mage.cards.t.ThrabenCharm.class));
|
||||
cards.add(new SetCardInfo("Thriving Skyclaw", 141, Rarity.COMMON, mage.cards.t.ThrivingSkyclaw.class));
|
||||
|
|
@ -289,6 +291,7 @@ public final class ModernHorizons3 extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Voltstorm Angel", 46, Rarity.UNCOMMON, mage.cards.v.VoltstormAngel.class));
|
||||
cards.add(new SetCardInfo("Warped Tusker", 16, Rarity.COMMON, mage.cards.w.WarpedTusker.class));
|
||||
cards.add(new SetCardInfo("Warren Soultrader", 110, Rarity.RARE, mage.cards.w.WarrenSoultrader.class));
|
||||
cards.add(new SetCardInfo("Wastescape Battlemage", 17, Rarity.UNCOMMON, mage.cards.w.WastescapeBattlemage.class));
|
||||
cards.add(new SetCardInfo("Waterlogged Teachings", 261, Rarity.UNCOMMON, mage.cards.w.WaterloggedTeachings.class));
|
||||
cards.add(new SetCardInfo("White Orchid Phantom", 47, Rarity.RARE, mage.cards.w.WhiteOrchidPhantom.class));
|
||||
cards.add(new SetCardInfo("Wight of the Reliquary", 207, Rarity.RARE, mage.cards.w.WightOfTheReliquary.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
package org.mage.test.cards.single.mh3;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author notgreat
|
||||
*/
|
||||
public class FangsOfKaloniaTest extends CardTestPlayerBase {
|
||||
/**
|
||||
* {@link mage.cards.f.FangsOfKalonia Fangs of Kalonia} {1}{G}
|
||||
* Sorcery
|
||||
* Put a +1/+1 counter on target creature you control, then double the number of +1/+1 counters on each creature that had a +1/+1 counter put on it this way.
|
||||
* Overload {4}{G}{G}
|
||||
**/
|
||||
private static final String fangs = "Fangs of Kalonia";
|
||||
|
||||
private static final String grizzly = "Grizzly Bears";
|
||||
private static final String arcbound = "Arcbound Lancer"; //0/0 with Modular 4
|
||||
@Test
|
||||
public void test_Basic() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, fangs, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, grizzly);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs, grizzly, true);
|
||||
checkPT("First Fangs", 1, PhaseStep.PRECOMBAT_MAIN, playerA, grizzly, 4, 4);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs, grizzly);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, grizzly, 8, 8);
|
||||
}
|
||||
@Test
|
||||
public void test_Overload() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, fangs);
|
||||
addCard(Zone.BATTLEFIELD, playerA, grizzly);
|
||||
addCard(Zone.BATTLEFIELD, playerA, arcbound);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs + " with overload");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, grizzly, 4, 4);
|
||||
assertPowerToughness(playerA, arcbound, 10, 10);
|
||||
}
|
||||
@Test
|
||||
public void test_Vorinclex() {
|
||||
addCard(Zone.HAND, playerA, fangs, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, grizzly);
|
||||
addCard(Zone.HAND, playerA, arcbound);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7+2+2);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Vorinclex, Monstrous Raider");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, true);
|
||||
checkPT("Played arcbound", 1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, 2, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs, grizzly, true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs, arcbound);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, grizzly, 2, 2);
|
||||
assertPowerToughness(playerA, arcbound, 2, 2);
|
||||
}
|
||||
@Test
|
||||
public void test_HardenedScales() {
|
||||
addCard(Zone.HAND, playerA, fangs, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, grizzly);
|
||||
addCard(Zone.HAND, playerA, arcbound);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7+2+2);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Hardened Scales");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, true);
|
||||
checkPT("Played arcbound", 1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, 5, 5);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs, grizzly, true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs, arcbound);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, grizzly, 7, 7);
|
||||
assertPowerToughness(playerA, arcbound, 15, 15);
|
||||
}
|
||||
@Test
|
||||
public void test_DoubleReplacement1() {
|
||||
addCard(Zone.HAND, playerA, fangs, 2);
|
||||
addCard(Zone.HAND, playerA, arcbound);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7+2);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Hardened Scales");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Vorinclex, Monstrous Raider");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound);
|
||||
setChoice(playerA, "Hardened Scales"); //(4+1)/2 = 2
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPT("Played arcbound", 1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, 2, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs, arcbound);
|
||||
setChoice(playerA, "Hardened Scales"); //adds (1+1)/2 = 1, success. Now 3 counters, double adds (3+1)/2 = 2
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, arcbound, 5, 5);
|
||||
}
|
||||
@Test
|
||||
public void test_DoubleReplacement2() {
|
||||
addCard(Zone.HAND, playerA, fangs, 2);
|
||||
addCard(Zone.HAND, playerA, arcbound);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7+2);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Hardened Scales");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Vorinclex, Monstrous Raider");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound);
|
||||
setChoice(playerA, "Vorinclex, Monstrous Raider"); //(4/2)+1 = 3
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPT("Played arcbound", 1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, 3, 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs, arcbound);
|
||||
setChoice(playerA, "Vorinclex, Monstrous Raider"); // adds (1/2), then no placement action to add to
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, arcbound, 3, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_VorinclexOverload() {
|
||||
addCard(Zone.HAND, playerA, fangs);
|
||||
addCard(Zone.BATTLEFIELD, playerA, grizzly);
|
||||
addCard(Zone.HAND, playerA, arcbound);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7+6);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Vorinclex, Monstrous Raider");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, true);
|
||||
checkPT("Played arcbound", 1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, 2, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs + " with overload");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, grizzly, 2, 2);
|
||||
assertPowerToughness(playerA, arcbound, 2, 2);
|
||||
}
|
||||
@Test
|
||||
public void test_HardenedScalesOverload() {
|
||||
addCard(Zone.HAND, playerA, fangs);
|
||||
addCard(Zone.BATTLEFIELD, playerA, grizzly);
|
||||
addCard(Zone.HAND, playerA, arcbound);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7+6);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Hardened Scales");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, true);
|
||||
checkPT("Played arcbound", 1, PhaseStep.PRECOMBAT_MAIN, playerA, arcbound, 5, 5);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fangs + " with overload");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, grizzly, 7, 7);
|
||||
assertPowerToughness(playerA, arcbound, 15, 15);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ public class KickedCostCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return KickerAbility.getKickedCounterStrict(game, source, kickerCostText) > 0;
|
||||
return KickerAbility.getKickedCounterStrict(game, source, kickerCostText) > 0
|
||||
|| KickerAbility.getSpellKickedCountStrict(game, source.getSourceId(), kickerCostText) > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,9 +273,16 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
* Find spell's kicked stats. Must be used on stack only, e.g. for SPELL_CAST events
|
||||
*/
|
||||
public static int getSpellKickedCount(Game game, UUID spellId) {
|
||||
return getSpellKickedCountStrict(game, spellId, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Find spell's kicked stats. Must be used on stack only, e.g. for SPELL_CAST events
|
||||
*/
|
||||
public static int getSpellKickedCountStrict(Game game, UUID spellId, String needKickerCost) {
|
||||
Spell spell = game.getSpellOrLKIStack(spellId);
|
||||
if (spell != null) {
|
||||
return KickerAbility.getKickedCounter(game, spell.getSpellAbility());
|
||||
return KickerAbility.getKickedCounterStrict(game, spell.getSpellAbility(), needKickerCost);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -795,6 +795,8 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
GameEvent addedAllEvent = GameEvent.getEvent(GameEvent.EventType.COUNTERS_ADDED, objectId, source, playerAddingCounters, counter.getName(), amount);
|
||||
addedAllEvent.setFlag(isEffectFlag);
|
||||
game.fireEvent(addedAllEvent);
|
||||
} else {
|
||||
returnCode = false;
|
||||
}
|
||||
} else {
|
||||
returnCode = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue