[WOE] Implement Faerie Fencing (#10899)

This commit is contained in:
Vivian Greenslade 2023-08-20 20:05:54 -02:30 committed by GitHub
parent 99c1d0e8a5
commit bee62063df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 151 additions and 0 deletions

View 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);
}
}

View file

@ -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("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 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("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));

View file

@ -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);
}
}