mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
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:
parent
5a0d99ee6f
commit
6804216ddc
7 changed files with 252 additions and 2 deletions
71
Mage.Sets/src/mage/cards/g/GarrukUnleashed.java
Normal file
71
Mage.Sets/src/mage/cards/g/GarrukUnleashed.java
Normal 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);
|
||||
}
|
||||
}
|
86
Mage.Sets/src/mage/cards/g/GarruksHarbinger.java
Normal file
86
Mage.Sets/src/mage/cards/g/GarruksHarbinger.java
Normal 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;
|
||||
}
|
||||
}
|
65
Mage.Sets/src/mage/cards/g/GarruksUprising.java
Normal file
65
Mage.Sets/src/mage/cards/g/GarruksUprising.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue