Implement garruk cards (#6650)

* Implement Garruk's Harbinger

* inline ability

* Implement Garruk's Uprising

* Implement Garruk, Unleashed

* fix Garruk, Unleashed
This commit is contained in:
htrajan 2020-06-16 18:09:26 -07:00 committed by GitHub
parent 5a0d99ee6f
commit 6804216ddc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 252 additions and 2 deletions

View file

@ -0,0 +1,71 @@
package mage.cards.g;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.condition.common.OpponentControlsMoreCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.command.emblems.GarrukUnleashedEmblem;
import mage.game.permanent.token.BeastToken;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author htrajan
*/
public final class GarrukUnleashed extends CardImpl {
public GarrukUnleashed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{G}{G}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GARRUK);
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Up to one target creature gets +3/+3 and gains trample until end of turn.
Effect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn)
.setText("up to one target creature gets +3/+3");
LoyaltyAbility ability = new LoyaltyAbility(effect, 1);
effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)
.setText("and gains trample until end of turn");
ability.addEffect(effect);
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability);
// 2: Create a 3/3 green Beast creature token. Then if an opponent controls more creatures than you, put a loyalty counter on Garruk, Unleashed.
ability = new LoyaltyAbility(new CreateTokenEffect(new BeastToken()), -2);
ability.addEffect(new ConditionalOneShotEffect(
new AddCountersSourceEffect(CounterType.LOYALTY.createInstance()),
new OpponentControlsMoreCondition(new FilterCreaturePermanent()))
.setText("Then if an opponent controls more creatures than you, put a loyalty counter on {this}"));
this.addAbility(ability);
// 7: You get an emblem with "At the beginning of your end step, you may search your library for a creature card, put it onto the battlefield, then shuffle your library."
this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new GarrukUnleashedEmblem()), -7));
}
private GarrukUnleashed(final GarrukUnleashed card) {
super(card);
}
@Override
public GarrukUnleashed copy() {
return new GarrukUnleashed(this);
}
}

View file

@ -0,0 +1,86 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.keyword.HexproofFromBlackAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import java.util.UUID;
/**
*
* @author htrajan
*/
public final class GarruksHarbinger extends CardImpl {
public GarruksHarbinger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// Hexproof from Black
this.addAbility(HexproofFromBlackAbility.getInstance());
// Whenever Garruk's Harbinger deals combat damage to a player or planeswalker, look at that many cards from the top of your library. You may reveal a creature card or Garruk planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
this.addAbility(
new DealsCombatDamageToAPlayerTriggeredAbility(new GarruksHarbingerEffect(), false, true)
.setOrPlaneswalker(true)
);
}
private GarruksHarbinger(final GarruksHarbinger card) {
super(card);
}
@Override
public GarruksHarbinger copy() {
return new GarruksHarbinger(this);
}
}
class GarruksHarbingerEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("a creature or Garruk planeswalker card");
static {
filter.add(Predicates.or(CardType.CREATURE.getPredicate(), Predicates.and(CardType.PLANESWALKER.getPredicate(), SubType.GARRUK.getPredicate())));
}
GarruksHarbingerEffect() {
super(Outcome.Benefit);
staticText = "look at that many cards from the top of your library. You may reveal a creature card or Garruk planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order";
}
private GarruksHarbingerEffect(GarruksHarbingerEffect effect) {
super(effect);
}
@Override
public GarruksHarbingerEffect copy() {
return new GarruksHarbingerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Integer damage = (Integer) getValue("damage");
if (damage != null) {
LookLibraryAndPickControllerEffect effect = new LookLibraryAndPickControllerEffect(StaticValue.get(damage), false, StaticValue.get(1), filter, false);
effect.setBackInRandomOrder(true);
return effect.apply(game, source);
}
return false;
}
}

View file

@ -0,0 +1,65 @@
package mage.cards.g;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.FerociousCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.hint.common.FerociousHint;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import java.util.UUID;
/**
*
* @author htrajan
*/
public final class GarruksUprising extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("a creature with power 4 or greater");
static {
filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3));
}
public GarruksUprising(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
// When Garruk's Uprising enters the battlefield, if you control a creature with power 4 or greater, draw a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1), FerociousCondition.instance))
.addHint(FerociousHint.instance));
// Creatures you control have trample.
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
TrampleAbility.getInstance(), Duration.WhileOnBattlefield,
StaticFilters.FILTER_PERMANENT_CREATURES
)));
// Whenever a creature with power 4 or greater enters the battlefield under your control, draw a card.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), filter, false
));
}
private GarruksUprising(final GarruksUprising card) {
super(card);
}
@Override
public GarruksUprising copy() {
return new GarruksUprising(this);
}
}

View file

@ -111,8 +111,11 @@ public final class CoreSet2021 extends ExpansionSet {
cards.add(new SetCardInfo("Gadrak, the Crown-Scourge", 146, Rarity.RARE, mage.cards.g.GadrakTheCrownScourge.class));
cards.add(new SetCardInfo("Gale Swooper", 20, Rarity.COMMON, mage.cards.g.GaleSwooper.class));
cards.add(new SetCardInfo("Garruk's Gorehorn", 184, Rarity.COMMON, mage.cards.g.GarruksGorehorn.class));
cards.add(new SetCardInfo("Garruk's Harbinger", 185, Rarity.RARE, mage.cards.g.GarruksHarbinger.class));
cards.add(new SetCardInfo("Garruk's Uprising", 186, Rarity.UNCOMMON, mage.cards.g.GarruksUprising.class));
cards.add(new SetCardInfo("Garruk's Warsteed", 337, Rarity.RARE, mage.cards.g.GarruksWarsteed.class));
cards.add(new SetCardInfo("Garruk, Savage Herald", 336, Rarity.MYTHIC, mage.cards.g.GarrukSavageHerald.class));
cards.add(new SetCardInfo("Garruk, Unleashed", 183, Rarity.MYTHIC, mage.cards.g.GarrukUnleashed.class));
cards.add(new SetCardInfo("Ghostly Pilferer", 52, Rarity.RARE, mage.cards.g.GhostlyPilferer.class));
cards.add(new SetCardInfo("Glorious Anthem", 21, Rarity.RARE, mage.cards.g.GloriousAnthem.class));
cards.add(new SetCardInfo("Goblin Arsonist", 147, Rarity.COMMON, mage.cards.g.GoblinArsonist.class));

View file

@ -985,9 +985,9 @@ public class VerifyCardDataTest {
System.out.println();
System.out.println(card.getName() + " " + card.getManaCost().getText());
if (card instanceof SplitCard) {
card.getAbilities().getRules(card.getName()).stream().forEach(System.out::println);
card.getAbilities().getRules(card.getName()).forEach(System.out::println);
} else {
card.getRules().stream().forEach(System.out::println);
card.getRules().forEach(System.out::println);
}
});
}

View file

@ -15,6 +15,10 @@ public class BeginningOfYourEndStepTriggeredAbility extends TriggeredAbilityImpl
super(Zone.BATTLEFIELD, effect, optional);
}
public BeginningOfYourEndStepTriggeredAbility(Zone zone, Effect effect, boolean optional) {
super(zone, effect, optional);
}
public BeginningOfYourEndStepTriggeredAbility(final BeginningOfYourEndStepTriggeredAbility ability) {
super(ability);
}

View file

@ -0,0 +1,21 @@
package mage.game.command.emblems;
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.command.Emblem;
import mage.target.common.TargetCardInLibrary;
public class GarrukUnleashedEmblem extends Emblem {
// At the beginning of your end step, you may search your library for a creature card, put it onto the battlefield, then shuffle your library.
public GarrukUnleashedEmblem() {
this.setName("Emblem Garruk");
Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), false, true, Outcome.PutCreatureInPlay)
.setText("search your library for a creature card, put it onto the battlefield, then shuffle your library");
this.getAbilities().add(new BeginningOfYourEndStepTriggeredAbility(Zone.COMMAND, effect, true));
}
}