[WOE] Implement Icewrought Sentry (#10879)

* [WOE] Implement Icewrought Sentry

* add tests for the new trigger

---------

Co-authored-by: Evan Kranzler <theelk801@gmail.com>
This commit is contained in:
Susucre 2023-08-21 15:22:29 +02:00 committed by GitHub
parent 4af977289e
commit ecbc1dfa81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 245 additions and 0 deletions

View file

@ -0,0 +1,63 @@
package mage.cards.i;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.TapUntappedPermanentTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author Susucr
*/
public final class IcewroughtSentry extends CardImpl {
public IcewroughtSentry(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.ELEMENTAL);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Whenever Icewrought Sentry attacks, you may pay {1}{U}. When you do, tap target creature an opponent controls.
ReflexiveTriggeredAbility reflexive = new ReflexiveTriggeredAbility(new TapTargetEffect(), false);
reflexive.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(new AttacksTriggeredAbility(
new DoWhenCostPaid(
reflexive, new ManaCostsImpl<>("{1}{U}"),
"pay to tap a creature?"
)
));
// Whenever you tap an untapped creature an opponent controls, Icewrought Sentry gets +2/+1 until end of turn.
this.addAbility(new TapUntappedPermanentTriggeredAbility(
new BoostSourceEffect(2, 1, Duration.EndOfTurn),
StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE
));
}
private IcewroughtSentry(final IcewroughtSentry card) {
super(card);
}
@Override
public IcewroughtSentry copy() {
return new IcewroughtSentry(this);
}
}

View file

@ -64,6 +64,7 @@ public final class WildsOfEldraine extends ExpansionSet {
cards.add(new SetCardInfo("Harried Spearguard", 135, Rarity.COMMON, mage.cards.h.HarriedSpearguard.class));
cards.add(new SetCardInfo("Hopeless Nightmare", 95, Rarity.COMMON, mage.cards.h.HopelessNightmare.class));
cards.add(new SetCardInfo("Howling Galefang", 175, Rarity.UNCOMMON, mage.cards.h.HowlingGalefang.class));
cards.add(new SetCardInfo("Icewrought Sentry", 55, Rarity.UNCOMMON, mage.cards.i.IcewroughtSentry.class));
cards.add(new SetCardInfo("Ingenious Prodigy", 56, Rarity.RARE, mage.cards.i.IngeniousProdigy.class));
cards.add(new SetCardInfo("Into the Fae Court", 57, Rarity.COMMON, mage.cards.i.IntoTheFaeCourt.class));
cards.add(new SetCardInfo("Island", 263, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));

View file

@ -0,0 +1,133 @@
package org.mage.test.cards.single.woe;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author Susucr
*/
public class IcewroughtSentryTest extends CardTestPlayerBase {
/**
* Icewrought Sentry
* {2}{U}
* Creature Elemental Soldier
* <p>
* Vigilance
* Whenever Icewrought Sentry attacks, you may pay {1}{U}. When you do, tap target creature an opponent controls.
* Whenever you tap an untapped creature an opponent controls, Icewrought Sentry gets +2/+1 until end of turn.
* <p>
* 2/3
*/
private static final String sentry = "Icewrought Sentry";
/**
* Ice
* {1}{U}
* Instant
* <p>
* Tap target permanent.
* <p>
* Draw a card.
*/
private static final String fireIce = "Fire // Ice";
// 2/1, will be tapped.
private static final String myr = "Alpha Myr";
@Test
public void triggerOnTapping() {
setStrictChooseMode(true);
addCard(Zone.HAND, playerA, fireIce);
addCard(Zone.BATTLEFIELD, playerA, sentry, 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
addCard(Zone.BATTLEFIELD, playerB, myr, 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ice", myr);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, sentry, 2 + 2, 3 + 1);
}
@Test
public void doesNotTriggerOnAlreadyTapped() {
setStrictChooseMode(true);
addCard(Zone.HAND, playerA, fireIce, 2);
addCard(Zone.BATTLEFIELD, playerA, sentry, 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
addCard(Zone.BATTLEFIELD, playerB, myr, 1);
// double ice, only 1 trigger
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ice", myr);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ice", myr);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, sentry, 2 + 2, 3 + 1);
}
@Test
public void doesNotTriggerOnYourCreature() {
setStrictChooseMode(true);
addCard(Zone.HAND, playerA, fireIce, 1);
addCard(Zone.BATTLEFIELD, playerA, sentry, 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
// double ice, only 1 trigger
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ice", sentry);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, sentry, 2, 3);
}
@Test
public void doesTriggerOncePerTappedOpponentCreature() {
setStrictChooseMode(true);
// Tap all creatures target player controls. Those creatures dont untap during that players next untap step.
addCard(Zone.HAND, playerA, "Sleep", 1);
addCard(Zone.BATTLEFIELD, playerA, sentry, 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
addCard(Zone.BATTLEFIELD, playerB, myr, 3);
// double ice, only 1 trigger
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sleep", playerB);
setChoice(playerA, "Whenever you tap an untapped creature an opponent controls, {this} gets +2/+1 until end of turn.", 2);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, sentry, 2 + 2 * 3, 3 + 1 * 3);
}
@Test
public void attackingDoesNotTrigger() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, myr, 1);
addCard(Zone.BATTLEFIELD, playerB, sentry, 1);
attack(1, playerA, myr);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPowerToughness(playerB, sentry, 2, 3);
assertLife(playerB, 20 - 2);
assertTapped(myr, true);
}
}

View file

@ -0,0 +1,48 @@
package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
* @author Susucr
*/
public class TapUntappedPermanentTriggeredAbility extends TriggeredAbilityImpl {
private final FilterPermanent filter;
public TapUntappedPermanentTriggeredAbility(Effect effect, FilterPermanent filter) {
super(Zone.BATTLEFIELD, effect);
this.filter = filter.copy();
setTriggerPhrase("Whenever you tap an untapped " + filter.getMessage() + ", ");
}
protected TapUntappedPermanentTriggeredAbility(final TapUntappedPermanentTriggeredAbility ability) {
super(ability);
this.filter = ability.filter.copy();
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TAPPED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
if (permanent == null) {
return false;
}
return getControllerId().equals(event.getPlayerId())
&& filter.match(permanent, getControllerId(), this, game);
}
@Override
public TapUntappedPermanentTriggeredAbility copy() {
return new TapUntappedPermanentTriggeredAbility(this);
}
}