forked from External/mage
[LCI] Implement Kellan, Daring Traveler (#11332)
Also adds Map Token, a new Token with implicit rules:
> {1}, {T}, sacrifice {this}: target creature you control explores. Activate only as a sorcery.
This commit is contained in:
parent
7ec64639bd
commit
d440cf5b08
4 changed files with 184 additions and 0 deletions
141
Mage.Sets/src/mage/cards/k/KellanDaringTraveler.java
Normal file
141
Mage.Sets/src/mage/cards/k/KellanDaringTraveler.java
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.IntPlusDynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.abilities.hint.ValueHint;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Controllable;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.token.MapToken;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class KellanDaringTraveler extends AdventureCard {
|
||||
|
||||
private static final DynamicValue xValue = new IntPlusDynamicValue(1, KellanDynamicValue.instance);
|
||||
private static final Hint hint = new ValueHint("Number of opponents controlling an artifact", KellanDynamicValue.instance);
|
||||
|
||||
public KellanDaringTraveler(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{1}{W}", "Journey On", "{G}");
|
||||
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.FAERIE);
|
||||
this.subtype.add(SubType.SCOUT);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// Whenever Kellan, Daring Traveler attacks, reveal the top card of your library. If it's a creature card with mana value 3 or less, put it into your hand. Otherwise, you may put it into your graveyard.
|
||||
this.addAbility(new AttacksTriggeredAbility(new KellanDaringTravelerEffect()));
|
||||
|
||||
// Journey On
|
||||
// Create X Map tokens, where X is one plus the number of opponents who control an artifact.
|
||||
this.getSpellCard().getSpellAbility().addEffect(
|
||||
new CreateTokenEffect(new MapToken(), xValue)
|
||||
.setText("create X Map tokens, where X is one plus the number of opponents who control an artifact")
|
||||
);
|
||||
this.getSpellCard().getSpellAbility().addHint(hint);
|
||||
|
||||
this.finalizeAdventure();
|
||||
}
|
||||
|
||||
private KellanDaringTraveler(final KellanDaringTraveler card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KellanDaringTraveler copy() {
|
||||
return new KellanDaringTraveler(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum KellanDynamicValue implements DynamicValue {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
Set<UUID> playerControllingArtifacts = game
|
||||
.getBattlefield()
|
||||
.getActivePermanents(
|
||||
StaticFilters.FILTER_PERMANENT_ARTIFACT,
|
||||
sourceAbility.getControllerId(),
|
||||
sourceAbility, game
|
||||
).stream()
|
||||
.map(Controllable::getControllerId)
|
||||
.collect(Collectors.toSet());
|
||||
return game.getOpponents(sourceAbility.getControllerId())
|
||||
.stream()
|
||||
.filter(p -> playerControllingArtifacts.contains(p))
|
||||
.mapToInt(p -> 1)
|
||||
.sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KellanDynamicValue copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "X";
|
||||
}
|
||||
}
|
||||
|
||||
class KellanDaringTravelerEffect extends OneShotEffect {
|
||||
|
||||
public KellanDaringTravelerEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.staticText = "reveal the top card of your library. "
|
||||
+ "If it's a creature card with mana value 3 or less, put it into your hand. "
|
||||
+ "Otherwise, you may put it into your graveyard.";
|
||||
}
|
||||
|
||||
private KellanDaringTravelerEffect(final KellanDaringTravelerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KellanDaringTravelerEffect copy() {
|
||||
return new KellanDaringTravelerEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (controller == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (controller.getLibrary().hasCards()) {
|
||||
Card card = controller.getLibrary().getFromTop(game);
|
||||
Cards cards = new CardsImpl(card);
|
||||
controller.revealCards(sourceObject.getIdName(), cards, game);
|
||||
|
||||
if (card != null) {
|
||||
if (card.isCreature(game) && card.getManaValue() <= 3) {
|
||||
controller.moveCards(card, Zone.HAND, source, game);
|
||||
} else if (controller.chooseUse(Outcome.Neutral, "Put " + card.getIdName() + " in your graveyard?", source, game)) {
|
||||
controller.moveCards(card, Zone.GRAVEYARD, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ public final class LostCavernsOfIxalan extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Ghalta, Stampede Tyrant", 185, Rarity.MYTHIC, mage.cards.g.GhaltaStampedeTyrant.class));
|
||||
cards.add(new SetCardInfo("Huatli, Poet of Unity", 189, Rarity.MYTHIC, mage.cards.h.HuatliPoetOfUnity.class));
|
||||
cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kellan, Daring Traveler", 231, Rarity.RARE, mage.cards.k.KellanDaringTraveler.class));
|
||||
cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Ojer Axonil, Deepest Might", 317, Rarity.MYTHIC, mage.cards.o.OjerAxonilDeepestMight.class));
|
||||
cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ public enum SubType {
|
|||
FORTIFICATION("Fortification", SubTypeSet.ArtifactType),
|
||||
GOLD("Gold", SubTypeSet.ArtifactType),
|
||||
INCUBATOR("Incubator", SubTypeSet.ArtifactType),
|
||||
MAP("Map", SubTypeSet.ArtifactType),
|
||||
POWERSTONE("Powerstone", SubTypeSet.ArtifactType),
|
||||
TREASURE("Treasure", SubTypeSet.ArtifactType),
|
||||
VEHICLE("Vehicle", SubTypeSet.ArtifactType),
|
||||
|
|
|
|||
41
Mage/src/main/java/mage/game/permanent/token/MapToken.java
Normal file
41
Mage/src/main/java/mage/game/permanent/token/MapToken.java
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package mage.game.permanent.token;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
|
||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.keyword.ExploreTargetEffect;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class MapToken extends TokenImpl {
|
||||
|
||||
public MapToken() {
|
||||
super("Map Token", "Map token");
|
||||
cardType.add(CardType.ARTIFACT);
|
||||
subtype.add(SubType.MAP);
|
||||
|
||||
Ability ability = new ActivateAsSorceryActivatedAbility(
|
||||
new ExploreTargetEffect(false)
|
||||
.setText("target creature you control explores"),
|
||||
new GenericManaCost(1)
|
||||
);
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new SacrificeSourceCost());
|
||||
ability.addTarget(new TargetControlledCreaturePermanent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
protected MapToken(final MapToken token) {
|
||||
super(token);
|
||||
}
|
||||
|
||||
public MapToken copy() {
|
||||
return new MapToken(this);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue