mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 03:22:00 -08:00
[WOE] Implement Faerie Fencing (#10899)
This commit is contained in:
parent
99c1d0e8a5
commit
bee62063df
3 changed files with 151 additions and 0 deletions
111
Mage.Sets/src/mage/cards/f/FaerieFencing.java
Normal file
111
Mage.Sets/src/mage/cards/f/FaerieFencing.java
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
package mage.cards.f;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.MageObjectReference;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.WatcherScope;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.stack.Spell;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Xanderhall
|
||||||
|
*/
|
||||||
|
public final class FaerieFencing extends CardImpl {
|
||||||
|
|
||||||
|
public FaerieFencing(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{B}");
|
||||||
|
|
||||||
|
// Target creature gets -X/-X until end of turn. It gets an additional -3/-3 if you controlled a Faerie as you cast this spell.
|
||||||
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||||
|
this.getSpellAbility().addEffect(new FaerieFencingEffect());
|
||||||
|
this.getSpellAbility().addWatcher(new ControlledFaerieAsSpellCastWatcher());
|
||||||
|
}
|
||||||
|
|
||||||
|
private FaerieFencing(final FaerieFencing card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FaerieFencing copy() {
|
||||||
|
return new FaerieFencing(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FaerieFencingEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
FaerieFencingEffect() {
|
||||||
|
super(Outcome.UnboostCreature);
|
||||||
|
this.staticText = "target creature gets -X/-X until end of turn. It gets an additional -3/-3 if you controlled a Faerie as you cast this spell.";
|
||||||
|
}
|
||||||
|
|
||||||
|
private FaerieFencingEffect(final FaerieFencingEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
ControlledFaerieAsSpellCastWatcher watcher = game.getState().getWatcher(ControlledFaerieAsSpellCastWatcher.class);
|
||||||
|
MageObject mo = source.getSourceObject(game);
|
||||||
|
int reduction = source.getManaCostsToPay().getX();
|
||||||
|
|
||||||
|
if (watcher != null && mo != null && watcher.getCount(new MageObjectReference(mo, game)) > 0) {
|
||||||
|
reduction += 3;
|
||||||
|
}
|
||||||
|
game.addEffect(new BoostTargetEffect(-reduction, -reduction, Duration.EndOfTurn), source);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FaerieFencingEffect copy() {
|
||||||
|
return new FaerieFencingEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ControlledFaerieAsSpellCastWatcher extends Watcher {
|
||||||
|
|
||||||
|
private final FilterPermanent filter = new FilterPermanent(SubType.FAERIE, "");
|
||||||
|
|
||||||
|
ControlledFaerieAsSpellCastWatcher() {
|
||||||
|
super(WatcherScope.GAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final HashMap<MageObjectReference, Integer> permanentsWhenCast = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void watch(GameEvent event, Game game) {
|
||||||
|
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
|
||||||
|
Spell spell = game.getSpell(event.getTargetId());
|
||||||
|
if (spell != null) {
|
||||||
|
MageObjectReference mor = new MageObjectReference(spell, game);
|
||||||
|
permanentsWhenCast.put(mor, game.getBattlefield().countAll(filter, spell.getControllerId(), game));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
permanentsWhenCast.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount(MageObjectReference mor) {
|
||||||
|
return permanentsWhenCast.getOrDefault(mor, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -48,6 +48,7 @@ public final class WildsOfEldraine extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Evolving Wilds", 256, Rarity.COMMON, mage.cards.e.EvolvingWilds.class));
|
cards.add(new SetCardInfo("Evolving Wilds", 256, Rarity.COMMON, mage.cards.e.EvolvingWilds.class));
|
||||||
cards.add(new SetCardInfo("Expel the Interlopers", 13, Rarity.RARE, mage.cards.e.ExpelTheInterlopers.class));
|
cards.add(new SetCardInfo("Expel the Interlopers", 13, Rarity.RARE, mage.cards.e.ExpelTheInterlopers.class));
|
||||||
cards.add(new SetCardInfo("Faerie Dreamthief", 89, Rarity.UNCOMMON, mage.cards.f.FaerieDreamthief.class));
|
cards.add(new SetCardInfo("Faerie Dreamthief", 89, Rarity.UNCOMMON, mage.cards.f.FaerieDreamthief.class));
|
||||||
|
cards.add(new SetCardInfo("Faerie Fencing", 90, Rarity.UNCOMMON, mage.cards.f.FaerieFencing.class));
|
||||||
cards.add(new SetCardInfo("Farsight Ritual", 49, Rarity.RARE, mage.cards.f.FarsightRitual.class));
|
cards.add(new SetCardInfo("Farsight Ritual", 49, Rarity.RARE, mage.cards.f.FarsightRitual.class));
|
||||||
cards.add(new SetCardInfo("Faunsbane Troll", 203, Rarity.RARE, mage.cards.f.FaunsbaneTroll.class));
|
cards.add(new SetCardInfo("Faunsbane Troll", 203, Rarity.RARE, mage.cards.f.FaunsbaneTroll.class));
|
||||||
cards.add(new SetCardInfo("Flick a Coin", 128, Rarity.COMMON, mage.cards.f.FlickACoin.class));
|
cards.add(new SetCardInfo("Flick a Coin", 128, Rarity.COMMON, mage.cards.f.FlickACoin.class));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package org.mage.test.cards.single.woe;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
|
||||||
|
public class FaerieFencingTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
private static String SPELL = "Faerie Fencing";
|
||||||
|
private static String FAERIE = "Faerie Miscreant";
|
||||||
|
private static String LION = "Silvercoat Lion";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEffect() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, FAERIE, 1);
|
||||||
|
addCard(Zone.HAND, playerA, SPELL, 1);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, LION, 1);
|
||||||
|
addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
|
||||||
|
|
||||||
|
// Player A casts Faerie Fencing for 1, controls a Faerie so lion should get -4/-4
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, SPELL, LION);
|
||||||
|
setChoice(playerA, "X=1");
|
||||||
|
|
||||||
|
// Player B kills Faerie in response
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", FAERIE, SPELL);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
// Lion should still have died
|
||||||
|
assertGraveyardCount(playerB, LION, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue