[WOE] Implement Blossoming Tortoise (#10847)

* [WOE] Implement Blossoming Tortoise

* skip verify test on types

* apply review

* clean another unecessary text

---------

Co-authored-by: Evan Kranzler <theelk801@gmail.com>
This commit is contained in:
Susucre 2023-08-19 00:29:43 +02:00 committed by GitHub
parent 43de68afe3
commit 62dda45f2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 136 additions and 0 deletions

View file

@ -0,0 +1,133 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.MillCardsControllerEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInYourGraveyard;
import mage.util.CardUtil;
import java.util.UUID;
/**
*
* @author Susucr
*/
public final class BlossomingTortoise extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("land creatures");
static {
filter.add(CardType.LAND.getPredicate());
}
public BlossomingTortoise(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
this.subtype.add(SubType.TURTLE);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever Blossoming Tortoise enters the battlefield or attacks, mill three cards, then return a land card from your graveyard to the battlefield tapped.
Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new MillCardsControllerEffect(3));
ability.addEffect(new BlossomingTortoiseEffect());
this.addAbility(ability);
// Activated abilities of lands you control cost {1} less to activate.
this.addAbility(new SimpleStaticAbility(new BlossomingTortoiseCostReductionEffect()));
// Land creatures you control get +1/+1.
this.addAbility(new SimpleStaticAbility(
new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter)
));
}
private BlossomingTortoise(final BlossomingTortoise card) {
super(card);
}
@Override
public BlossomingTortoise copy() {
return new BlossomingTortoise(this);
}
}
class BlossomingTortoiseEffect extends OneShotEffect {
BlossomingTortoiseEffect() {
super(Outcome.Benefit);
staticText = ", then return a land card from your graveyard to the battlefield tapped";
}
private BlossomingTortoiseEffect(final BlossomingTortoiseEffect effect) {
super(effect);
}
@Override
public BlossomingTortoiseEffect copy() {
return new BlossomingTortoiseEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null || player.getGraveyard().count(StaticFilters.FILTER_CARD_LAND, game) < 1) {
return false;
}
TargetCard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_LAND);
target.setNotTarget(true);
player.choose(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
return card != null && player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null);
}
}
class BlossomingTortoiseCostReductionEffect extends CostModificationEffectImpl {
BlossomingTortoiseCostReductionEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "activated abilities of lands you control cost {1} less to activate";
}
private BlossomingTortoiseCostReductionEffect(BlossomingTortoiseCostReductionEffect effect) {
super(effect);
}
@Override
public BlossomingTortoiseCostReductionEffect copy() {
return new BlossomingTortoiseCostReductionEffect(this);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
CardUtil.reduceCost(abilityToModify, 1);
return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (!(abilityToModify instanceof ActivatedAbility)) {
return false;
}
Permanent permanent = abilityToModify.getSourcePermanentIfItStillExists(game);
return permanent != null
&& permanent.isControlledBy(source.getControllerId())
&& permanent.isLand(game);
}
}

View file

@ -28,6 +28,7 @@ public final class WildsOfEldraine extends ExpansionSet {
cards.add(new SetCardInfo("Beanstalk Wurm", 161, Rarity.COMMON, mage.cards.b.BeanstalkWurm.class)); cards.add(new SetCardInfo("Beanstalk Wurm", 161, Rarity.COMMON, mage.cards.b.BeanstalkWurm.class));
cards.add(new SetCardInfo("Beseech the Mirror", 82, Rarity.MYTHIC, mage.cards.b.BeseechTheMirror.class)); cards.add(new SetCardInfo("Beseech the Mirror", 82, Rarity.MYTHIC, mage.cards.b.BeseechTheMirror.class));
cards.add(new SetCardInfo("Besotted Knight", 4, Rarity.COMMON, mage.cards.b.BesottedKnight.class)); cards.add(new SetCardInfo("Besotted Knight", 4, Rarity.COMMON, mage.cards.b.BesottedKnight.class));
cards.add(new SetCardInfo("Blossoming Tortoise", 163, Rarity.MYTHIC, mage.cards.b.BlossomingTortoise.class));
cards.add(new SetCardInfo("Bitter Chill", 44, Rarity.UNCOMMON, mage.cards.b.BitterChill.class)); cards.add(new SetCardInfo("Bitter Chill", 44, Rarity.UNCOMMON, mage.cards.b.BitterChill.class));
cards.add(new SetCardInfo("Break the Spell", 5, Rarity.COMMON, mage.cards.b.BreakTheSpell.class)); cards.add(new SetCardInfo("Break the Spell", 5, Rarity.COMMON, mage.cards.b.BreakTheSpell.class));
cards.add(new SetCardInfo("Callous Sell-Sword", 221, Rarity.UNCOMMON, mage.cards.c.CallousSellSword.class)); cards.add(new SetCardInfo("Callous Sell-Sword", 221, Rarity.UNCOMMON, mage.cards.c.CallousSellSword.class));

View file

@ -136,6 +136,7 @@ public class VerifyCardDataTest {
skipListAddName(SKIP_LIST_TYPE, "UST", "capital offense"); // uses "instant" instead "Instant" as a joke card skipListAddName(SKIP_LIST_TYPE, "UST", "capital offense"); // uses "instant" instead "Instant" as a joke card
skipListAddName(SKIP_LIST_TYPE, "WOE", "Knight of Doves"); // temporary skipListAddName(SKIP_LIST_TYPE, "WOE", "Knight of Doves"); // temporary
skipListAddName(SKIP_LIST_TYPE, "WOE", "Faunsbane Troll"); // temporary skipListAddName(SKIP_LIST_TYPE, "WOE", "Faunsbane Troll"); // temporary
skipListAddName(SKIP_LIST_TYPE, "WOE", "Blossoming Tortoise"); // temporary
skipListAddName(SKIP_LIST_TYPE, "WOE", "Ashiok's Reaper"); // temporary skipListAddName(SKIP_LIST_TYPE, "WOE", "Ashiok's Reaper"); // temporary
skipListAddName(SKIP_LIST_TYPE, "WOE", "Agatha's Champion"); // temporary skipListAddName(SKIP_LIST_TYPE, "WOE", "Agatha's Champion"); // temporary
@ -146,6 +147,7 @@ public class VerifyCardDataTest {
skipListAddName(SKIP_LIST_SUBTYPE, "UND", "Elvish Impersonators"); skipListAddName(SKIP_LIST_SUBTYPE, "UND", "Elvish Impersonators");
skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Knight of Doves"); // temporary skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Knight of Doves"); // temporary
skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Faunsbane Troll"); // temporary skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Faunsbane Troll"); // temporary
skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Blossoming Tortoise"); // temporary
skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Ashiok's Reaper"); // temporary skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Ashiok's Reaper"); // temporary
skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Agatha's Champion"); // temporary skipListAddName(SKIP_LIST_SUBTYPE, "WOE", "Agatha's Champion"); // temporary