mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
[BRO] Implement The Temporal Anchor
This commit is contained in:
parent
accc5d2d0b
commit
4cb8466d07
4 changed files with 174 additions and 1 deletions
166
Mage.Sets/src/mage/cards/t/TheTemporalAnchor.java
Normal file
166
Mage.Sets/src/mage/cards/t/TheTemporalAnchor.java
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
package mage.cards.t;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.effects.AsThoughEffectImpl;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.keyword.ScryEffect;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.*;
|
||||||
|
import mage.game.ExileZone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class TheTemporalAnchor extends CardImpl {
|
||||||
|
|
||||||
|
public TheTemporalAnchor(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{U}{U}{U}");
|
||||||
|
|
||||||
|
this.addSuperType(SuperType.LEGENDARY);
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, scry 2.
|
||||||
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
|
||||||
|
new ScryEffect(2), TargetController.YOU, false
|
||||||
|
));
|
||||||
|
|
||||||
|
// Whenever you choose to put one or more cards on the bottom of your library while scrying, exile that many cards from the bottom of your library.
|
||||||
|
this.addAbility(new TheTemporalAnchorTriggeredAbility());
|
||||||
|
|
||||||
|
// During your turn, you may play cards exiled with The Temporal Anchor.
|
||||||
|
this.addAbility(new SimpleStaticAbility(new TheTemporalAnchorPlayEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TheTemporalAnchor(final TheTemporalAnchor card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TheTemporalAnchor copy() {
|
||||||
|
return new TheTemporalAnchor(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TheTemporalAnchorTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
TheTemporalAnchorTriggeredAbility() {
|
||||||
|
super(Zone.BATTLEFIELD, new TheTemporalAnchorExileEffect());
|
||||||
|
}
|
||||||
|
|
||||||
|
private TheTemporalAnchorTriggeredAbility(final TheTemporalAnchorTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TheTemporalAnchorTriggeredAbility copy() {
|
||||||
|
return new TheTemporalAnchorTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.SCRY_TO_BOTTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
if (isControlledBy(event.getPlayerId()) && event.getAmount() > 0) {
|
||||||
|
this.getEffects().setValue("amount", event.getAmount());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return "Whenever you choose to put one or more cards on the bottom of your library while scrying, " +
|
||||||
|
"exile that many cards from the bottom of your library.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TheTemporalAnchorExileEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
TheTemporalAnchorExileEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TheTemporalAnchorExileEffect(final TheTemporalAnchorExileEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TheTemporalAnchorExileEffect copy() {
|
||||||
|
return new TheTemporalAnchorExileEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
int amount = (Integer) getValue("amount");
|
||||||
|
if (player == null || amount < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int toSkip = Math.max(player.getLibrary().size() - amount, 0);
|
||||||
|
Set<Card> cards = player
|
||||||
|
.getLibrary()
|
||||||
|
.getCards(game)
|
||||||
|
.stream()
|
||||||
|
.skip(toSkip)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
return !cards.isEmpty() && player.moveCardsToExile(
|
||||||
|
cards, source, game, true,
|
||||||
|
CardUtil.getExileZoneId(game, source),
|
||||||
|
CardUtil.getSourceName(game, source)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TheTemporalAnchorPlayEffect extends AsThoughEffectImpl {
|
||||||
|
|
||||||
|
TheTemporalAnchorPlayEffect() {
|
||||||
|
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||||
|
staticText = "during your turn, you may play cards exiled with {this}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private TheTemporalAnchorPlayEffect(final TheTemporalAnchorPlayEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TheTemporalAnchorPlayEffect copy() {
|
||||||
|
return new TheTemporalAnchorPlayEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||||
|
if (!source.isControlledBy(affectedControllerId) || !game.isActivePlayer(affectedControllerId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Card card = game.getCard(objectId);
|
||||||
|
if (card == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UUID mainId = card.getMainCard().getId(); // for split cards
|
||||||
|
|
||||||
|
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source));
|
||||||
|
return exileZone != null
|
||||||
|
&& exileZone.contains(mainId)
|
||||||
|
&& game.getCard(mainId) != null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -249,6 +249,7 @@ public final class TheBrothersWar extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Terror Ballista", 290, Rarity.RARE, mage.cards.t.TerrorBallista.class));
|
cards.add(new SetCardInfo("Terror Ballista", 290, Rarity.RARE, mage.cards.t.TerrorBallista.class));
|
||||||
cards.add(new SetCardInfo("The Mightstone and Weakstone", "238a", Rarity.RARE, mage.cards.t.TheMightstoneAndWeakstone.class));
|
cards.add(new SetCardInfo("The Mightstone and Weakstone", "238a", Rarity.RARE, mage.cards.t.TheMightstoneAndWeakstone.class));
|
||||||
cards.add(new SetCardInfo("The Stasis Coffin", 245, Rarity.RARE, mage.cards.t.TheStasisCoffin.class));
|
cards.add(new SetCardInfo("The Stasis Coffin", 245, Rarity.RARE, mage.cards.t.TheStasisCoffin.class));
|
||||||
|
cards.add(new SetCardInfo("The Temporal Anchor", 82, Rarity.RARE, mage.cards.t.TheTemporalAnchor.class));
|
||||||
cards.add(new SetCardInfo("Third Path Iconoclast", 223, Rarity.UNCOMMON, mage.cards.t.ThirdPathIconoclast.class));
|
cards.add(new SetCardInfo("Third Path Iconoclast", 223, Rarity.UNCOMMON, mage.cards.t.ThirdPathIconoclast.class));
|
||||||
cards.add(new SetCardInfo("Third Path Savant", 67, Rarity.COMMON, mage.cards.t.ThirdPathSavant.class));
|
cards.add(new SetCardInfo("Third Path Savant", 67, Rarity.COMMON, mage.cards.t.ThirdPathSavant.class));
|
||||||
cards.add(new SetCardInfo("Thopter Architect", 29, Rarity.UNCOMMON, mage.cards.t.ThopterArchitect.class));
|
cards.add(new SetCardInfo("Thopter Architect", 29, Rarity.UNCOMMON, mage.cards.t.ThopterArchitect.class));
|
||||||
|
|
|
@ -305,7 +305,7 @@ public class GameEvent implements Serializable {
|
||||||
SHUFFLE_LIBRARY, LIBRARY_SHUFFLED,
|
SHUFFLE_LIBRARY, LIBRARY_SHUFFLED,
|
||||||
ENCHANT_PLAYER, ENCHANTED_PLAYER,
|
ENCHANT_PLAYER, ENCHANTED_PLAYER,
|
||||||
CAN_TAKE_MULLIGAN,
|
CAN_TAKE_MULLIGAN,
|
||||||
SCRY, SCRIED,
|
SCRY, SCRIED, SCRY_TO_BOTTOM,
|
||||||
SURVEIL, SURVEILED,
|
SURVEIL, SURVEILED,
|
||||||
FATESEALED,
|
FATESEALED,
|
||||||
FLIP_COIN, COIN_FLIPPED,
|
FLIP_COIN, COIN_FLIPPED,
|
||||||
|
|
|
@ -4989,6 +4989,12 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
+ " to PUT on the BOTTOM of your library (Scry)"));
|
+ " to PUT on the BOTTOM of your library (Scry)"));
|
||||||
chooseTarget(Outcome.Benefit, cards, target, source, game);
|
chooseTarget(Outcome.Benefit, cards, target, source, game);
|
||||||
putCardsOnBottomOfLibrary(new CardsImpl(target.getTargets()), game, source, true);
|
putCardsOnBottomOfLibrary(new CardsImpl(target.getTargets()), game, source, true);
|
||||||
|
if (!target.getTargets().isEmpty()) {
|
||||||
|
game.fireEvent(GameEvent.getEvent(
|
||||||
|
GameEvent.EventType.SCRY_TO_BOTTOM, getId(),
|
||||||
|
source, getId(), target.getTargets().size()
|
||||||
|
));
|
||||||
|
}
|
||||||
cards.removeIf(target.getTargets()::contains);
|
cards.removeIf(target.getTargets()::contains);
|
||||||
putCardsOnTopOfLibrary(cards, game, source, true);
|
putCardsOnTopOfLibrary(cards, game, source, true);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue